chiark / gitweb /
systemctl: make sure daemon-reload returns success
[elogind.git] / src / libsystemd-bus / bus-message.c
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3 /***
4   This file is part of systemd.
5
6   Copyright 2013 Lennart Poettering
7
8   systemd is free software; you can redistribute it and/or modify it
9   under the terms of the GNU Lesser General Public License as published by
10   the Free Software Foundation; either version 2.1 of the License, or
11   (at your option) any later version.
12
13   systemd is distributed in the hope that it will be useful, but
14   WITHOUT ANY WARRANTY; without even the implied warranty of
15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16   Lesser General Public License for more details.
17
18   You should have received a copy of the GNU Lesser General Public License
19   along with systemd; If not, see <http://www.gnu.org/licenses/>.
20 ***/
21
22 #include <errno.h>
23 #include <fcntl.h>
24 #include <sys/mman.h>
25
26 #include "util.h"
27 #include "utf8.h"
28 #include "strv.h"
29 #include "time-util.h"
30 #include "cgroup-util.h"
31
32 #include "sd-bus.h"
33 #include "bus-message.h"
34 #include "bus-internal.h"
35 #include "bus-type.h"
36 #include "bus-signature.h"
37
38 static int message_append_basic(sd_bus_message *m, char type, const void *p, const void **stored);
39
40 static void *adjust_pointer(const void *p, void *old_base, size_t sz, void *new_base) {
41
42         if (p == NULL)
43                 return NULL;
44
45         if (old_base == new_base)
46                 return (void*) p;
47
48         if ((uint8_t*) p < (uint8_t*) old_base)
49                 return (void*) p;
50
51         if ((uint8_t*) p >= (uint8_t*) old_base + sz)
52                 return (void*) p;
53
54         return (uint8_t*) new_base + ((uint8_t*) p - (uint8_t*) old_base);
55 }
56
57 static void message_free_part(sd_bus_message *m, struct bus_body_part *part) {
58         assert(m);
59         assert(part);
60
61         if (part->memfd >= 0) {
62                 /* If we can reuse the memfd, try that. For that it
63                  * can't be sealed yet. */
64
65                 if (!part->sealed)
66                         bus_kernel_push_memfd(m->bus, part->memfd, part->data, part->mapped);
67                 else {
68                         if (part->mapped > 0)
69                                 assert_se(munmap(part->data, part->mapped) == 0);
70
71                         close_nointr_nofail(part->memfd);
72                 }
73
74         } else if (part->munmap_this)
75                 munmap(part->data, part->mapped);
76         else if (part->free_this)
77                 free(part->data);
78
79         if (part != &m->body)
80                 free(part);
81 }
82
83 static void message_reset_parts(sd_bus_message *m) {
84         struct bus_body_part *part;
85
86         assert(m);
87
88         part = &m->body;
89         while (m->n_body_parts > 0) {
90                 struct bus_body_part *next = part->next;
91                 message_free_part(m, part);
92                 part = next;
93                 m->n_body_parts--;
94         }
95
96         m->body_end = NULL;
97
98         m->cached_rindex_part = NULL;
99         m->cached_rindex_part_begin = 0;
100 }
101
102 static void message_reset_containers(sd_bus_message *m) {
103         unsigned i;
104
105         assert(m);
106
107         for (i = 0; i < m->n_containers; i++)
108                 free(m->containers[i].signature);
109
110         free(m->containers);
111         m->containers = NULL;
112
113         m->n_containers = 0;
114         m->root_container.index = 0;
115 }
116
117 static void message_free(sd_bus_message *m) {
118         assert(m);
119
120         if (m->free_header)
121                 free(m->header);
122
123         message_reset_parts(m);
124
125         if (m->free_kdbus)
126                 free(m->kdbus);
127
128         if (m->release_kdbus) {
129                 uint64_t off;
130
131                 off = (uint8_t *)m->kdbus - (uint8_t *)m->bus->kdbus_buffer;
132                 ioctl(m->bus->input_fd, KDBUS_CMD_MSG_RELEASE, &off);
133         }
134
135         if (m->bus)
136                 sd_bus_unref(m->bus);
137
138         if (m->free_fds) {
139                 close_many(m->fds, m->n_fds);
140                 free(m->fds);
141         }
142
143         if (m->iovec != m->iovec_fixed)
144                 free(m->iovec);
145
146         free(m->cmdline_array);
147
148         message_reset_containers(m);
149         free(m->root_container.signature);
150
151         free(m->peeked_signature);
152
153         free(m->unit);
154         free(m->user_unit);
155         free(m->session);
156         free(m);
157 }
158
159 static void *message_extend_fields(sd_bus_message *m, size_t align, size_t sz) {
160         void *op, *np;
161         size_t old_size, new_size, start;
162
163         assert(m);
164
165         if (m->poisoned)
166                 return NULL;
167
168         old_size = sizeof(struct bus_header) + m->header->fields_size;
169         start = ALIGN_TO(old_size, align);
170         new_size = start + sz;
171
172         if (old_size == new_size)
173                 return (uint8_t*) m->header + old_size;
174
175         if (new_size > (size_t) ((uint32_t) -1))
176                 goto poison;
177
178         if (m->free_header) {
179                 np = realloc(m->header, ALIGN8(new_size));
180                 if (!np)
181                         goto poison;
182         } else {
183                 /* Initially, the header is allocated as part of of
184                  * the sd_bus_message itself, let's replace it by
185                  * dynamic data */
186
187                 np = malloc(ALIGN8(new_size));
188                 if (!np)
189                         goto poison;
190
191                 memcpy(np, m->header, sizeof(struct bus_header));
192         }
193
194         /* Zero out padding */
195         if (start > old_size)
196                 memset((uint8_t*) np + old_size, 0, start - old_size);
197
198         op = m->header;
199         m->header = np;
200         m->header->fields_size = new_size - sizeof(struct bus_header);
201
202         /* Adjust quick access pointers */
203         m->path = adjust_pointer(m->path, op, old_size, m->header);
204         m->interface = adjust_pointer(m->interface, op, old_size, m->header);
205         m->member = adjust_pointer(m->member, op, old_size, m->header);
206         m->destination = adjust_pointer(m->destination, op, old_size, m->header);
207         m->sender = adjust_pointer(m->sender, op, old_size, m->header);
208         m->error.name = adjust_pointer(m->error.name, op, old_size, m->header);
209
210         m->free_header = true;
211
212         return (uint8_t*) np + start;
213
214 poison:
215         m->poisoned = true;
216         return NULL;
217 }
218
219 static int message_append_field_string(
220                 sd_bus_message *m,
221                 uint8_t h,
222                 char type,
223                 const char *s,
224                 const char **ret) {
225
226         size_t l;
227         uint8_t *p;
228
229         assert(m);
230
231         l = strlen(s);
232         if (l > (size_t) (uint32_t) -1)
233                 return -EINVAL;
234
235         /* field id byte + signature length + signature 's' + NUL + string length + string + NUL */
236         p = message_extend_fields(m, 8, 4 + 4 + l + 1);
237         if (!p)
238                 return -ENOMEM;
239
240         p[0] = h;
241         p[1] = 1;
242         p[2] = type;
243         p[3] = 0;
244
245         ((uint32_t*) p)[1] = l;
246         memcpy(p + 8, s, l + 1);
247
248         if (ret)
249                 *ret = (char*) p + 8;
250
251         return 0;
252 }
253
254 static int message_append_field_signature(
255                 sd_bus_message *m,
256                 uint8_t h,
257                 const char *s,
258                 const char **ret) {
259
260         size_t l;
261         uint8_t *p;
262
263         assert(m);
264
265         l = strlen(s);
266         if (l > 255)
267                 return -EINVAL;
268
269         /* field id byte + signature length + signature 'g' + NUL + string length + string + NUL */
270         p = message_extend_fields(m, 8, 4 + 1 + l + 1);
271         if (!p)
272                 return -ENOMEM;
273
274         p[0] = h;
275         p[1] = 1;
276         p[2] = SD_BUS_TYPE_SIGNATURE;
277         p[3] = 0;
278         p[4] = l;
279         memcpy(p + 5, s, l + 1);
280
281         if (ret)
282                 *ret = (const char*) p + 5;
283
284         return 0;
285 }
286
287 static int message_append_field_uint32(sd_bus_message *m, uint8_t h, uint32_t x) {
288         uint8_t *p;
289
290         assert(m);
291
292         /* field id byte + signature length + signature 'u' + NUL + value */
293         p = message_extend_fields(m, 8, 4 + 4);
294         if (!p)
295                 return -ENOMEM;
296
297         p[0] = h;
298         p[1] = 1;
299         p[2] = SD_BUS_TYPE_UINT32;
300         p[3] = 0;
301
302         ((uint32_t*) p)[1] = x;
303
304         return 0;
305 }
306
307 int bus_message_from_header(
308                 void *buffer,
309                 size_t length,
310                 int *fds,
311                 unsigned n_fds,
312                 const struct ucred *ucred,
313                 const char *label,
314                 size_t extra,
315                 sd_bus_message **ret) {
316
317         sd_bus_message *m;
318         struct bus_header *h;
319         size_t a, label_sz;
320
321         assert(buffer || length <= 0);
322         assert(fds || n_fds <= 0);
323         assert(ret);
324
325         if (length < sizeof(struct bus_header))
326                 return -EBADMSG;
327
328         h = buffer;
329         if (h->version != 1)
330                 return -EBADMSG;
331
332         if (h->serial == 0)
333                 return -EBADMSG;
334
335         if (h->type == _SD_BUS_MESSAGE_TYPE_INVALID)
336                 return -EBADMSG;
337
338         if (h->endian != SD_BUS_LITTLE_ENDIAN &&
339             h->endian != SD_BUS_BIG_ENDIAN)
340                 return -EBADMSG;
341
342         a = ALIGN(sizeof(sd_bus_message)) + ALIGN(extra);
343
344         if (label) {
345                 label_sz = strlen(label);
346                 a += label_sz + 1;
347         }
348
349         m = malloc0(a);
350         if (!m)
351                 return -ENOMEM;
352
353         m->n_ref = 1;
354         m->sealed = true;
355         m->header = h;
356         m->fds = fds;
357         m->n_fds = n_fds;
358
359         if (ucred) {
360                 m->uid = ucred->uid;
361                 m->pid = ucred->pid;
362                 m->gid = ucred->gid;
363                 m->uid_valid = m->gid_valid = true;
364         }
365
366         if (label) {
367                 m->label = (char*) m + ALIGN(sizeof(sd_bus_message)) + ALIGN(extra);
368                 memcpy(m->label, label, label_sz + 1);
369         }
370
371         *ret = m;
372         return 0;
373 }
374
375 int bus_message_from_malloc(
376                 void *buffer,
377                 size_t length,
378                 int *fds,
379                 unsigned n_fds,
380                 const struct ucred *ucred,
381                 const char *label,
382                 sd_bus_message **ret) {
383
384         sd_bus_message *m;
385         int r;
386
387         r = bus_message_from_header(buffer, length, fds, n_fds, ucred, label, 0, &m);
388         if (r < 0)
389                 return r;
390
391         if (length != BUS_MESSAGE_SIZE(m)) {
392                 r = -EBADMSG;
393                 goto fail;
394         }
395
396         m->n_body_parts = 1;
397         m->body.data = (uint8_t*) buffer + sizeof(struct bus_header) + ALIGN8(BUS_MESSAGE_FIELDS_SIZE(m));
398         m->body.size = length - sizeof(struct bus_header) - ALIGN8(BUS_MESSAGE_FIELDS_SIZE(m));
399         m->body.sealed = true;
400         m->body.memfd = -1;
401
402         m->n_iovec = 1;
403         m->iovec = m->iovec_fixed;
404         m->iovec[0].iov_base = buffer;
405         m->iovec[0].iov_len = length;
406
407         r = bus_message_parse_fields(m);
408         if (r < 0)
409                 goto fail;
410
411         /* We take possession of the memory and fds now */
412         m->free_header = true;
413         m->free_fds = true;
414
415         *ret = m;
416         return 0;
417
418 fail:
419         message_free(m);
420         return r;
421 }
422
423 static sd_bus_message *message_new(sd_bus *bus, uint8_t type) {
424         sd_bus_message *m;
425
426         m = malloc0(ALIGN(sizeof(sd_bus_message)) + sizeof(struct bus_header));
427         if (!m)
428                 return NULL;
429
430         m->n_ref = 1;
431         m->header = (struct bus_header*) ((uint8_t*) m + ALIGN(sizeof(struct sd_bus_message)));
432         m->header->endian = SD_BUS_NATIVE_ENDIAN;
433         m->header->type = type;
434         m->header->version = bus ? bus->message_version : 1;
435         m->allow_fds = !bus || bus->can_fds || (bus->state != BUS_HELLO && bus->state != BUS_RUNNING);
436
437         if (bus)
438                 m->bus = sd_bus_ref(bus);
439
440         return m;
441 }
442
443 _public_ int sd_bus_message_new_signal(
444                 sd_bus *bus,
445                 const char *path,
446                 const char *interface,
447                 const char *member,
448                 sd_bus_message **m) {
449
450         sd_bus_message *t;
451         int r;
452
453         assert_return(!bus || bus->state != BUS_UNSET, -ENOTCONN);
454         assert_return(object_path_is_valid(path), -EINVAL);
455         assert_return(interface_name_is_valid(interface), -EINVAL);
456         assert_return(member_name_is_valid(member), -EINVAL);
457         assert_return(m, -EINVAL);
458
459         t = message_new(bus, SD_BUS_MESSAGE_SIGNAL);
460         if (!t)
461                 return -ENOMEM;
462
463         t->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
464
465         r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_PATH, SD_BUS_TYPE_OBJECT_PATH, path, &t->path);
466         if (r < 0)
467                 goto fail;
468         r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_INTERFACE, SD_BUS_TYPE_STRING, interface, &t->interface);
469         if (r < 0)
470                 goto fail;
471         r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_MEMBER, SD_BUS_TYPE_STRING, member, &t->member);
472         if (r < 0)
473                 goto fail;
474
475         *m = t;
476         return 0;
477
478 fail:
479         sd_bus_message_unref(t);
480         return r;
481 }
482
483 _public_ int sd_bus_message_new_method_call(
484                 sd_bus *bus,
485                 const char *destination,
486                 const char *path,
487                 const char *interface,
488                 const char *member,
489                 sd_bus_message **m) {
490
491         sd_bus_message *t;
492         int r;
493
494         assert_return(!bus || bus->state != BUS_UNSET, -ENOTCONN);
495         assert_return(!destination || service_name_is_valid(destination), -EINVAL);
496         assert_return(object_path_is_valid(path), -EINVAL);
497         assert_return(!interface || interface_name_is_valid(interface), -EINVAL);
498         assert_return(member_name_is_valid(member), -EINVAL);
499         assert_return(m, -EINVAL);
500
501         t = message_new(bus, SD_BUS_MESSAGE_METHOD_CALL);
502         if (!t)
503                 return -ENOMEM;
504
505         r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_PATH, SD_BUS_TYPE_OBJECT_PATH, path, &t->path);
506         if (r < 0)
507                 goto fail;
508         r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_MEMBER, SD_BUS_TYPE_STRING, member, &t->member);
509         if (r < 0)
510                 goto fail;
511
512         if (interface) {
513                 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_INTERFACE, SD_BUS_TYPE_STRING, interface, &t->interface);
514                 if (r < 0)
515                         goto fail;
516         }
517
518         if (destination) {
519                 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &t->destination);
520                 if (r < 0)
521                         goto fail;
522         }
523
524         *m = t;
525         return 0;
526
527 fail:
528         message_free(t);
529         return r;
530 }
531
532 static int message_new_reply(
533                 sd_bus *bus,
534                 sd_bus_message *call,
535                 uint8_t type,
536                 sd_bus_message **m) {
537
538         sd_bus_message *t;
539         int r;
540
541         assert_return(!bus || bus->state != BUS_UNSET, -ENOTCONN);
542         assert_return(call, -EINVAL);
543         assert_return(call->sealed, -EPERM);
544         assert_return(call->header->type == SD_BUS_MESSAGE_METHOD_CALL, -EINVAL);
545         assert_return(m, -EINVAL);
546
547         t = message_new(bus, type);
548         if (!t)
549                 return -ENOMEM;
550
551         t->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
552         t->reply_serial = BUS_MESSAGE_SERIAL(call);
553
554         r = message_append_field_uint32(t, SD_BUS_MESSAGE_HEADER_REPLY_SERIAL, t->reply_serial);
555         if (r < 0)
556                 goto fail;
557
558         if (call->sender) {
559                 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, call->sender, &t->destination);
560                 if (r < 0)
561                         goto fail;
562         }
563
564         t->dont_send = !!(call->header->flags & SD_BUS_MESSAGE_NO_REPLY_EXPECTED);
565
566         *m = t;
567         return 0;
568
569 fail:
570         message_free(t);
571         return r;
572 }
573
574 _public_ int sd_bus_message_new_method_return(
575                 sd_bus *bus,
576                 sd_bus_message *call,
577                 sd_bus_message **m) {
578
579         return message_new_reply(bus, call, SD_BUS_MESSAGE_METHOD_RETURN, m);
580 }
581
582 _public_ int sd_bus_message_new_method_error(
583                 sd_bus *bus,
584                 sd_bus_message *call,
585                 const sd_bus_error *e,
586                 sd_bus_message **m) {
587
588         sd_bus_message *t;
589         int r;
590
591         assert_return(sd_bus_error_is_set(e), -EINVAL);
592         assert_return(m, -EINVAL);
593
594         r = message_new_reply(bus, call, SD_BUS_MESSAGE_METHOD_ERROR, &t);
595         if (r < 0)
596                 return r;
597
598         r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_ERROR_NAME, SD_BUS_TYPE_STRING, e->name, &t->error.name);
599         if (r < 0)
600                 goto fail;
601
602         if (e->message) {
603                 r = message_append_basic(t, SD_BUS_TYPE_STRING, e->message, (const void**) &t->error.message);
604                 if (r < 0)
605                         goto fail;
606         }
607
608         *m = t;
609         return 0;
610
611 fail:
612         message_free(t);
613         return r;
614 }
615
616 _public_ int sd_bus_message_new_method_errorf(
617                 sd_bus *bus,
618                 sd_bus_message *call,
619                 sd_bus_message **m,
620                 const char *name,
621                 const char *format,
622                 ...) {
623
624         _cleanup_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
625         va_list ap;
626         int r;
627
628         assert_return(name, -EINVAL);
629         assert_return(m, -EINVAL);
630
631         va_start(ap, format);
632         r = bus_error_setfv(&error, name, format, ap);
633         va_end(ap);
634
635         if (r < 0)
636                 return r;
637
638         return sd_bus_message_new_method_error(bus, call, &error, m);
639 }
640
641 _public_ int sd_bus_message_new_method_errno(
642                 sd_bus *bus,
643                 sd_bus_message *call,
644                 int error,
645                 const sd_bus_error *p,
646                 sd_bus_message **m) {
647
648         _cleanup_free_ sd_bus_error berror = SD_BUS_ERROR_NULL;
649
650         if (sd_bus_error_is_set(p))
651                 return sd_bus_message_new_method_error(bus, call, p, m);
652
653         sd_bus_error_set_errno(&berror, error);
654
655         return sd_bus_message_new_method_error(bus, call, &berror, m);
656 }
657
658 _public_ int sd_bus_message_new_method_errnof(
659                 sd_bus *bus,
660                 sd_bus_message *call,
661                 sd_bus_message **m,
662                 int error,
663                 const char *format,
664                 ...) {
665
666         _cleanup_free_ sd_bus_error berror = SD_BUS_ERROR_NULL;
667         va_list ap;
668         int r;
669
670         va_start(ap, format);
671         r = bus_error_set_errnofv(&berror, error, format, ap);
672         va_end(ap);
673
674         if (r < 0)
675                 return r;
676
677         return sd_bus_message_new_method_error(bus, call, &berror, m);
678 }
679
680 int bus_message_new_synthetic_error(
681                 sd_bus *bus,
682                 uint64_t serial,
683                 const sd_bus_error *e,
684                 sd_bus_message **m) {
685
686         sd_bus_message *t;
687         int r;
688
689         assert(sd_bus_error_is_set(e));
690         assert(m);
691
692         t = message_new(bus, SD_BUS_MESSAGE_METHOD_ERROR);
693         if (!t)
694                 return -ENOMEM;
695
696         t->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
697         t->reply_serial = serial;
698
699         r = message_append_field_uint32(t, SD_BUS_MESSAGE_HEADER_REPLY_SERIAL, t->reply_serial);
700         if (r < 0)
701                 goto fail;
702
703         if (bus && bus->unique_name) {
704                 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, bus->unique_name, &t->destination);
705                 if (r < 0)
706                         goto fail;
707         }
708
709         r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_ERROR_NAME, SD_BUS_TYPE_STRING, e->name, &t->error.name);
710         if (r < 0)
711                 goto fail;
712
713         if (e->message) {
714                 r = message_append_basic(t, SD_BUS_TYPE_STRING, e->message, (const void**) &t->error.message);
715                 if (r < 0)
716                         goto fail;
717         }
718
719         *m = t;
720         return 0;
721
722 fail:
723         message_free(t);
724         return r;
725 }
726
727 _public_ sd_bus_message* sd_bus_message_ref(sd_bus_message *m) {
728         assert_return(m, NULL);
729
730         assert(m->n_ref > 0);
731         m->n_ref++;
732
733         return m;
734 }
735
736 _public_ sd_bus_message* sd_bus_message_unref(sd_bus_message *m) {
737         assert_return(m, NULL);
738
739         assert(m->n_ref > 0);
740         m->n_ref--;
741
742         if (m->n_ref <= 0)
743                 message_free(m);
744
745         return NULL;
746 }
747
748 _public_ int sd_bus_message_get_type(sd_bus_message *m, uint8_t *type) {
749         assert_return(m, -EINVAL);
750         assert_return(type, -EINVAL);
751
752         *type = m->header->type;
753         return 0;
754 }
755
756 _public_ int sd_bus_message_get_serial(sd_bus_message *m, uint64_t *serial) {
757         assert_return(m, -EINVAL);
758         assert_return(serial, -EINVAL);
759         assert_return(m->header->serial != 0, -ENOENT);
760
761         *serial = BUS_MESSAGE_SERIAL(m);
762         return 0;
763 }
764
765 _public_ int sd_bus_message_get_reply_serial(sd_bus_message *m, uint64_t *serial) {
766         assert_return(m, -EINVAL);
767         assert_return(serial, -EINVAL);
768         assert_return(m->reply_serial != 0, -ENOENT);
769
770         *serial = m->reply_serial;
771         return 0;
772 }
773
774 _public_ int sd_bus_message_get_no_reply(sd_bus_message *m) {
775         assert_return(m, -EINVAL);
776
777         return m->header->type == SD_BUS_MESSAGE_METHOD_CALL ? !!(m->header->flags & SD_BUS_MESSAGE_NO_REPLY_EXPECTED) : 0;
778 }
779
780 _public_ const char *sd_bus_message_get_path(sd_bus_message *m) {
781         assert_return(m, NULL);
782
783         return m->path;
784 }
785
786 _public_ const char *sd_bus_message_get_interface(sd_bus_message *m) {
787         assert_return(m, NULL);
788
789         return m->interface;
790 }
791
792 _public_ const char *sd_bus_message_get_member(sd_bus_message *m) {
793         assert_return(m, NULL);
794
795         return m->member;
796 }
797
798 _public_ const char *sd_bus_message_get_destination(sd_bus_message *m) {
799         assert_return(m, NULL);
800
801         return m->destination;
802 }
803
804 _public_ const char *sd_bus_message_get_sender(sd_bus_message *m) {
805         assert_return(m, NULL);
806
807         return m->sender;
808 }
809
810 _public_ const sd_bus_error *sd_bus_message_get_error(sd_bus_message *m) {
811         assert_return(m, NULL);
812         assert_return(sd_bus_error_is_set(&m->error), NULL);
813
814         return &m->error;
815 }
816
817 _public_ int sd_bus_message_get_uid(sd_bus_message *m, uid_t *uid) {
818         assert_return(m, -EINVAL);
819         assert_return(uid, -EINVAL);
820         assert_return(m->uid_valid, -ESRCH);
821
822         *uid = m->uid;
823         return 0;
824 }
825
826 _public_ int sd_bus_message_get_gid(sd_bus_message *m, gid_t *gid) {
827         assert_return(m, -EINVAL);
828         assert_return(gid, -EINVAL);
829         assert_return(m->gid_valid, -ESRCH);
830
831         *gid = m->gid;
832         return 0;
833 }
834
835 _public_ int sd_bus_message_get_pid(sd_bus_message *m, pid_t *pid) {
836         assert_return(m, -EINVAL);
837         assert_return(pid, -EINVAL);
838         assert_return(m->pid > 0, -ESRCH);
839
840         *pid = m->pid;
841         return 0;
842 }
843
844 _public_ int sd_bus_message_get_tid(sd_bus_message *m, pid_t *tid) {
845         assert_return(m, -EINVAL);
846         assert_return(tid, -EINVAL);
847         assert_return(m->tid > 0, -ESRCH);
848
849         *tid = m->tid;
850         return 0;
851 }
852
853 _public_ int sd_bus_message_get_pid_starttime(sd_bus_message *m, uint64_t *usec) {
854         assert_return(m, -EINVAL);
855         assert_return(usec, -EINVAL);
856         assert_return(m->pid_starttime > 0, -ESRCH);
857
858         *usec = m->pid_starttime;
859         return 0;
860 }
861
862 _public_ int sd_bus_message_get_selinux_context(sd_bus_message *m, const char **ret) {
863         assert_return(m, -EINVAL);
864         assert_return(m->label, -ESRCH);
865
866         *ret = m->label;
867         return 0;
868 }
869
870 _public_ int sd_bus_message_get_monotonic_timestamp(sd_bus_message *m, uint64_t *usec) {
871         assert_return(m, -EINVAL);
872         assert_return(usec, -EINVAL);
873         assert_return(m->monotonic > 0, -ESRCH);
874
875         *usec = m->monotonic;
876         return 0;
877 }
878
879 _public_ int sd_bus_message_get_realtime_timestamp(sd_bus_message *m, uint64_t *usec) {
880         assert_return(m, -EINVAL);
881         assert_return(usec, -EINVAL);
882         assert_return(m->realtime > 0, -ESRCH);
883
884         *usec = m->realtime;
885         return 0;
886 }
887
888 _public_ int sd_bus_message_get_comm(sd_bus_message *m, const char **ret) {
889         assert_return(m, -EINVAL);
890         assert_return(ret, -EINVAL);
891         assert_return(m->comm, -ESRCH);
892
893         *ret = m->comm;
894         return 0;
895 }
896
897 _public_ int sd_bus_message_get_tid_comm(sd_bus_message *m, const char **ret) {
898         assert_return(m, -EINVAL);
899         assert_return(ret, -EINVAL);
900         assert_return(m->tid_comm, -ESRCH);
901
902         *ret = m->tid_comm;
903         return 0;
904 }
905
906 _public_ int sd_bus_message_get_exe(sd_bus_message *m, const char **ret) {
907         assert_return(m, -EINVAL);
908         assert_return(ret, -EINVAL);
909         assert_return(m->exe, -ESRCH);
910
911         *ret = m->exe;
912         return 0;
913 }
914
915 _public_ int sd_bus_message_get_cgroup(sd_bus_message *m, const char **ret) {
916         assert_return(m, -EINVAL);
917         assert_return(ret, -EINVAL);
918         assert_return(m->cgroup, -ESRCH);
919
920         *ret = m->cgroup;
921         return 0;
922 }
923
924 _public_ int sd_bus_message_get_unit(sd_bus_message *m, const char **ret) {
925         int r;
926
927         assert_return(m, -EINVAL);
928         assert_return(ret, -EINVAL);
929         assert_return(m->cgroup, -ESRCH);
930
931         if (!m->unit) {
932                 r = cg_path_get_unit(m->cgroup, &m->unit);
933                 if (r < 0)
934                         return r;
935         }
936
937         *ret = m->unit;
938         return 0;
939 }
940
941 _public_ int sd_bus_message_get_user_unit(sd_bus_message *m, const char **ret) {
942         int r;
943
944         assert_return(m, -EINVAL);
945         assert_return(ret, -EINVAL);
946         assert_return(m->cgroup, -ESRCH);
947
948         if (!m->user_unit) {
949                 r = cg_path_get_user_unit(m->cgroup, &m->user_unit);
950                 if (r < 0)
951                         return r;
952         }
953
954         *ret = m->user_unit;
955         return 0;
956 }
957
958 _public_ int sd_bus_message_get_session(sd_bus_message *m, const char **ret) {
959         int r;
960
961         assert_return(m, -EINVAL);
962         assert_return(ret, -EINVAL);
963         assert_return(m->cgroup, -ESRCH);
964
965         if (!m->session) {
966                 r = cg_path_get_session(m->cgroup, &m->session);
967                 if (r < 0)
968                         return r;
969         }
970
971         *ret = m->session;
972         return 0;
973 }
974
975 _public_ int sd_bus_message_get_owner_uid(sd_bus_message *m, uid_t *uid) {
976         assert_return(m, -EINVAL);
977         assert_return(uid, -EINVAL);
978         assert_return(m->cgroup, -ESRCH);
979
980         return cg_path_get_owner_uid(m->cgroup, uid);
981 }
982
983 _public_ int sd_bus_message_get_cmdline(sd_bus_message *m, char ***cmdline) {
984         size_t n, i;
985         const char *p;
986         bool first;
987
988         assert_return(m, -EINVAL);
989         assert_return(m->cmdline, -ESRCH);
990
991         for (p = m->cmdline, n = 0; p < m->cmdline + m->cmdline_length; p++)
992                 if (*p == 0)
993                         n++;
994
995         m->cmdline_array = new(char*, n + 1);
996         if (!m->cmdline_array)
997                 return -ENOMEM;
998
999         for (p = m->cmdline, i = 0, first = true; p < m->cmdline + m->cmdline_length; p++) {
1000                 if (first)
1001                         m->cmdline_array[i++] = (char*) p;
1002
1003                 first = *p == 0;
1004         }
1005
1006         m->cmdline_array[i] = NULL;
1007         *cmdline = m->cmdline_array;
1008
1009         return 0;
1010 }
1011
1012 _public_ int sd_bus_message_get_audit_sessionid(sd_bus_message *m, uint32_t *sessionid) {
1013         assert_return(m, -EINVAL);
1014         assert_return(sessionid, -EINVAL);
1015         assert_return(m->audit, -ESRCH);
1016
1017         *sessionid = m->audit->sessionid;
1018         return 0;
1019 }
1020
1021 _public_ int sd_bus_message_get_audit_loginuid(sd_bus_message *m, uid_t *uid) {
1022         assert_return(m, -EINVAL);
1023         assert_return(uid, -EINVAL);
1024         assert_return(m->audit, -ESRCH);
1025
1026         *uid = m->audit->loginuid;
1027         return 0;
1028 }
1029
1030 _public_ int sd_bus_message_has_effective_cap(sd_bus_message *m, int capability) {
1031         unsigned sz;
1032
1033         assert_return(m, -EINVAL);
1034         assert_return(capability < 0, -EINVAL);
1035         assert_return(!m->capability, -ESRCH);
1036
1037         sz = m->capability_size / 4;
1038         if ((unsigned) capability >= sz*8)
1039                 return 0;
1040
1041         return !!(m->capability[2 * sz + (capability / 8)] & (1 << (capability % 8)));
1042 }
1043
1044 _public_ int sd_bus_message_is_signal(sd_bus_message *m,
1045                                       const char *interface,
1046                                       const char *member) {
1047         assert_return(m, -EINVAL);
1048
1049         if (m->header->type != SD_BUS_MESSAGE_SIGNAL)
1050                 return 0;
1051
1052         if (interface && (!m->interface || !streq(m->interface, interface)))
1053                 return 0;
1054
1055         if (member &&  (!m->member || !streq(m->member, member)))
1056                 return 0;
1057
1058         return 1;
1059 }
1060
1061 _public_ int sd_bus_message_is_method_call(sd_bus_message *m,
1062                                            const char *interface,
1063                                            const char *member) {
1064         assert_return(m, -EINVAL);
1065
1066         if (m->header->type != SD_BUS_MESSAGE_METHOD_CALL)
1067                 return 0;
1068
1069         if (interface && (!m->interface || !streq(m->interface, interface)))
1070                 return 0;
1071
1072         if (member &&  (!m->member || !streq(m->member, member)))
1073                 return 0;
1074
1075         return 1;
1076 }
1077
1078 _public_ int sd_bus_message_is_method_error(sd_bus_message *m, const char *name) {
1079         assert_return(m, -EINVAL);
1080
1081         if (m->header->type != SD_BUS_MESSAGE_METHOD_ERROR)
1082                 return 0;
1083
1084         if (name && (!m->error.name || !streq(m->error.name, name)))
1085                 return 0;
1086
1087         return 1;
1088 }
1089
1090 _public_ int sd_bus_message_set_no_reply(sd_bus_message *m, int b) {
1091         assert_return(m, -EINVAL);
1092         assert_return(!m->sealed, -EPERM);
1093         assert_return(m->header->type == SD_BUS_MESSAGE_METHOD_CALL, -EPERM);
1094
1095         if (b)
1096                 m->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
1097         else
1098                 m->header->flags &= ~SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
1099
1100         return 0;
1101 }
1102
1103 static struct bus_container *message_get_container(sd_bus_message *m) {
1104         assert(m);
1105
1106         if (m->n_containers == 0)
1107                 return &m->root_container;
1108
1109         assert(m->containers);
1110         return m->containers + m->n_containers - 1;
1111 }
1112
1113 struct bus_body_part *message_append_part(sd_bus_message *m) {
1114         struct bus_body_part *part;
1115
1116         assert(m);
1117
1118         if (m->poisoned)
1119                 return NULL;
1120
1121         if (m->n_body_parts <= 0) {
1122                 part = &m->body;
1123                 zero(*part);
1124         } else {
1125                 assert(m->body_end);
1126
1127                 part = new0(struct bus_body_part, 1);
1128                 if (!part) {
1129                         m->poisoned = true;
1130                         return NULL;
1131                 }
1132
1133                 m->body_end->next = part;
1134         }
1135
1136         part->memfd = -1;
1137         m->body_end = part;
1138         m->n_body_parts ++;
1139
1140         return part;
1141 }
1142
1143 static void part_zero(struct bus_body_part *part, size_t sz) {
1144         assert(part);
1145         assert(sz > 0);
1146         assert(sz < 8);
1147
1148         /* All other fields can be left in their defaults */
1149         assert(!part->data);
1150         assert(part->memfd < 0);
1151
1152         part->size = sz;
1153         part->is_zero = true;
1154         part->sealed = true;
1155 }
1156
1157 static int part_make_space(
1158                 struct sd_bus_message *m,
1159                 struct bus_body_part *part,
1160                 size_t sz,
1161                 void **q) {
1162
1163         void *n;
1164         int r;
1165
1166         assert(m);
1167         assert(part);
1168         assert(!part->sealed);
1169
1170         if (m->poisoned)
1171                 return -ENOMEM;
1172
1173         if (!part->data && part->memfd < 0)
1174                 part->memfd = bus_kernel_pop_memfd(m->bus, &part->data, &part->mapped);
1175
1176         if (part->memfd >= 0) {
1177                 uint64_t u = sz;
1178
1179                 r = ioctl(part->memfd, KDBUS_CMD_MEMFD_SIZE_SET, &u);
1180                 if (r < 0) {
1181                         m->poisoned = true;
1182                         return -errno;
1183                 }
1184
1185                 if (!part->data || sz > part->mapped) {
1186                         size_t psz = PAGE_ALIGN(sz > 0 ? sz : 1);
1187
1188                         if (part->mapped <= 0)
1189                                 n = mmap(NULL, psz, PROT_READ|PROT_WRITE, MAP_SHARED, part->memfd, 0);
1190                         else
1191                                 n = mremap(part->data, part->mapped, psz, MREMAP_MAYMOVE);
1192
1193                         if (n == MAP_FAILED) {
1194                                 m->poisoned = true;
1195                                 return -errno;
1196                         }
1197
1198                         part->mapped = psz;
1199                         part->data = n;
1200                 }
1201
1202                 part->munmap_this = true;
1203         } else {
1204                 n = realloc(part->data, MAX(sz, 1u));
1205                 if (!n) {
1206                         m->poisoned = true;
1207                         return -ENOMEM;
1208                 }
1209
1210                 part->data = n;
1211                 part->free_this = true;
1212         }
1213
1214         if (q)
1215                 *q = part->data ? (uint8_t*) part->data + part->size : NULL;
1216
1217         part->size = sz;
1218         return 0;
1219 }
1220
1221 static void message_extend_containers(sd_bus_message *m, size_t expand) {
1222         struct bus_container *c;
1223
1224         assert(m);
1225
1226         if (expand <= 0)
1227                 return;
1228
1229         /* Update counters */
1230         for (c = m->containers; c < m->containers + m->n_containers; c++)
1231                 if (c->array_size)
1232                         *c->array_size += expand;
1233 }
1234
1235 static void *message_extend_body(sd_bus_message *m, size_t align, size_t sz) {
1236         struct bus_body_part *part = NULL;
1237         size_t start_body, end_body, padding, start_part, end_part, added;
1238         bool add_new_part;
1239         void *p;
1240         int r;
1241
1242         assert(m);
1243         assert(align > 0);
1244         assert(!m->sealed);
1245
1246         if (m->poisoned)
1247                 return NULL;
1248
1249         start_body = ALIGN_TO((size_t) m->header->body_size, align);
1250         end_body = start_body + sz;
1251
1252         padding = start_body - m->header->body_size;
1253         added = padding + sz;
1254
1255         /* Check for 32bit overflows */
1256         if (end_body > (size_t) ((uint32_t) -1)) {
1257                 m->poisoned = true;
1258                 return NULL;
1259         }
1260
1261         add_new_part =
1262                 m->n_body_parts <= 0 ||
1263                 m->body_end->sealed ||
1264                 padding != ALIGN_TO(m->body_end->size, align) - m->body_end->size;
1265
1266         if (add_new_part) {
1267                 if (padding > 0) {
1268                         part = message_append_part(m);
1269                         if (!part)
1270                                 return NULL;
1271
1272                         part_zero(part, padding);
1273                 }
1274
1275                 part = message_append_part(m);
1276                 if (!part)
1277                         return NULL;
1278
1279                 r = part_make_space(m, part, sz, &p);
1280                 if (r < 0)
1281                         return NULL;
1282         } else {
1283                 struct bus_container *c;
1284                 void *op;
1285                 size_t os;
1286
1287                 part = m->body_end;
1288                 op = part->data;
1289                 os = part->size;
1290
1291                 start_part = ALIGN_TO(part->size, align);
1292                 end_part = start_part + sz;
1293
1294                 r = part_make_space(m, part, end_part, &p);
1295                 if (r < 0)
1296                         return NULL;
1297
1298                 if (padding > 0) {
1299                         memset(p, 0, padding);
1300                         p = (uint8_t*) p + padding;
1301                 }
1302
1303                 /* Readjust pointers */
1304                 for (c = m->containers; c < m->containers + m->n_containers; c++)
1305                         c->array_size = adjust_pointer(c->array_size, op, os, part->data);
1306
1307                 m->error.message = (const char*) adjust_pointer(m->error.message, op, os, part->data);
1308         }
1309
1310         m->header->body_size = end_body;
1311         message_extend_containers(m, added);
1312
1313         return p;
1314 }
1315
1316 int message_append_basic(sd_bus_message *m, char type, const void *p, const void **stored) {
1317         struct bus_container *c;
1318         ssize_t align, sz;
1319         uint32_t k;
1320         void *a;
1321         int fd = -1;
1322         uint32_t fdi = 0;
1323         int r;
1324
1325         assert_return(m, -EINVAL);
1326         assert_return(!m->sealed, -EPERM);
1327         assert_return(bus_type_is_basic(type), -EINVAL);
1328         assert_return(!m->poisoned, -ESTALE);
1329
1330         c = message_get_container(m);
1331
1332         if (c->signature && c->signature[c->index]) {
1333                 /* Container signature is already set */
1334
1335                 if (c->signature[c->index] != type)
1336                         return -ENXIO;
1337         } else {
1338                 char *e;
1339
1340                 /* Maybe we can append to the signature? But only if this is the top-level container*/
1341                 if (c->enclosing != 0)
1342                         return -ENXIO;
1343
1344                 e = strextend(&c->signature, CHAR_TO_STR(type), NULL);
1345                 if (!e) {
1346                         m->poisoned = true;
1347                         return -ENOMEM;
1348                 }
1349         }
1350
1351         switch (type) {
1352
1353         case SD_BUS_TYPE_STRING:
1354                 /* To make things easy we'll serialize a NULL string
1355                  * into the empty string */
1356                 p = strempty(p);
1357
1358                 /* Fall through... */
1359         case SD_BUS_TYPE_OBJECT_PATH:
1360
1361                 if (!p) {
1362                         r = -EINVAL;
1363                         goto fail;
1364                 }
1365
1366                 align = 4;
1367                 sz = 4 + strlen(p) + 1;
1368                 break;
1369
1370         case SD_BUS_TYPE_SIGNATURE:
1371
1372                 if (!p) {
1373                         r = -EINVAL;
1374                         goto fail;
1375                 }
1376
1377                 align = 1;
1378                 sz = 1 + strlen(p) + 1;
1379                 break;
1380
1381         case SD_BUS_TYPE_BOOLEAN:
1382
1383                 if (!p) {
1384                         r = -EINVAL;
1385                         goto fail;
1386                 }
1387
1388                 align = sz = 4;
1389
1390                 assert_cc(sizeof(int) == sizeof(uint32_t));
1391                 memcpy(&k, p, 4);
1392                 k = !!k;
1393                 p = &k;
1394                 break;
1395
1396         case SD_BUS_TYPE_UNIX_FD: {
1397                 int z, *f;
1398
1399                 if (!p) {
1400                         r = -EINVAL;
1401                         goto fail;
1402                 }
1403
1404                 if (!m->allow_fds) {
1405                         r = -ENOTSUP;
1406                         goto fail;
1407                 }
1408
1409                 align = sz = 4;
1410
1411                 z = *(int*) p;
1412                 if (z < 0) {
1413                         r = -EINVAL;
1414                         goto fail;
1415                 }
1416
1417                 fd = fcntl(z, F_DUPFD_CLOEXEC, 3);
1418                 if (fd < 0) {
1419                         r = -errno;
1420                         goto fail;
1421                 }
1422
1423                 f = realloc(m->fds, sizeof(int) * (m->n_fds + 1));
1424                 if (!f) {
1425                         m->poisoned = true;
1426                         r = -ENOMEM;
1427                         goto fail;
1428                 }
1429
1430                 fdi = m->n_fds;
1431                 f[fdi] = fd;
1432                 m->fds = f;
1433                 m->free_fds = true;
1434                 break;
1435         }
1436
1437         default:
1438                 if (!p) {
1439                         r = -EINVAL;
1440                         goto fail;
1441                 }
1442
1443                 align = bus_type_get_alignment(type);
1444                 sz = bus_type_get_size(type);
1445                 break;
1446         }
1447
1448         assert(align > 0);
1449         assert(sz > 0);
1450
1451         a = message_extend_body(m, align, sz);
1452         if (!a) {
1453                 r = -ENOMEM;
1454                 goto fail;
1455         }
1456
1457         if (type == SD_BUS_TYPE_STRING || type == SD_BUS_TYPE_OBJECT_PATH) {
1458                 *(uint32_t*) a = sz - 5;
1459                 memcpy((uint8_t*) a + 4, p, sz - 4);
1460
1461                 if (stored)
1462                         *stored = (const uint8_t*) a + 4;
1463
1464         } else if (type == SD_BUS_TYPE_SIGNATURE) {
1465                 *(uint8_t*) a = sz - 1;
1466                 memcpy((uint8_t*) a + 1, p, sz - 1);
1467
1468                 if (stored)
1469                         *stored = (const uint8_t*) a + 1;
1470         } else if (type == SD_BUS_TYPE_UNIX_FD) {
1471                 *(uint32_t*) a = fdi;
1472
1473                 if (stored)
1474                         *stored = a;
1475
1476                 m->n_fds ++;
1477
1478         } else {
1479                 memcpy(a, p, sz);
1480
1481                 if (stored)
1482                         *stored = a;
1483         }
1484
1485         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1486                 c->index++;
1487
1488         return 0;
1489
1490 fail:
1491         if (fd >= 0)
1492                 close_nointr_nofail(fd);
1493
1494         return r;
1495 }
1496
1497 _public_ int sd_bus_message_append_basic(sd_bus_message *m, char type, const void *p) {
1498         return message_append_basic(m, type, p, NULL);
1499 }
1500
1501 _public_ int sd_bus_message_append_string_space(sd_bus_message *m, size_t size, char **s) {
1502         struct bus_container *c;
1503         void *a;
1504
1505         assert_return(m, -EINVAL);
1506         assert_return(s, -EINVAL);
1507         assert_return(!m->sealed, -EPERM);
1508         assert_return(!m->poisoned, -ESTALE);
1509
1510         c = message_get_container(m);
1511
1512         if (c->signature && c->signature[c->index]) {
1513                 /* Container signature is already set */
1514
1515                 if (c->signature[c->index] != SD_BUS_TYPE_STRING)
1516                         return -ENXIO;
1517         } else {
1518                 char *e;
1519
1520                 /* Maybe we can append to the signature? But only if this is the top-level container*/
1521                 if (c->enclosing != 0)
1522                         return -ENXIO;
1523
1524                 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRING), NULL);
1525                 if (!e) {
1526                         m->poisoned = true;
1527                         return -ENOMEM;
1528                 }
1529         }
1530
1531         a = message_extend_body(m, 4, 4 + size + 1);
1532         if (!a)
1533                 return -ENOMEM;
1534
1535         *(uint32_t*) a = size;
1536         *s = (char*) a + 4;
1537
1538         (*s)[size] = 0;
1539
1540         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1541                 c->index++;
1542
1543         return 0;
1544 }
1545
1546 static int bus_message_open_array(
1547                 sd_bus_message *m,
1548                 struct bus_container *c,
1549                 const char *contents,
1550                 uint32_t **array_size) {
1551
1552         unsigned nindex;
1553         void *a, *op;
1554         int alignment;
1555         size_t os;
1556         struct bus_body_part *o;
1557
1558         assert(m);
1559         assert(c);
1560         assert(contents);
1561         assert(array_size);
1562
1563         if (!signature_is_single(contents, true))
1564                 return -EINVAL;
1565
1566         alignment = bus_type_get_alignment(contents[0]);
1567         if (alignment < 0)
1568                 return alignment;
1569
1570         if (c->signature && c->signature[c->index]) {
1571
1572                 /* Verify the existing signature */
1573
1574                 if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
1575                         return -ENXIO;
1576
1577                 if (!startswith(c->signature + c->index + 1, contents))
1578                         return -ENXIO;
1579
1580                 nindex = c->index + 1 + strlen(contents);
1581         } else {
1582                 char *e;
1583
1584                 if (c->enclosing != 0)
1585                         return -ENXIO;
1586
1587                 /* Extend the existing signature */
1588
1589                 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_ARRAY), contents, NULL);
1590                 if (!e) {
1591                         m->poisoned = true;
1592                         return -ENOMEM;
1593                 }
1594
1595                 nindex = e - c->signature;
1596         }
1597
1598         a = message_extend_body(m, 4, 4);
1599         if (!a)
1600                 return -ENOMEM;
1601
1602         o = m->body_end;
1603         op = m->body_end->data;
1604         os = m->body_end->size;
1605
1606         /* Add alignment between size and first element */
1607         if (!message_extend_body(m, alignment, 0))
1608                 return -ENOMEM;
1609
1610         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1611                 c->index = nindex;
1612
1613         /* location of array size might have changed so let's readjust a */
1614         if (o == m->body_end)
1615                 a = adjust_pointer(a, op, os, m->body_end->data);
1616
1617         *(uint32_t*) a = 0;
1618         *array_size = a;
1619         return 0;
1620 }
1621
1622 static int bus_message_open_variant(
1623                 sd_bus_message *m,
1624                 struct bus_container *c,
1625                 const char *contents) {
1626
1627         size_t l;
1628         void *a;
1629
1630         assert(m);
1631         assert(c);
1632         assert(contents);
1633
1634         if (!signature_is_single(contents, false))
1635                 return -EINVAL;
1636
1637         if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
1638                 return -EINVAL;
1639
1640         if (c->signature && c->signature[c->index]) {
1641
1642                 if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
1643                         return -ENXIO;
1644
1645         } else {
1646                 char *e;
1647
1648                 if (c->enclosing != 0)
1649                         return -ENXIO;
1650
1651                 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_VARIANT), NULL);
1652                 if (!e) {
1653                         m->poisoned = true;
1654                         return -ENOMEM;
1655                 }
1656         }
1657
1658         l = strlen(contents);
1659         a = message_extend_body(m, 1, 1 + l + 1);
1660         if (!a)
1661                 return -ENOMEM;
1662
1663         *(uint8_t*) a = l;
1664         memcpy((uint8_t*) a + 1, contents, l + 1);
1665
1666         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1667                 c->index++;
1668
1669         return 0;
1670 }
1671
1672 static int bus_message_open_struct(
1673                 sd_bus_message *m,
1674                 struct bus_container *c,
1675                 const char *contents) {
1676
1677         size_t nindex;
1678
1679         assert(m);
1680         assert(c);
1681         assert(contents);
1682
1683         if (!signature_is_valid(contents, false))
1684                 return -EINVAL;
1685
1686         if (c->signature && c->signature[c->index]) {
1687                 size_t l;
1688
1689                 l = strlen(contents);
1690
1691                 if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
1692                     !startswith(c->signature + c->index + 1, contents) ||
1693                     c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
1694                         return -ENXIO;
1695
1696                 nindex = c->index + 1 + l + 1;
1697         } else {
1698                 char *e;
1699
1700                 if (c->enclosing != 0)
1701                         return -ENXIO;
1702
1703                 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_BEGIN), contents, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_END), NULL);
1704                 if (!e) {
1705                         m->poisoned = true;
1706                         return -ENOMEM;
1707                 }
1708
1709                 nindex = e - c->signature;
1710         }
1711
1712         /* Align contents to 8 byte boundary */
1713         if (!message_extend_body(m, 8, 0))
1714                 return -ENOMEM;
1715
1716         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1717                 c->index = nindex;
1718
1719         return 0;
1720 }
1721
1722 static int bus_message_open_dict_entry(
1723                 sd_bus_message *m,
1724                 struct bus_container *c,
1725                 const char *contents) {
1726
1727         size_t nindex;
1728
1729         assert(m);
1730         assert(c);
1731         assert(contents);
1732
1733         if (!signature_is_pair(contents))
1734                 return -EINVAL;
1735
1736         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1737                 return -ENXIO;
1738
1739         if (c->signature && c->signature[c->index]) {
1740                 size_t l;
1741
1742                 l = strlen(contents);
1743
1744                 if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
1745                     !startswith(c->signature + c->index + 1, contents) ||
1746                     c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
1747                         return -ENXIO;
1748
1749                 nindex = c->index + 1 + l + 1;
1750         } else
1751                 return -ENXIO;
1752
1753         /* Align contents to 8 byte boundary */
1754         if (!message_extend_body(m, 8, 0))
1755                 return -ENOMEM;
1756
1757         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1758                 c->index = nindex;
1759
1760         return 0;
1761 }
1762
1763 _public_ int sd_bus_message_open_container(
1764                 sd_bus_message *m,
1765                 char type,
1766                 const char *contents) {
1767
1768         struct bus_container *c, *w;
1769         uint32_t *array_size = NULL;
1770         char *signature;
1771         size_t before;
1772         int r;
1773
1774         assert_return(m, -EINVAL);
1775         assert_return(!m->sealed, -EPERM);
1776         assert_return(contents, -EINVAL);
1777         assert_return(!m->poisoned, -ESTALE);
1778
1779         /* Make sure we have space for one more container */
1780         w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
1781         if (!w) {
1782                 m->poisoned = true;
1783                 return -ENOMEM;
1784         }
1785
1786         m->containers = w;
1787
1788         c = message_get_container(m);
1789
1790         signature = strdup(contents);
1791         if (!signature) {
1792                 m->poisoned = true;
1793                 return -ENOMEM;
1794         }
1795
1796         /* Save old index in the parent container, in case we have to
1797          * abort this container */
1798         c->saved_index = c->index;
1799         before = m->header->body_size;
1800
1801         if (type == SD_BUS_TYPE_ARRAY)
1802                 r = bus_message_open_array(m, c, contents, &array_size);
1803         else if (type == SD_BUS_TYPE_VARIANT)
1804                 r = bus_message_open_variant(m, c, contents);
1805         else if (type == SD_BUS_TYPE_STRUCT)
1806                 r = bus_message_open_struct(m, c, contents);
1807         else if (type == SD_BUS_TYPE_DICT_ENTRY)
1808                 r = bus_message_open_dict_entry(m, c, contents);
1809         else
1810                 r = -EINVAL;
1811
1812         if (r < 0) {
1813                 free(signature);
1814                 return r;
1815         }
1816
1817         /* OK, let's fill it in */
1818         w += m->n_containers++;
1819         w->enclosing = type;
1820         w->signature = signature;
1821         w->index = 0;
1822         w->array_size = array_size;
1823         w->before = before;
1824         w->begin = m->rindex;
1825
1826         return 0;
1827 }
1828
1829 _public_ int sd_bus_message_close_container(sd_bus_message *m) {
1830         struct bus_container *c;
1831
1832         assert_return(m, -EINVAL);
1833         assert_return(!m->sealed, -EPERM);
1834         assert_return(m->n_containers > 0, -EINVAL);
1835         assert_return(!m->poisoned, -ESTALE);
1836
1837         c = message_get_container(m);
1838         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1839                 if (c->signature && c->signature[c->index] != 0)
1840                         return -EINVAL;
1841
1842         free(c->signature);
1843         m->n_containers--;
1844
1845         return 0;
1846 }
1847
1848 typedef struct {
1849         const char *types;
1850         unsigned n_struct;
1851         unsigned n_array;
1852 } TypeStack;
1853
1854 static int type_stack_push(TypeStack *stack, unsigned max, unsigned *i, const char *types, unsigned n_struct, unsigned n_array) {
1855         assert(stack);
1856         assert(max > 0);
1857
1858         if (*i >= max)
1859                 return -EINVAL;
1860
1861         stack[*i].types = types;
1862         stack[*i].n_struct = n_struct;
1863         stack[*i].n_array = n_array;
1864         (*i)++;
1865
1866         return 0;
1867 }
1868
1869 static int type_stack_pop(TypeStack *stack, unsigned max, unsigned *i, const char **types, unsigned *n_struct, unsigned *n_array) {
1870         assert(stack);
1871         assert(max > 0);
1872         assert(types);
1873         assert(n_struct);
1874         assert(n_array);
1875
1876         if (*i <= 0)
1877                 return 0;
1878
1879         (*i)--;
1880         *types = stack[*i].types;
1881         *n_struct = stack[*i].n_struct;
1882         *n_array = stack[*i].n_array;
1883
1884         return 1;
1885 }
1886
1887 int bus_message_append_ap(
1888                 sd_bus_message *m,
1889                 const char *types,
1890                 va_list ap) {
1891
1892         unsigned n_array, n_struct;
1893         TypeStack stack[BUS_CONTAINER_DEPTH];
1894         unsigned stack_ptr = 0;
1895         int r;
1896
1897         assert(m);
1898
1899         if (!types)
1900                 return 0;
1901
1902         n_array = (unsigned) -1;
1903         n_struct = strlen(types);
1904
1905         for (;;) {
1906                 const char *t;
1907
1908                 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
1909                         r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
1910                         if (r < 0)
1911                                 return r;
1912                         if (r == 0)
1913                                 break;
1914
1915                         r = sd_bus_message_close_container(m);
1916                         if (r < 0)
1917                                 return r;
1918
1919                         continue;
1920                 }
1921
1922                 t = types;
1923                 if (n_array != (unsigned) -1)
1924                         n_array --;
1925                 else {
1926                         types ++;
1927                         n_struct--;
1928                 }
1929
1930                 switch (*t) {
1931
1932                 case SD_BUS_TYPE_BYTE: {
1933                         uint8_t x;
1934
1935                         x = (uint8_t) va_arg(ap, int);
1936                         r = sd_bus_message_append_basic(m, *t, &x);
1937                         break;
1938                 }
1939
1940                 case SD_BUS_TYPE_BOOLEAN:
1941                 case SD_BUS_TYPE_INT32:
1942                 case SD_BUS_TYPE_UINT32:
1943                 case SD_BUS_TYPE_UNIX_FD: {
1944                         uint32_t x;
1945
1946                         /* We assume a boolean is the same as int32_t */
1947                         assert_cc(sizeof(int32_t) == sizeof(int));
1948
1949                         x = va_arg(ap, uint32_t);
1950                         r = sd_bus_message_append_basic(m, *t, &x);
1951                         break;
1952                 }
1953
1954                 case SD_BUS_TYPE_INT16:
1955                 case SD_BUS_TYPE_UINT16: {
1956                         uint16_t x;
1957
1958                         x = (uint16_t) va_arg(ap, int);
1959                         r = sd_bus_message_append_basic(m, *t, &x);
1960                         break;
1961                 }
1962
1963                 case SD_BUS_TYPE_INT64:
1964                 case SD_BUS_TYPE_UINT64:
1965                 case SD_BUS_TYPE_DOUBLE: {
1966                         uint64_t x;
1967
1968                         x = va_arg(ap, uint64_t);
1969                         r = sd_bus_message_append_basic(m, *t, &x);
1970                         break;
1971                 }
1972
1973                 case SD_BUS_TYPE_STRING:
1974                 case SD_BUS_TYPE_OBJECT_PATH:
1975                 case SD_BUS_TYPE_SIGNATURE: {
1976                         const char *x;
1977
1978                         x = va_arg(ap, const char*);
1979                         r = sd_bus_message_append_basic(m, *t, x);
1980                         break;
1981                 }
1982
1983                 case SD_BUS_TYPE_ARRAY: {
1984                         size_t k;
1985
1986                         r = signature_element_length(t + 1, &k);
1987                         if (r < 0)
1988                                 return r;
1989
1990                         {
1991                                 char s[k + 1];
1992                                 memcpy(s, t + 1, k);
1993                                 s[k] = 0;
1994
1995                                 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, s);
1996                                 if (r < 0)
1997                                         return r;
1998                         }
1999
2000                         if (n_array == (unsigned) -1) {
2001                                 types += k;
2002                                 n_struct -= k;
2003                         }
2004
2005                         r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2006                         if (r < 0)
2007                                 return r;
2008
2009                         types = t + 1;
2010                         n_struct = k;
2011                         n_array = va_arg(ap, unsigned);
2012
2013                         break;
2014                 }
2015
2016                 case SD_BUS_TYPE_VARIANT: {
2017                         const char *s;
2018
2019                         s = va_arg(ap, const char*);
2020                         if (!s)
2021                                 return -EINVAL;
2022
2023                         r = sd_bus_message_open_container(m, SD_BUS_TYPE_VARIANT, s);
2024                         if (r < 0)
2025                                 return r;
2026
2027                         r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2028                         if (r < 0)
2029                                 return r;
2030
2031                         types = s;
2032                         n_struct = strlen(s);
2033                         n_array = (unsigned) -1;
2034
2035                         break;
2036                 }
2037
2038                 case SD_BUS_TYPE_STRUCT_BEGIN:
2039                 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
2040                         size_t k;
2041
2042                         r = signature_element_length(t, &k);
2043                         if (r < 0)
2044                                 return r;
2045
2046                         {
2047                                 char s[k - 1];
2048
2049                                 memcpy(s, t + 1, k - 2);
2050                                 s[k - 2] = 0;
2051
2052                                 r = sd_bus_message_open_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
2053                                 if (r < 0)
2054                                         return r;
2055                         }
2056
2057                         if (n_array == (unsigned) -1) {
2058                                 types += k - 1;
2059                                 n_struct -= k - 1;
2060                         }
2061
2062                         r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2063                         if (r < 0)
2064                                 return r;
2065
2066                         types = t + 1;
2067                         n_struct = k - 2;
2068                         n_array = (unsigned) -1;
2069
2070                         break;
2071                 }
2072
2073                 default:
2074                         r = -EINVAL;
2075                 }
2076
2077                 if (r < 0)
2078                         return r;
2079         }
2080
2081         return 0;
2082 }
2083
2084 _public_ int sd_bus_message_append(sd_bus_message *m, const char *types, ...) {
2085         va_list ap;
2086         int r;
2087
2088         assert_return(m, -EINVAL);
2089         assert_return(types, -EINVAL);
2090         assert_return(!m->sealed, -EPERM);
2091         assert_return(!m->poisoned, -ESTALE);
2092
2093         va_start(ap, types);
2094         r = bus_message_append_ap(m, types, ap);
2095         va_end(ap);
2096
2097         return r;
2098 }
2099
2100 _public_ int sd_bus_message_append_array_space(sd_bus_message *m,
2101                                                char type,
2102                                                size_t size,
2103                                                void **ptr) {
2104         ssize_t align, sz;
2105         void *a;
2106         int r;
2107
2108         assert_return(m, -EINVAL);
2109         assert_return(!m->sealed, -EPERM);
2110         assert_return(bus_type_is_trivial(type), -EINVAL);
2111         assert_return(ptr || size == 0, -EINVAL);
2112         assert_return(!m->poisoned, -ESTALE);
2113
2114         align = bus_type_get_alignment(type);
2115         sz = bus_type_get_size(type);
2116
2117         assert_se(align > 0);
2118         assert_se(sz > 0);
2119
2120         if (size % sz != 0)
2121                 return -EINVAL;
2122
2123         r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
2124         if (r < 0)
2125                 return r;
2126
2127         a = message_extend_body(m, align, size);
2128         if (!a)
2129                 return -ENOMEM;
2130
2131         r = sd_bus_message_close_container(m);
2132         if (r < 0)
2133                 return r;
2134
2135         *ptr = a;
2136         return 0;
2137 }
2138
2139 _public_ int sd_bus_message_append_array(sd_bus_message *m,
2140                                          char type,
2141                                          const void *ptr,
2142                                          size_t size) {
2143         int r;
2144         void *p;
2145
2146         assert_return(m, -EINVAL);
2147         assert_return(!m->sealed, -EPERM);
2148         assert_return(bus_type_is_trivial(type), -EINVAL);
2149         assert_return(ptr || size == 0, -EINVAL);
2150         assert_return(!m->poisoned, -ESTALE);
2151
2152         r = sd_bus_message_append_array_space(m, type, size, &p);
2153         if (r < 0)
2154                 return r;
2155
2156         if (size > 0)
2157                 memcpy(p, ptr, size);
2158
2159         return 0;
2160 }
2161
2162 _public_ int sd_bus_message_append_array_memfd(sd_bus_message *m,
2163                                                char type,
2164                                                sd_memfd *memfd) {
2165         _cleanup_close_ int copy_fd = -1;
2166         struct bus_body_part *part;
2167         ssize_t align, sz;
2168         uint64_t size;
2169         void *a;
2170         int r;
2171
2172         if (!m)
2173                 return -EINVAL;
2174         if (!memfd)
2175                 return -EINVAL;
2176         if (m->sealed)
2177                 return -EPERM;
2178         if (!bus_type_is_trivial(type))
2179                 return -EINVAL;
2180         if (m->poisoned)
2181                 return -ESTALE;
2182
2183         r = sd_memfd_set_sealed(memfd, true);
2184         if (r < 0)
2185                 return r;
2186
2187         copy_fd = sd_memfd_dup_fd(memfd);
2188         if (copy_fd < 0)
2189                 return copy_fd;
2190
2191         r = sd_memfd_get_size(memfd, &size);
2192         if (r < 0)
2193                 return r;
2194
2195         align = bus_type_get_alignment(type);
2196         sz = bus_type_get_size(type);
2197
2198         assert_se(align > 0);
2199         assert_se(sz > 0);
2200
2201         if (size % sz != 0)
2202                 return -EINVAL;
2203
2204         if (size > (uint64_t) (uint32_t) -1)
2205                 return -EINVAL;
2206
2207         r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
2208         if (r < 0)
2209                 return r;
2210
2211         a = message_extend_body(m, align, 0);
2212         if (!a)
2213                 return -ENOMEM;
2214
2215         part = message_append_part(m);
2216         if (!part)
2217                 return -ENOMEM;
2218
2219         part->memfd = copy_fd;
2220         part->sealed = true;
2221         part->size = size;
2222         copy_fd = -1;
2223
2224         message_extend_containers(m, size);
2225         m->header->body_size += size;
2226
2227         return sd_bus_message_close_container(m);
2228 }
2229
2230 _public_ int sd_bus_message_append_string_memfd(sd_bus_message *m, sd_memfd *memfd) {
2231         _cleanup_close_ int copy_fd = -1;
2232         struct bus_body_part *part;
2233         struct bus_container *c;
2234         uint64_t size;
2235         void *a;
2236         int r;
2237
2238         assert_return(m, -EINVAL);
2239         assert_return(memfd, -EINVAL);
2240         assert_return(!m->sealed, -EPERM);
2241         assert_return(!m->poisoned, -ESTALE);
2242
2243         r = sd_memfd_set_sealed(memfd, true);
2244         if (r < 0)
2245                 return r;
2246
2247         copy_fd = sd_memfd_dup_fd(memfd);
2248         if (copy_fd < 0)
2249                 return copy_fd;
2250
2251         r = sd_memfd_get_size(memfd, &size);
2252         if (r < 0)
2253                 return r;
2254
2255         /* We require this to be NUL terminated */
2256         if (size == 0)
2257                 return -EINVAL;
2258
2259         if (size > (uint64_t) (uint32_t) -1)
2260                 return -EINVAL;
2261
2262         c = message_get_container(m);
2263         if (c->signature && c->signature[c->index]) {
2264                 /* Container signature is already set */
2265
2266                 if (c->signature[c->index] != SD_BUS_TYPE_STRING)
2267                         return -ENXIO;
2268         } else {
2269                 char *e;
2270
2271                 /* Maybe we can append to the signature? But only if this is the top-level container*/
2272                 if (c->enclosing != 0)
2273                         return -ENXIO;
2274
2275                 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRING), NULL);
2276                 if (!e) {
2277                         m->poisoned = true;
2278                         return -ENOMEM;
2279                 }
2280         }
2281
2282         a = message_extend_body(m, 4, 4);
2283         if (!a)
2284                 return -ENOMEM;
2285
2286         *(uint32_t*) a = size - 1;
2287
2288         part = message_append_part(m);
2289         if (!part)
2290                 return -ENOMEM;
2291
2292         part->memfd = copy_fd;
2293         part->sealed = true;
2294         part->size = size;
2295         copy_fd = -1;
2296
2297         message_extend_containers(m, size);
2298         m->header->body_size += size;
2299
2300         if (c->enclosing != SD_BUS_TYPE_ARRAY)
2301                 c->index++;
2302
2303         return 0;
2304 }
2305
2306 _public_ int sd_bus_message_append_strv(sd_bus_message *m, char **l) {
2307         char **i;
2308         int r;
2309
2310         assert_return(m, -EINVAL);
2311         assert_return(!m->sealed, -EPERM);
2312         assert_return(!m->poisoned, -ESTALE);
2313
2314         r = sd_bus_message_open_container(m, 'a', "s");
2315         if (r < 0)
2316                 return r;
2317
2318         STRV_FOREACH(i, l) {
2319                 r = sd_bus_message_append_basic(m, 's', *i);
2320                 if (r < 0)
2321                         return r;
2322         }
2323
2324         return sd_bus_message_close_container(m);
2325 }
2326
2327 int bus_body_part_map(struct bus_body_part *part) {
2328         void *p;
2329         size_t psz;
2330
2331         assert_se(part);
2332
2333         if (part->data)
2334                 return 0;
2335
2336         if (part->size <= 0)
2337                 return 0;
2338
2339         /* For smaller zero parts (as used for padding) we don't need to map anything... */
2340         if (part->memfd < 0 && part->is_zero && part->size < 8) {
2341                 static const uint8_t zeroes[7] = { };
2342                 part->data = (void*) zeroes;
2343                 return 0;
2344         }
2345
2346         psz = PAGE_ALIGN(part->size);
2347
2348         if (part->memfd >= 0)
2349                 p = mmap(NULL, psz, PROT_READ, MAP_SHARED, part->memfd, 0);
2350         else if (part->is_zero)
2351                 p = mmap(NULL, psz, PROT_READ, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
2352         else
2353                 return -EINVAL;
2354
2355         if (p == MAP_FAILED)
2356                 return -errno;
2357
2358         part->mapped = psz;
2359         part->data = p;
2360         part->munmap_this = true;
2361
2362         return 0;
2363 }
2364
2365 void bus_body_part_unmap(struct bus_body_part *part) {
2366
2367         assert_se(part);
2368
2369         if (part->memfd < 0)
2370                 return;
2371
2372         if (!part->data)
2373                 return;
2374
2375         if (!part->munmap_this)
2376                 return;
2377
2378         assert_se(munmap(part->data, part->mapped) == 0);
2379
2380         part->data = NULL;
2381         part->mapped = 0;
2382         part->munmap_this = false;
2383
2384         return;
2385 }
2386
2387 static int buffer_peek(const void *p, uint32_t sz, size_t *rindex, size_t align, size_t nbytes, void **r) {
2388         size_t k, start, end;
2389
2390         assert(rindex);
2391         assert(align > 0);
2392
2393         start = ALIGN_TO((size_t) *rindex, align);
2394         end = start + nbytes;
2395
2396         if (end > sz)
2397                 return -EBADMSG;
2398
2399         /* Verify that padding is 0 */
2400         for (k = *rindex; k < start; k++)
2401                 if (((const uint8_t*) p)[k] != 0)
2402                         return -EBADMSG;
2403
2404         if (r)
2405                 *r = (uint8_t*) p + start;
2406
2407         *rindex = end;
2408
2409         return 1;
2410 }
2411
2412 static bool message_end_of_signature(sd_bus_message *m) {
2413         struct bus_container *c;
2414
2415         assert(m);
2416
2417         c = message_get_container(m);
2418         return !c->signature || c->signature[c->index] == 0;
2419 }
2420
2421 static bool message_end_of_array(sd_bus_message *m, size_t index) {
2422         struct bus_container *c;
2423
2424         assert(m);
2425
2426         c = message_get_container(m);
2427         if (!c->array_size)
2428                 return false;
2429
2430         return index >= c->begin + BUS_MESSAGE_BSWAP32(m, *c->array_size);
2431 }
2432
2433 _public_ int sd_bus_message_at_end(sd_bus_message *m, int complete) {
2434         assert_return(m, -EINVAL);
2435         assert_return(m->sealed, -EPERM);
2436
2437         if (complete && m->n_containers > 0)
2438                 return false;
2439
2440         if (message_end_of_signature(m))
2441                 return true;
2442
2443         if (message_end_of_array(m, m->rindex))
2444                 return true;
2445
2446         return false;
2447 }
2448
2449 static struct bus_body_part* find_part(sd_bus_message *m, size_t index, size_t sz, void **p) {
2450         struct bus_body_part *part;
2451         size_t begin;
2452         int r;
2453
2454         assert(m);
2455
2456         if (m->cached_rindex_part && index >= m->cached_rindex_part_begin) {
2457                 part = m->cached_rindex_part;
2458                 begin = m->cached_rindex_part_begin;
2459         } else {
2460                 part = &m->body;
2461                 begin = 0;
2462         }
2463
2464         while (part) {
2465                 if (index < begin)
2466                         return NULL;
2467
2468                 if (index + sz <= begin + part->size) {
2469
2470                         r = bus_body_part_map(part);
2471                         if (r < 0)
2472                                 return NULL;
2473
2474                         if (p)
2475                                 *p = (uint8_t*) part->data + index - begin;
2476
2477                         m->cached_rindex_part = part;
2478                         m->cached_rindex_part_begin = begin;
2479
2480                         return part;
2481                 }
2482
2483                 begin += part->size;
2484                 part = part->next;
2485         }
2486
2487         return NULL;
2488 }
2489
2490 static int message_peek_body(
2491                 sd_bus_message *m,
2492                 size_t *rindex,
2493                 size_t align,
2494                 size_t nbytes,
2495                 void **ret) {
2496
2497         size_t k, start, end, padding;
2498         struct bus_body_part *part;
2499         uint8_t *q;
2500
2501         assert(m);
2502         assert(rindex);
2503         assert(align > 0);
2504
2505         if (message_end_of_array(m, *rindex))
2506                 return 0;
2507
2508         start = ALIGN_TO((size_t) *rindex, align);
2509         padding = start - *rindex;
2510         end = start + nbytes;
2511
2512         if (end > BUS_MESSAGE_BODY_SIZE(m))
2513                 return -EBADMSG;
2514
2515         part = find_part(m, *rindex, padding, (void**) &q);
2516         if (!part)
2517                 return -EBADMSG;
2518
2519         if (q) {
2520                 /* Verify padding */
2521                 for (k = 0; k < padding; k++)
2522                         if (q[k] != 0)
2523                                 return -EBADMSG;
2524         }
2525
2526         part = find_part(m, start, nbytes, (void**) &q);
2527         if (!part || !q)
2528                 return -EBADMSG;
2529
2530         *rindex = end;
2531
2532         if (ret)
2533                 *ret = q;
2534
2535         return 1;
2536 }
2537
2538 static bool validate_nul(const char *s, size_t l) {
2539
2540         /* Check for NUL chars in the string */
2541         if (memchr(s, 0, l))
2542                 return false;
2543
2544         /* Check for NUL termination */
2545         if (s[l] != 0)
2546                 return false;
2547
2548         return true;
2549 }
2550
2551 static bool validate_string(const char *s, size_t l) {
2552
2553         if (!validate_nul(s, l))
2554                 return false;
2555
2556         /* Check if valid UTF8 */
2557         if (!utf8_is_valid(s))
2558                 return false;
2559
2560         return true;
2561 }
2562
2563 static bool validate_signature(const char *s, size_t l) {
2564
2565         if (!validate_nul(s, l))
2566                 return false;
2567
2568         /* Check if valid signature */
2569         if (!signature_is_valid(s, true))
2570                 return false;
2571
2572         return true;
2573 }
2574
2575 static bool validate_object_path(const char *s, size_t l) {
2576
2577         if (!validate_nul(s, l))
2578                 return false;
2579
2580         if (!object_path_is_valid(s))
2581                 return false;
2582
2583         return true;
2584 }
2585
2586 _public_ int sd_bus_message_read_basic(sd_bus_message *m, char type, void *p) {
2587         struct bus_container *c;
2588         void *q;
2589         int r;
2590
2591         assert_return(m, -EINVAL);
2592         assert_return(m->sealed, -EPERM);
2593         assert_return(bus_type_is_basic(type), -EINVAL);
2594
2595         if (message_end_of_signature(m))
2596                 return -ENXIO;
2597
2598         if (message_end_of_array(m, m->rindex))
2599                 return 0;
2600
2601         c = message_get_container(m);
2602         if (c->signature[c->index] != type)
2603                 return -ENXIO;
2604
2605         switch (type) {
2606
2607         case SD_BUS_TYPE_STRING:
2608         case SD_BUS_TYPE_OBJECT_PATH: {
2609                 uint32_t l;
2610                 size_t rindex;
2611
2612                 rindex = m->rindex;
2613                 r = message_peek_body(m, &rindex, 4, 4, &q);
2614                 if (r <= 0)
2615                         return r;
2616
2617                 l = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2618                 r = message_peek_body(m, &rindex, 1, l+1, &q);
2619                 if (r < 0)
2620                         return r;
2621                 if (r == 0)
2622                         return -EBADMSG;
2623
2624                 if (type == SD_BUS_TYPE_OBJECT_PATH) {
2625                         if (!validate_object_path(q, l))
2626                                 return -EBADMSG;
2627                 } else {
2628                         if (!validate_string(q, l))
2629                                 return -EBADMSG;
2630                 }
2631
2632                 m->rindex = rindex;
2633                 if (p)
2634                         *(const char**) p = q;
2635
2636                 break;
2637         }
2638
2639         case SD_BUS_TYPE_SIGNATURE: {
2640                 uint8_t l;
2641                 size_t rindex;
2642
2643                 rindex = m->rindex;
2644                 r = message_peek_body(m, &rindex, 1, 1, &q);
2645                 if (r <= 0)
2646                         return r;
2647
2648                 l = *(uint8_t*) q;
2649                 r = message_peek_body(m, &rindex, 1, l+1, &q);
2650                 if (r < 0)
2651                         return r;
2652                 if (r == 0)
2653                         return -EBADMSG;
2654
2655                 if (!validate_signature(q, l))
2656                         return -EBADMSG;
2657
2658                 m->rindex = rindex;
2659
2660                 if (p)
2661                         *(const char**) p = q;
2662                 break;
2663         }
2664
2665         default: {
2666                 ssize_t sz, align;
2667                 size_t rindex;
2668
2669                 align = bus_type_get_alignment(type);
2670                 sz = bus_type_get_size(type);
2671                 assert(align > 0 && sz > 0);
2672
2673                 rindex = m->rindex;
2674                 r = message_peek_body(m, &rindex, align, sz, &q);
2675                 if (r <= 0)
2676                         return r;
2677
2678                 switch (type) {
2679
2680                 case SD_BUS_TYPE_BYTE:
2681                         if (p)
2682                                 *(uint8_t*) p = *(uint8_t*) q;
2683                         break;
2684
2685                 case SD_BUS_TYPE_BOOLEAN:
2686                         if (p)
2687                                 *(int*) p = !!*(uint32_t*) q;
2688                         break;
2689
2690                 case SD_BUS_TYPE_INT16:
2691                 case SD_BUS_TYPE_UINT16:
2692                         if (p)
2693                                 *(uint16_t*) p = BUS_MESSAGE_BSWAP16(m, *(uint16_t*) q);
2694                         break;
2695
2696                 case SD_BUS_TYPE_INT32:
2697                 case SD_BUS_TYPE_UINT32:
2698                         if (p)
2699                                 *(uint32_t*) p = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2700                         break;
2701
2702                 case SD_BUS_TYPE_INT64:
2703                 case SD_BUS_TYPE_UINT64:
2704                 case SD_BUS_TYPE_DOUBLE:
2705                         if (p)
2706                                 *(uint64_t*) p = BUS_MESSAGE_BSWAP64(m, *(uint64_t*) q);
2707                         break;
2708
2709                 case SD_BUS_TYPE_UNIX_FD: {
2710                         uint32_t j;
2711
2712                         j = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2713                         if (j >= m->n_fds)
2714                                 return -EBADMSG;
2715
2716                         if (p)
2717                                 *(int*) p = m->fds[j];
2718                         break;
2719                 }
2720
2721                 default:
2722                         assert_not_reached("Unknown basic type...");
2723                 }
2724
2725                 m->rindex = rindex;
2726
2727                 break;
2728         }
2729         }
2730
2731         if (c->enclosing != SD_BUS_TYPE_ARRAY)
2732                 c->index++;
2733
2734         return 1;
2735 }
2736
2737 static int bus_message_enter_array(
2738                 sd_bus_message *m,
2739                 struct bus_container *c,
2740                 const char *contents,
2741                 uint32_t **array_size) {
2742
2743         size_t rindex;
2744         void *q;
2745         int r, alignment;
2746
2747         assert(m);
2748         assert(c);
2749         assert(contents);
2750         assert(array_size);
2751
2752         if (!signature_is_single(contents, true))
2753                 return -EINVAL;
2754
2755         alignment = bus_type_get_alignment(contents[0]);
2756         if (alignment < 0)
2757                 return alignment;
2758
2759         if (!c->signature || c->signature[c->index] == 0)
2760                 return 0;
2761
2762         if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
2763                 return -ENXIO;
2764
2765         if (!startswith(c->signature + c->index + 1, contents))
2766                 return -ENXIO;
2767
2768         rindex = m->rindex;
2769         r = message_peek_body(m, &rindex, 4, 4, &q);
2770         if (r <= 0)
2771                 return r;
2772
2773         if (BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q) > BUS_ARRAY_MAX_SIZE)
2774                 return -EBADMSG;
2775
2776         r = message_peek_body(m, &rindex, alignment, 0, NULL);
2777         if (r < 0)
2778                 return r;
2779         if (r == 0)
2780                 return -EBADMSG;
2781
2782         if (c->enclosing != SD_BUS_TYPE_ARRAY)
2783                 c->index += 1 + strlen(contents);
2784
2785         m->rindex = rindex;
2786
2787         *array_size = (uint32_t*) q;
2788
2789         return 1;
2790 }
2791
2792 static int bus_message_enter_variant(
2793                 sd_bus_message *m,
2794                 struct bus_container *c,
2795                 const char *contents) {
2796
2797         size_t rindex;
2798         uint8_t l;
2799         void *q;
2800         int r;
2801
2802         assert(m);
2803         assert(c);
2804         assert(contents);
2805
2806         if (!signature_is_single(contents, false))
2807                 return -EINVAL;
2808
2809         if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
2810                 return -EINVAL;
2811
2812         if (!c->signature || c->signature[c->index] == 0)
2813                 return 0;
2814
2815         if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
2816                 return -ENXIO;
2817
2818         rindex = m->rindex;
2819         r = message_peek_body(m, &rindex, 1, 1, &q);
2820         if (r <= 0)
2821                 return r;
2822
2823         l = *(uint8_t*) q;
2824         r = message_peek_body(m, &rindex, 1, l+1, &q);
2825         if (r < 0)
2826                 return r;
2827         if (r == 0)
2828                 return -EBADMSG;
2829
2830         if (!validate_signature(q, l))
2831                 return -EBADMSG;
2832
2833         if (!streq(q, contents))
2834                 return -ENXIO;
2835
2836         if (c->enclosing != SD_BUS_TYPE_ARRAY)
2837                 c->index++;
2838
2839         m->rindex = rindex;
2840
2841         return 1;
2842 }
2843
2844 static int bus_message_enter_struct(
2845                 sd_bus_message *m,
2846                 struct bus_container *c,
2847                 const char *contents) {
2848
2849         size_t l;
2850         int r;
2851
2852         assert(m);
2853         assert(c);
2854         assert(contents);
2855
2856         if (!signature_is_valid(contents, false))
2857                 return -EINVAL;
2858
2859         if (!c->signature || c->signature[c->index] == 0)
2860                 return 0;
2861
2862         l = strlen(contents);
2863
2864         if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
2865             !startswith(c->signature + c->index + 1, contents) ||
2866             c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
2867                 return -ENXIO;
2868
2869         r = message_peek_body(m, &m->rindex, 8, 0, NULL);
2870         if (r <= 0)
2871                 return r;
2872
2873         if (c->enclosing != SD_BUS_TYPE_ARRAY)
2874                 c->index += 1 + l + 1;
2875
2876         return 1;
2877 }
2878
2879 static int bus_message_enter_dict_entry(
2880                 sd_bus_message *m,
2881                 struct bus_container *c,
2882                 const char *contents) {
2883
2884         size_t l;
2885         int r;
2886
2887         assert(m);
2888         assert(c);
2889         assert(contents);
2890
2891         if (!signature_is_pair(contents))
2892                 return -EINVAL;
2893
2894         if (c->enclosing != SD_BUS_TYPE_ARRAY)
2895                 return -ENXIO;
2896
2897         if (!c->signature || c->signature[c->index] == 0)
2898                 return 0;
2899
2900         l = strlen(contents);
2901
2902         if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
2903             !startswith(c->signature + c->index + 1, contents) ||
2904             c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
2905                 return -ENXIO;
2906
2907         r = message_peek_body(m, &m->rindex, 8, 0, NULL);
2908         if (r <= 0)
2909                 return r;
2910
2911         if (c->enclosing != SD_BUS_TYPE_ARRAY)
2912                 c->index += 1 + l + 1;
2913
2914         return 1;
2915 }
2916
2917 _public_ int sd_bus_message_enter_container(sd_bus_message *m,
2918                                             char type,
2919                                             const char *contents) {
2920         struct bus_container *c, *w;
2921         uint32_t *array_size = NULL;
2922         char *signature;
2923         size_t before;
2924         int r;
2925
2926         assert_return(m, -EINVAL);
2927         assert_return(m->sealed, -EPERM);
2928         assert_return(type != 0 || !contents, -EINVAL);
2929
2930         if (type == 0 || !contents) {
2931                 const char *cc;
2932                 char tt;
2933
2934                 /* Allow entering into anonymous containers */
2935                 r = sd_bus_message_peek_type(m, &tt, &cc);
2936                 if (r <= 0)
2937                         return r;
2938
2939                 if (type != 0 && type != tt)
2940                         return -ENXIO;
2941
2942                 if (contents && !streq(contents, cc))
2943                         return -ENXIO;
2944
2945                 type = tt;
2946                 contents = cc;
2947         }
2948
2949         /*
2950          * We enforce a global limit on container depth, that is much
2951          * higher than the 32 structs and 32 arrays the specification
2952          * mandates. This is simpler to implement for us, and we need
2953          * this only to ensure our container array doesn't grow
2954          * without bounds. We are happy to return any data from a
2955          * message as long as the data itself is valid, even if the
2956          * overall message might be not.
2957          *
2958          * Note that the message signature is validated when
2959          * parsing the headers, and that validation does check the
2960          * 32/32 limit.
2961          *
2962          * Note that the specification defines no limits on the depth
2963          * of stacked variants, but we do.
2964          */
2965         if (m->n_containers >= BUS_CONTAINER_DEPTH)
2966                 return -EBADMSG;
2967
2968         w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
2969         if (!w)
2970                 return -ENOMEM;
2971         m->containers = w;
2972
2973         if (message_end_of_signature(m))
2974                 return -ENXIO;
2975
2976         if (message_end_of_array(m, m->rindex))
2977                 return 0;
2978
2979         c = message_get_container(m);
2980
2981         signature = strdup(contents);
2982         if (!signature)
2983                 return -ENOMEM;
2984
2985         c->saved_index = c->index;
2986         before = m->rindex;
2987
2988         if (type == SD_BUS_TYPE_ARRAY)
2989                 r = bus_message_enter_array(m, c, contents, &array_size);
2990         else if (type == SD_BUS_TYPE_VARIANT)
2991                 r = bus_message_enter_variant(m, c, contents);
2992         else if (type == SD_BUS_TYPE_STRUCT)
2993                 r = bus_message_enter_struct(m, c, contents);
2994         else if (type == SD_BUS_TYPE_DICT_ENTRY)
2995                 r = bus_message_enter_dict_entry(m, c, contents);
2996         else
2997                 r = -EINVAL;
2998
2999         if (r <= 0) {
3000                 free(signature);
3001                 return r;
3002         }
3003
3004         /* OK, let's fill it in */
3005         w += m->n_containers++;
3006         w->enclosing = type;
3007         w->signature = signature;
3008         w->index = 0;
3009         w->array_size = array_size;
3010         w->before = before;
3011         w->begin = m->rindex;
3012
3013         return 1;
3014 }
3015
3016 _public_ int sd_bus_message_exit_container(sd_bus_message *m) {
3017         struct bus_container *c;
3018
3019         assert_return(m, -EINVAL);
3020         assert_return(m->sealed, -EPERM);
3021         assert_return(m->n_containers > 0, -ENOENT);
3022
3023         c = message_get_container(m);
3024         if (c->enclosing == SD_BUS_TYPE_ARRAY) {
3025                 uint32_t l;
3026
3027                 l = BUS_MESSAGE_BSWAP32(m, *c->array_size);
3028                 if (c->begin + l != m->rindex)
3029                         return -EBUSY;
3030
3031         } else {
3032                 if (c->signature && c->signature[c->index] != 0)
3033                         return -EINVAL;
3034         }
3035
3036         free(c->signature);
3037         m->n_containers--;
3038
3039         return 1;
3040 }
3041
3042 static void message_quit_container(sd_bus_message *m) {
3043         struct bus_container *c;
3044
3045         assert(m);
3046         assert(m->sealed);
3047         assert(m->n_containers > 0);
3048
3049         c = message_get_container(m);
3050
3051         /* Undo seeks */
3052         assert(m->rindex >= c->before);
3053         m->rindex = c->before;
3054
3055         /* Free container */
3056         free(c->signature);
3057         m->n_containers--;
3058
3059         /* Correct index of new top-level container */
3060         c = message_get_container(m);
3061         c->index = c->saved_index;
3062 }
3063
3064 _public_ int sd_bus_message_peek_type(sd_bus_message *m, char *type, const char **contents) {
3065         struct bus_container *c;
3066         int r;
3067
3068         assert_return(m, -EINVAL);
3069         assert_return(m->sealed, -EPERM);
3070
3071         if (message_end_of_signature(m))
3072                 goto eof;
3073
3074         if (message_end_of_array(m, m->rindex))
3075                 goto eof;
3076
3077         c = message_get_container(m);
3078
3079         if (bus_type_is_basic(c->signature[c->index])) {
3080                 if (contents)
3081                         *contents = NULL;
3082                 if (type)
3083                         *type = c->signature[c->index];
3084                 return 1;
3085         }
3086
3087         if (c->signature[c->index] == SD_BUS_TYPE_ARRAY) {
3088
3089                 if (contents) {
3090                         size_t l;
3091                         char *sig;
3092
3093                         r = signature_element_length(c->signature+c->index+1, &l);
3094                         if (r < 0)
3095                                 return r;
3096
3097                         assert(l >= 1);
3098
3099                         sig = strndup(c->signature + c->index + 1, l);
3100                         if (!sig)
3101                                 return -ENOMEM;
3102
3103                         free(m->peeked_signature);
3104                         m->peeked_signature = sig;
3105
3106                         *contents = sig;
3107                 }
3108
3109                 if (type)
3110                         *type = SD_BUS_TYPE_ARRAY;
3111
3112                 return 1;
3113         }
3114
3115         if (c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ||
3116             c->signature[c->index] == SD_BUS_TYPE_DICT_ENTRY_BEGIN) {
3117
3118                 if (contents) {
3119                         size_t l;
3120                         char *sig;
3121
3122                         r = signature_element_length(c->signature+c->index, &l);
3123                         if (r < 0)
3124                                 return r;
3125
3126                         assert(l >= 2);
3127                         sig = strndup(c->signature + c->index + 1, l - 2);
3128                         if (!sig)
3129                                 return -ENOMEM;
3130
3131                         free(m->peeked_signature);
3132                         m->peeked_signature = sig;
3133
3134                         *contents = sig;
3135                 }
3136
3137                 if (type)
3138                         *type = c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY;
3139
3140                 return 1;
3141         }
3142
3143         if (c->signature[c->index] == SD_BUS_TYPE_VARIANT) {
3144                 if (contents) {
3145                         size_t rindex, l;
3146                         void *q;
3147
3148                         rindex = m->rindex;
3149                         r = message_peek_body(m, &rindex, 1, 1, &q);
3150                         if (r < 0)
3151                                 return r;
3152                         if (r == 0)
3153                                 goto eof;
3154
3155                         l = *(uint8_t*) q;
3156                         r = message_peek_body(m, &rindex, 1, l+1, &q);
3157                         if (r < 0)
3158                                 return r;
3159                         if (r == 0)
3160                                 return -EBADMSG;
3161
3162                         if (!validate_signature(q, l))
3163                                 return -EBADMSG;
3164
3165                         *contents = q;
3166                 }
3167
3168                 if (type)
3169                         *type = SD_BUS_TYPE_VARIANT;
3170
3171                 return 1;
3172         }
3173
3174         return -EINVAL;
3175
3176 eof:
3177         if (type)
3178                 *type = 0;
3179         if (contents)
3180                 *contents = NULL;
3181         return 0;
3182 }
3183
3184 _public_ int sd_bus_message_rewind(sd_bus_message *m, int complete) {
3185         struct bus_container *c;
3186
3187         assert_return(m, -EINVAL);
3188         assert_return(m->sealed, -EPERM);
3189
3190         if (complete) {
3191                 message_reset_containers(m);
3192                 m->rindex = 0;
3193                 m->root_container.index = 0;
3194
3195                 c = message_get_container(m);
3196         } else {
3197                 c = message_get_container(m);
3198
3199                 c->index = 0;
3200                 m->rindex = c->begin;
3201         }
3202
3203         return !isempty(c->signature);
3204 }
3205 static int message_read_ap(
3206                 sd_bus_message *m,
3207                 const char *types,
3208                 va_list ap) {
3209
3210         unsigned n_array, n_struct;
3211         TypeStack stack[BUS_CONTAINER_DEPTH];
3212         unsigned stack_ptr = 0;
3213         unsigned n_loop = 0;
3214         int r;
3215
3216         assert(m);
3217
3218         if (isempty(types))
3219                 return 0;
3220
3221         /* Ideally, we'd just call ourselves recursively on every
3222          * complex type. However, the state of a va_list that is
3223          * passed to a function is undefined after that function
3224          * returns. This means we need to docode the va_list linearly
3225          * in a single stackframe. We hence implement our own
3226          * home-grown stack in an array. */
3227
3228         n_array = (unsigned) -1; /* lenght of current array entries */
3229         n_struct = strlen(types); /* length of current struct contents signature */
3230
3231         for (;;) {
3232                 const char *t;
3233
3234                 n_loop++;
3235
3236                 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
3237                         r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
3238                         if (r < 0)
3239                                 return r;
3240                         if (r == 0)
3241                                 break;
3242
3243                         r = sd_bus_message_exit_container(m);
3244                         if (r < 0)
3245                                 return r;
3246
3247                         continue;
3248                 }
3249
3250                 t = types;
3251                 if (n_array != (unsigned) -1)
3252                         n_array --;
3253                 else {
3254                         types ++;
3255                         n_struct--;
3256                 }
3257
3258                 switch (*t) {
3259
3260                 case SD_BUS_TYPE_BYTE:
3261                 case SD_BUS_TYPE_BOOLEAN:
3262                 case SD_BUS_TYPE_INT16:
3263                 case SD_BUS_TYPE_UINT16:
3264                 case SD_BUS_TYPE_INT32:
3265                 case SD_BUS_TYPE_UINT32:
3266                 case SD_BUS_TYPE_INT64:
3267                 case SD_BUS_TYPE_UINT64:
3268                 case SD_BUS_TYPE_DOUBLE:
3269                 case SD_BUS_TYPE_STRING:
3270                 case SD_BUS_TYPE_OBJECT_PATH:
3271                 case SD_BUS_TYPE_SIGNATURE:
3272                 case SD_BUS_TYPE_UNIX_FD: {
3273                         void *p;
3274
3275                         p = va_arg(ap, void*);
3276                         r = sd_bus_message_read_basic(m, *t, p);
3277                         if (r < 0)
3278                                 return r;
3279                         if (r == 0) {
3280