chiark / gitweb /
bus: export libsystemd-bus as a public library
[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(p, -EINVAL);
1327         assert_return(!m->sealed, -EPERM);
1328         assert_return(bus_type_is_basic(type), -EINVAL);
1329         assert_return(!m->poisoned, -ESTALE);
1330
1331         c = message_get_container(m);
1332
1333         if (c->signature && c->signature[c->index]) {
1334                 /* Container signature is already set */
1335
1336                 if (c->signature[c->index] != type)
1337                         return -ENXIO;
1338         } else {
1339                 char *e;
1340
1341                 /* Maybe we can append to the signature? But only if this is the top-level container*/
1342                 if (c->enclosing != 0)
1343                         return -ENXIO;
1344
1345                 e = strextend(&c->signature, CHAR_TO_STR(type), NULL);
1346                 if (!e) {
1347                         m->poisoned = true;
1348                         return -ENOMEM;
1349                 }
1350         }
1351
1352         switch (type) {
1353
1354         case SD_BUS_TYPE_STRING:
1355                 /* To make things easy we'll serialize a NULL string
1356                  * into the empty string */
1357                 p = strempty(p);
1358
1359                 /* Fall through... */
1360         case SD_BUS_TYPE_OBJECT_PATH:
1361
1362                 if (!p) {
1363                         r = -EINVAL;
1364                         goto fail;
1365                 }
1366
1367                 align = 4;
1368                 sz = 4 + strlen(p) + 1;
1369                 break;
1370
1371         case SD_BUS_TYPE_SIGNATURE:
1372
1373                 if (!p) {
1374                         r = -EINVAL;
1375                         goto fail;
1376                 }
1377
1378                 align = 1;
1379                 sz = 1 + strlen(p) + 1;
1380                 break;
1381
1382         case SD_BUS_TYPE_BOOLEAN:
1383                 align = sz = 4;
1384
1385                 assert_cc(sizeof(int) == sizeof(uint32_t));
1386                 memcpy(&k, p, 4);
1387                 k = !!k;
1388                 p = &k;
1389                 break;
1390
1391         case SD_BUS_TYPE_UNIX_FD: {
1392                 int z, *f;
1393
1394                 if (!m->allow_fds) {
1395                         r = -ENOTSUP;
1396                         goto fail;
1397                 }
1398
1399                 align = sz = 4;
1400
1401                 z = *(int*) p;
1402                 if (z < 0) {
1403                         r = -EINVAL;
1404                         goto fail;
1405                 }
1406
1407                 fd = fcntl(z, F_DUPFD_CLOEXEC, 3);
1408                 if (fd < 0) {
1409                         r = -errno;
1410                         goto fail;
1411                 }
1412
1413                 f = realloc(m->fds, sizeof(int) * (m->n_fds + 1));
1414                 if (!f) {
1415                         m->poisoned = true;
1416                         r = -ENOMEM;
1417                         goto fail;
1418                 }
1419
1420                 fdi = m->n_fds;
1421                 f[fdi] = fd;
1422                 m->fds = f;
1423                 m->free_fds = true;
1424                 break;
1425         }
1426
1427         default:
1428                 align = bus_type_get_alignment(type);
1429                 sz = bus_type_get_size(type);
1430                 break;
1431         }
1432
1433         assert(align > 0);
1434         assert(sz > 0);
1435
1436         a = message_extend_body(m, align, sz);
1437         if (!a) {
1438                 r = -ENOMEM;
1439                 goto fail;
1440         }
1441
1442         if (type == SD_BUS_TYPE_STRING || type == SD_BUS_TYPE_OBJECT_PATH) {
1443                 *(uint32_t*) a = sz - 5;
1444                 memcpy((uint8_t*) a + 4, p, sz - 4);
1445
1446                 if (stored)
1447                         *stored = (const uint8_t*) a + 4;
1448
1449         } else if (type == SD_BUS_TYPE_SIGNATURE) {
1450                 *(uint8_t*) a = sz - 1;
1451                 memcpy((uint8_t*) a + 1, p, sz - 1);
1452
1453                 if (stored)
1454                         *stored = (const uint8_t*) a + 1;
1455         } else if (type == SD_BUS_TYPE_UNIX_FD) {
1456                 *(uint32_t*) a = fdi;
1457
1458                 if (stored)
1459                         *stored = a;
1460
1461                 m->n_fds ++;
1462
1463         } else {
1464                 memcpy(a, p, sz);
1465
1466                 if (stored)
1467                         *stored = a;
1468         }
1469
1470         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1471                 c->index++;
1472
1473         return 0;
1474
1475 fail:
1476         if (fd >= 0)
1477                 close_nointr_nofail(fd);
1478
1479         return r;
1480 }
1481
1482 _public_ int sd_bus_message_append_basic(sd_bus_message *m, char type, const void *p) {
1483         return message_append_basic(m, type, p, NULL);
1484 }
1485
1486 _public_ int sd_bus_message_append_string_space(sd_bus_message *m, size_t size, char **s) {
1487         struct bus_container *c;
1488         void *a;
1489
1490         assert_return(m, -EINVAL);
1491         assert_return(s, -EINVAL);
1492         assert_return(!m->sealed, -EPERM);
1493         assert_return(!m->poisoned, -ESTALE);
1494
1495         c = message_get_container(m);
1496
1497         if (c->signature && c->signature[c->index]) {
1498                 /* Container signature is already set */
1499
1500                 if (c->signature[c->index] != SD_BUS_TYPE_STRING)
1501                         return -ENXIO;
1502         } else {
1503                 char *e;
1504
1505                 /* Maybe we can append to the signature? But only if this is the top-level container*/
1506                 if (c->enclosing != 0)
1507                         return -ENXIO;
1508
1509                 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRING), NULL);
1510                 if (!e) {
1511                         m->poisoned = true;
1512                         return -ENOMEM;
1513                 }
1514         }
1515
1516         a = message_extend_body(m, 4, 4 + size + 1);
1517         if (!a)
1518                 return -ENOMEM;
1519
1520         *(uint32_t*) a = size;
1521         *s = (char*) a + 4;
1522
1523         (*s)[size] = 0;
1524
1525         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1526                 c->index++;
1527
1528         return 0;
1529 }
1530
1531 static int bus_message_open_array(
1532                 sd_bus_message *m,
1533                 struct bus_container *c,
1534                 const char *contents,
1535                 uint32_t **array_size) {
1536
1537         unsigned nindex;
1538         void *a, *op;
1539         int alignment;
1540         size_t os;
1541         struct bus_body_part *o;
1542
1543         assert(m);
1544         assert(c);
1545         assert(contents);
1546         assert(array_size);
1547
1548         if (!signature_is_single(contents, true))
1549                 return -EINVAL;
1550
1551         alignment = bus_type_get_alignment(contents[0]);
1552         if (alignment < 0)
1553                 return alignment;
1554
1555         if (c->signature && c->signature[c->index]) {
1556
1557                 /* Verify the existing signature */
1558
1559                 if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
1560                         return -ENXIO;
1561
1562                 if (!startswith(c->signature + c->index + 1, contents))
1563                         return -ENXIO;
1564
1565                 nindex = c->index + 1 + strlen(contents);
1566         } else {
1567                 char *e;
1568
1569                 if (c->enclosing != 0)
1570                         return -ENXIO;
1571
1572                 /* Extend the existing signature */
1573
1574                 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_ARRAY), contents, NULL);
1575                 if (!e) {
1576                         m->poisoned = true;
1577                         return -ENOMEM;
1578                 }
1579
1580                 nindex = e - c->signature;
1581         }
1582
1583         a = message_extend_body(m, 4, 4);
1584         if (!a)
1585                 return -ENOMEM;
1586
1587         o = m->body_end;
1588         op = m->body_end->data;
1589         os = m->body_end->size;
1590
1591         /* Add alignment between size and first element */
1592         if (!message_extend_body(m, alignment, 0))
1593                 return -ENOMEM;
1594
1595         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1596                 c->index = nindex;
1597
1598         /* location of array size might have changed so let's readjust a */
1599         if (o == m->body_end)
1600                 a = adjust_pointer(a, op, os, m->body_end->data);
1601
1602         *(uint32_t*) a = 0;
1603         *array_size = a;
1604         return 0;
1605 }
1606
1607 static int bus_message_open_variant(
1608                 sd_bus_message *m,
1609                 struct bus_container *c,
1610                 const char *contents) {
1611
1612         size_t l;
1613         void *a;
1614
1615         assert(m);
1616         assert(c);
1617         assert(contents);
1618
1619         if (!signature_is_single(contents, false))
1620                 return -EINVAL;
1621
1622         if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
1623                 return -EINVAL;
1624
1625         if (c->signature && c->signature[c->index]) {
1626
1627                 if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
1628                         return -ENXIO;
1629
1630         } else {
1631                 char *e;
1632
1633                 if (c->enclosing != 0)
1634                         return -ENXIO;
1635
1636                 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_VARIANT), NULL);
1637                 if (!e) {
1638                         m->poisoned = true;
1639                         return -ENOMEM;
1640                 }
1641         }
1642
1643         l = strlen(contents);
1644         a = message_extend_body(m, 1, 1 + l + 1);
1645         if (!a)
1646                 return -ENOMEM;
1647
1648         *(uint8_t*) a = l;
1649         memcpy((uint8_t*) a + 1, contents, l + 1);
1650
1651         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1652                 c->index++;
1653
1654         return 0;
1655 }
1656
1657 static int bus_message_open_struct(
1658                 sd_bus_message *m,
1659                 struct bus_container *c,
1660                 const char *contents) {
1661
1662         size_t nindex;
1663
1664         assert(m);
1665         assert(c);
1666         assert(contents);
1667
1668         if (!signature_is_valid(contents, false))
1669                 return -EINVAL;
1670
1671         if (c->signature && c->signature[c->index]) {
1672                 size_t l;
1673
1674                 l = strlen(contents);
1675
1676                 if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
1677                     !startswith(c->signature + c->index + 1, contents) ||
1678                     c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
1679                         return -ENXIO;
1680
1681                 nindex = c->index + 1 + l + 1;
1682         } else {
1683                 char *e;
1684
1685                 if (c->enclosing != 0)
1686                         return -ENXIO;
1687
1688                 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_BEGIN), contents, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_END), NULL);
1689                 if (!e) {
1690                         m->poisoned = true;
1691                         return -ENOMEM;
1692                 }
1693
1694                 nindex = e - c->signature;
1695         }
1696
1697         /* Align contents to 8 byte boundary */
1698         if (!message_extend_body(m, 8, 0))
1699                 return -ENOMEM;
1700
1701         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1702                 c->index = nindex;
1703
1704         return 0;
1705 }
1706
1707 static int bus_message_open_dict_entry(
1708                 sd_bus_message *m,
1709                 struct bus_container *c,
1710                 const char *contents) {
1711
1712         size_t nindex;
1713
1714         assert(m);
1715         assert(c);
1716         assert(contents);
1717
1718         if (!signature_is_pair(contents))
1719                 return -EINVAL;
1720
1721         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1722                 return -ENXIO;
1723
1724         if (c->signature && c->signature[c->index]) {
1725                 size_t l;
1726
1727                 l = strlen(contents);
1728
1729                 if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
1730                     !startswith(c->signature + c->index + 1, contents) ||
1731                     c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
1732                         return -ENXIO;
1733
1734                 nindex = c->index + 1 + l + 1;
1735         } else
1736                 return -ENXIO;
1737
1738         /* Align contents to 8 byte boundary */
1739         if (!message_extend_body(m, 8, 0))
1740                 return -ENOMEM;
1741
1742         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1743                 c->index = nindex;
1744
1745         return 0;
1746 }
1747
1748 _public_ int sd_bus_message_open_container(
1749                 sd_bus_message *m,
1750                 char type,
1751                 const char *contents) {
1752
1753         struct bus_container *c, *w;
1754         uint32_t *array_size = NULL;
1755         char *signature;
1756         size_t before;
1757         int r;
1758
1759         assert_return(m, -EINVAL);
1760         assert_return(!m->sealed, -EPERM);
1761         assert_return(contents, -EINVAL);
1762         assert_return(!m->poisoned, -ESTALE);
1763
1764         /* Make sure we have space for one more container */
1765         w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
1766         if (!w) {
1767                 m->poisoned = true;
1768                 return -ENOMEM;
1769         }
1770
1771         m->containers = w;
1772
1773         c = message_get_container(m);
1774
1775         signature = strdup(contents);
1776         if (!signature) {
1777                 m->poisoned = true;
1778                 return -ENOMEM;
1779         }
1780
1781         /* Save old index in the parent container, in case we have to
1782          * abort this container */
1783         c->saved_index = c->index;
1784         before = m->header->body_size;
1785
1786         if (type == SD_BUS_TYPE_ARRAY)
1787                 r = bus_message_open_array(m, c, contents, &array_size);
1788         else if (type == SD_BUS_TYPE_VARIANT)
1789                 r = bus_message_open_variant(m, c, contents);
1790         else if (type == SD_BUS_TYPE_STRUCT)
1791                 r = bus_message_open_struct(m, c, contents);
1792         else if (type == SD_BUS_TYPE_DICT_ENTRY)
1793                 r = bus_message_open_dict_entry(m, c, contents);
1794         else
1795                 r = -EINVAL;
1796
1797         if (r < 0) {
1798                 free(signature);
1799                 return r;
1800         }
1801
1802         /* OK, let's fill it in */
1803         w += m->n_containers++;
1804         w->enclosing = type;
1805         w->signature = signature;
1806         w->index = 0;
1807         w->array_size = array_size;
1808         w->before = before;
1809         w->begin = m->rindex;
1810
1811         return 0;
1812 }
1813
1814 _public_ int sd_bus_message_close_container(sd_bus_message *m) {
1815         struct bus_container *c;
1816
1817         assert_return(m, -EINVAL);
1818         assert_return(!m->sealed, -EPERM);
1819         assert_return(m->n_containers > 0, -EINVAL);
1820         assert_return(!m->poisoned, -ESTALE);
1821
1822         c = message_get_container(m);
1823         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1824                 if (c->signature && c->signature[c->index] != 0)
1825                         return -EINVAL;
1826
1827         free(c->signature);
1828         m->n_containers--;
1829
1830         return 0;
1831 }
1832
1833 typedef struct {
1834         const char *types;
1835         unsigned n_struct;
1836         unsigned n_array;
1837 } TypeStack;
1838
1839 static int type_stack_push(TypeStack *stack, unsigned max, unsigned *i, const char *types, unsigned n_struct, unsigned n_array) {
1840         assert(stack);
1841         assert(max > 0);
1842
1843         if (*i >= max)
1844                 return -EINVAL;
1845
1846         stack[*i].types = types;
1847         stack[*i].n_struct = n_struct;
1848         stack[*i].n_array = n_array;
1849         (*i)++;
1850
1851         return 0;
1852 }
1853
1854 static int type_stack_pop(TypeStack *stack, unsigned max, unsigned *i, const char **types, unsigned *n_struct, unsigned *n_array) {
1855         assert(stack);
1856         assert(max > 0);
1857         assert(types);
1858         assert(n_struct);
1859         assert(n_array);
1860
1861         if (*i <= 0)
1862                 return 0;
1863
1864         (*i)--;
1865         *types = stack[*i].types;
1866         *n_struct = stack[*i].n_struct;
1867         *n_array = stack[*i].n_array;
1868
1869         return 1;
1870 }
1871
1872 int bus_message_append_ap(
1873                 sd_bus_message *m,
1874                 const char *types,
1875                 va_list ap) {
1876
1877         unsigned n_array, n_struct;
1878         TypeStack stack[BUS_CONTAINER_DEPTH];
1879         unsigned stack_ptr = 0;
1880         int r;
1881
1882         assert(m);
1883
1884         if (!types)
1885                 return 0;
1886
1887         n_array = (unsigned) -1;
1888         n_struct = strlen(types);
1889
1890         for (;;) {
1891                 const char *t;
1892
1893                 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
1894                         r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
1895                         if (r < 0)
1896                                 return r;
1897                         if (r == 0)
1898                                 break;
1899
1900                         r = sd_bus_message_close_container(m);
1901                         if (r < 0)
1902                                 return r;
1903
1904                         continue;
1905                 }
1906
1907                 t = types;
1908                 if (n_array != (unsigned) -1)
1909                         n_array --;
1910                 else {
1911                         types ++;
1912                         n_struct--;
1913                 }
1914
1915                 switch (*t) {
1916
1917                 case SD_BUS_TYPE_BYTE: {
1918                         uint8_t x;
1919
1920                         x = (uint8_t) va_arg(ap, int);
1921                         r = sd_bus_message_append_basic(m, *t, &x);
1922                         break;
1923                 }
1924
1925                 case SD_BUS_TYPE_BOOLEAN:
1926                 case SD_BUS_TYPE_INT32:
1927                 case SD_BUS_TYPE_UINT32:
1928                 case SD_BUS_TYPE_UNIX_FD: {
1929                         uint32_t x;
1930
1931                         /* We assume a boolean is the same as int32_t */
1932                         assert_cc(sizeof(int32_t) == sizeof(int));
1933
1934                         x = va_arg(ap, uint32_t);
1935                         r = sd_bus_message_append_basic(m, *t, &x);
1936                         break;
1937                 }
1938
1939                 case SD_BUS_TYPE_INT16:
1940                 case SD_BUS_TYPE_UINT16: {
1941                         uint16_t x;
1942
1943                         x = (uint16_t) va_arg(ap, int);
1944                         r = sd_bus_message_append_basic(m, *t, &x);
1945                         break;
1946                 }
1947
1948                 case SD_BUS_TYPE_INT64:
1949                 case SD_BUS_TYPE_UINT64:
1950                 case SD_BUS_TYPE_DOUBLE: {
1951                         uint64_t x;
1952
1953                         x = va_arg(ap, uint64_t);
1954                         r = sd_bus_message_append_basic(m, *t, &x);
1955                         break;
1956                 }
1957
1958                 case SD_BUS_TYPE_STRING:
1959                 case SD_BUS_TYPE_OBJECT_PATH:
1960                 case SD_BUS_TYPE_SIGNATURE: {
1961                         const char *x;
1962
1963                         x = va_arg(ap, const char*);
1964                         r = sd_bus_message_append_basic(m, *t, x);
1965                         break;
1966                 }
1967
1968                 case SD_BUS_TYPE_ARRAY: {
1969                         size_t k;
1970
1971                         r = signature_element_length(t + 1, &k);
1972                         if (r < 0)
1973                                 return r;
1974
1975                         {
1976                                 char s[k + 1];
1977                                 memcpy(s, t + 1, k);
1978                                 s[k] = 0;
1979
1980                                 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, s);
1981                                 if (r < 0)
1982                                         return r;
1983                         }
1984
1985                         if (n_array == (unsigned) -1) {
1986                                 types += k;
1987                                 n_struct -= k;
1988                         }
1989
1990                         r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
1991                         if (r < 0)
1992                                 return r;
1993
1994                         types = t + 1;
1995                         n_struct = k;
1996                         n_array = va_arg(ap, unsigned);
1997
1998                         break;
1999                 }
2000
2001                 case SD_BUS_TYPE_VARIANT: {
2002                         const char *s;
2003
2004                         s = va_arg(ap, const char*);
2005                         if (!s)
2006                                 return -EINVAL;
2007
2008                         r = sd_bus_message_open_container(m, SD_BUS_TYPE_VARIANT, s);
2009                         if (r < 0)
2010                                 return r;
2011
2012                         r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2013                         if (r < 0)
2014                                 return r;
2015
2016                         types = s;
2017                         n_struct = strlen(s);
2018                         n_array = (unsigned) -1;
2019
2020                         break;
2021                 }
2022
2023                 case SD_BUS_TYPE_STRUCT_BEGIN:
2024                 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
2025                         size_t k;
2026
2027                         r = signature_element_length(t, &k);
2028                         if (r < 0)
2029                                 return r;
2030
2031                         {
2032                                 char s[k - 1];
2033
2034                                 memcpy(s, t + 1, k - 2);
2035                                 s[k - 2] = 0;
2036
2037                                 r = sd_bus_message_open_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
2038                                 if (r < 0)
2039                                         return r;
2040                         }
2041
2042                         if (n_array == (unsigned) -1) {
2043                                 types += k - 1;
2044                                 n_struct -= k - 1;
2045                         }
2046
2047                         r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2048                         if (r < 0)
2049                                 return r;
2050
2051                         types = t + 1;
2052                         n_struct = k - 2;
2053                         n_array = (unsigned) -1;
2054
2055                         break;
2056                 }
2057
2058                 default:
2059                         r = -EINVAL;
2060                 }
2061
2062                 if (r < 0)
2063                         return r;
2064         }
2065
2066         return 0;
2067 }
2068
2069 _public_ int sd_bus_message_append(sd_bus_message *m, const char *types, ...) {
2070         va_list ap;
2071         int r;
2072
2073         assert_return(m, -EINVAL);
2074         assert_return(types, -EINVAL);
2075         assert_return(!m->sealed, -EPERM);
2076         assert_return(!m->poisoned, -ESTALE);
2077
2078         va_start(ap, types);
2079         r = bus_message_append_ap(m, types, ap);
2080         va_end(ap);
2081
2082         return r;
2083 }
2084
2085 _public_ int sd_bus_message_append_array_space(sd_bus_message *m,
2086                                                char type,
2087                                                size_t size,
2088                                                void **ptr) {
2089         ssize_t align, sz;
2090         void *a;
2091         int r;
2092
2093         assert_return(m, -EINVAL);
2094         assert_return(!m->sealed, -EPERM);
2095         assert_return(bus_type_is_trivial(type), -EINVAL);
2096         assert_return(ptr || size == 0, -EINVAL);
2097         assert_return(!m->poisoned, -ESTALE);
2098
2099         align = bus_type_get_alignment(type);
2100         sz = bus_type_get_size(type);
2101
2102         assert_se(align > 0);
2103         assert_se(sz > 0);
2104
2105         if (size % sz != 0)
2106                 return -EINVAL;
2107
2108         r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
2109         if (r < 0)
2110                 return r;
2111
2112         a = message_extend_body(m, align, size);
2113         if (!a)
2114                 return -ENOMEM;
2115
2116         r = sd_bus_message_close_container(m);
2117         if (r < 0)
2118                 return r;
2119
2120         *ptr = a;
2121         return 0;
2122 }
2123
2124 _public_ int sd_bus_message_append_array(sd_bus_message *m,
2125                                          char type,
2126                                          const void *ptr,
2127                                          size_t size) {
2128         int r;
2129         void *p;
2130
2131         assert_return(m, -EINVAL);
2132         assert_return(!m->sealed, -EPERM);
2133         assert_return(bus_type_is_trivial(type), -EINVAL);
2134         assert_return(ptr || size == 0, -EINVAL);
2135         assert_return(!m->poisoned, -ESTALE);
2136
2137         r = sd_bus_message_append_array_space(m, type, size, &p);
2138         if (r < 0)
2139                 return r;
2140
2141         if (size > 0)
2142                 memcpy(p, ptr, size);
2143
2144         return 0;
2145 }
2146
2147 _public_ int sd_bus_message_append_array_memfd(sd_bus_message *m,
2148                                                char type,
2149                                                sd_memfd *memfd) {
2150         _cleanup_close_ int copy_fd = -1;
2151         struct bus_body_part *part;
2152         ssize_t align, sz;
2153         uint64_t size;
2154         void *a;
2155         int r;
2156
2157         if (!m)
2158                 return -EINVAL;
2159         if (!memfd)
2160                 return -EINVAL;
2161         if (m->sealed)
2162                 return -EPERM;
2163         if (!bus_type_is_trivial(type))
2164                 return -EINVAL;
2165         if (m->poisoned)
2166                 return -ESTALE;
2167
2168         r = sd_memfd_set_sealed(memfd, true);
2169         if (r < 0)
2170                 return r;
2171
2172         copy_fd = sd_memfd_dup_fd(memfd);
2173         if (copy_fd < 0)
2174                 return copy_fd;
2175
2176         r = sd_memfd_get_size(memfd, &size);
2177         if (r < 0)
2178                 return r;
2179
2180         align = bus_type_get_alignment(type);
2181         sz = bus_type_get_size(type);
2182
2183         assert_se(align > 0);
2184         assert_se(sz > 0);
2185
2186         if (size % sz != 0)
2187                 return -EINVAL;
2188
2189         if (size > (uint64_t) (uint32_t) -1)
2190                 return -EINVAL;
2191
2192         r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
2193         if (r < 0)
2194                 return r;
2195
2196         a = message_extend_body(m, align, 0);
2197         if (!a)
2198                 return -ENOMEM;
2199
2200         part = message_append_part(m);
2201         if (!part)
2202                 return -ENOMEM;
2203
2204         part->memfd = copy_fd;
2205         part->sealed = true;
2206         part->size = size;
2207         copy_fd = -1;
2208
2209         message_extend_containers(m, size);
2210         m->header->body_size += size;
2211
2212         return sd_bus_message_close_container(m);
2213 }
2214
2215 _public_ int sd_bus_message_append_string_memfd(sd_bus_message *m, sd_memfd *memfd) {
2216         _cleanup_close_ int copy_fd = -1;
2217         struct bus_body_part *part;
2218         struct bus_container *c;
2219         uint64_t size;
2220         void *a;
2221         int r;
2222
2223         assert_return(m, -EINVAL);
2224         assert_return(memfd, -EINVAL);
2225         assert_return(!m->sealed, -EPERM);
2226         assert_return(!m->poisoned, -ESTALE);
2227
2228         r = sd_memfd_set_sealed(memfd, true);
2229         if (r < 0)
2230                 return r;
2231
2232         copy_fd = sd_memfd_dup_fd(memfd);
2233         if (copy_fd < 0)
2234                 return copy_fd;
2235
2236         r = sd_memfd_get_size(memfd, &size);
2237         if (r < 0)
2238                 return r;
2239
2240         /* We require this to be NUL terminated */
2241         if (size == 0)
2242                 return -EINVAL;
2243
2244         if (size > (uint64_t) (uint32_t) -1)
2245                 return -EINVAL;
2246
2247         c = message_get_container(m);
2248         if (c->signature && c->signature[c->index]) {
2249                 /* Container signature is already set */
2250
2251                 if (c->signature[c->index] != SD_BUS_TYPE_STRING)
2252                         return -ENXIO;
2253         } else {
2254                 char *e;
2255
2256                 /* Maybe we can append to the signature? But only if this is the top-level container*/
2257                 if (c->enclosing != 0)
2258                         return -ENXIO;
2259
2260                 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRING), NULL);
2261                 if (!e) {
2262                         m->poisoned = true;
2263                         return -ENOMEM;
2264                 }
2265         }
2266
2267         a = message_extend_body(m, 4, 4);
2268         if (!a)
2269                 return -ENOMEM;
2270
2271         *(uint32_t*) a = size - 1;
2272
2273         part = message_append_part(m);
2274         if (!part)
2275                 return -ENOMEM;
2276
2277         part->memfd = copy_fd;
2278         part->sealed = true;
2279         part->size = size;
2280         copy_fd = -1;
2281
2282         message_extend_containers(m, size);
2283         m->header->body_size += size;
2284
2285         if (c->enclosing != SD_BUS_TYPE_ARRAY)
2286                 c->index++;
2287
2288         return 0;
2289 }
2290
2291 _public_ int sd_bus_message_append_strv(sd_bus_message *m, char **l) {
2292         char **i;
2293         int r;
2294
2295         assert_return(m, -EINVAL);
2296         assert_return(!m->sealed, -EPERM);
2297         assert_return(!m->poisoned, -ESTALE);
2298
2299         r = sd_bus_message_open_container(m, 'a', "s");
2300         if (r < 0)
2301                 return r;
2302
2303         STRV_FOREACH(i, l) {
2304                 r = sd_bus_message_append_basic(m, 's', *i);
2305                 if (r < 0)
2306                         return r;
2307         }
2308
2309         return sd_bus_message_close_container(m);
2310 }
2311
2312 int bus_body_part_map(struct bus_body_part *part) {
2313         void *p;
2314         size_t psz;
2315
2316         assert_se(part);
2317
2318         if (part->data)
2319                 return 0;
2320
2321         if (part->size <= 0)
2322                 return 0;
2323
2324         /* For smaller zero parts (as used for padding) we don't need to map anything... */
2325         if (part->memfd < 0 && part->is_zero && part->size < 8) {
2326                 static const uint8_t zeroes[7] = { };
2327                 part->data = (void*) zeroes;
2328                 return 0;
2329         }
2330
2331         psz = PAGE_ALIGN(part->size);
2332
2333         if (part->memfd >= 0)
2334                 p = mmap(NULL, psz, PROT_READ, MAP_SHARED, part->memfd, 0);
2335         else if (part->is_zero)
2336                 p = mmap(NULL, psz, PROT_READ, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
2337         else
2338                 return -EINVAL;
2339
2340         if (p == MAP_FAILED)
2341                 return -errno;
2342
2343         part->mapped = psz;
2344         part->data = p;
2345         part->munmap_this = true;
2346
2347         return 0;
2348 }
2349
2350 void bus_body_part_unmap(struct bus_body_part *part) {
2351
2352         assert_se(part);
2353
2354         if (part->memfd < 0)
2355                 return;
2356
2357         if (!part->data)
2358                 return;
2359
2360         if (!part->munmap_this)
2361                 return;
2362
2363         assert_se(munmap(part->data, part->mapped) == 0);
2364
2365         part->data = NULL;
2366         part->mapped = 0;
2367         part->munmap_this = false;
2368
2369         return;
2370 }
2371
2372 static int buffer_peek(const void *p, uint32_t sz, size_t *rindex, size_t align, size_t nbytes, void **r) {
2373         size_t k, start, end;
2374
2375         assert(rindex);
2376         assert(align > 0);
2377
2378         start = ALIGN_TO((size_t) *rindex, align);
2379         end = start + nbytes;
2380
2381         if (end > sz)
2382                 return -EBADMSG;
2383
2384         /* Verify that padding is 0 */
2385         for (k = *rindex; k < start; k++)
2386                 if (((const uint8_t*) p)[k] != 0)
2387                         return -EBADMSG;
2388
2389         if (r)
2390                 *r = (uint8_t*) p + start;
2391
2392         *rindex = end;
2393
2394         return 1;
2395 }
2396
2397 static bool message_end_of_signature(sd_bus_message *m) {
2398         struct bus_container *c;
2399
2400         assert(m);
2401
2402         c = message_get_container(m);
2403         return !c->signature || c->signature[c->index] == 0;
2404 }
2405
2406 static bool message_end_of_array(sd_bus_message *m, size_t index) {
2407         struct bus_container *c;
2408
2409         assert(m);
2410
2411         c = message_get_container(m);
2412         if (!c->array_size)
2413                 return false;
2414
2415         return index >= c->begin + BUS_MESSAGE_BSWAP32(m, *c->array_size);
2416 }
2417
2418 int sd_bus_message_at_end(sd_bus_message *m, int complete) {
2419         assert_return(m, -EINVAL);
2420         assert_return(m->sealed, -EPERM);
2421
2422         if (complete && m->n_containers > 0)
2423                 return false;
2424
2425         if (message_end_of_signature(m))
2426                 return true;
2427
2428         if (message_end_of_array(m, m->rindex))
2429                 return true;
2430
2431         return false;
2432 }
2433
2434 static struct bus_body_part* find_part(sd_bus_message *m, size_t index, size_t sz, void **p) {
2435         struct bus_body_part *part;
2436         size_t begin;
2437         int r;
2438
2439         assert(m);
2440
2441         if (m->cached_rindex_part && index >= m->cached_rindex_part_begin) {
2442                 part = m->cached_rindex_part;
2443                 begin = m->cached_rindex_part_begin;
2444         } else {
2445                 part = &m->body;
2446                 begin = 0;
2447         }
2448
2449         while (part) {
2450                 if (index < begin)
2451                         return NULL;
2452
2453                 if (index + sz <= begin + part->size) {
2454
2455                         r = bus_body_part_map(part);
2456                         if (r < 0)
2457                                 return NULL;
2458
2459                         if (p)
2460                                 *p = (uint8_t*) part->data + index - begin;
2461
2462                         m->cached_rindex_part = part;
2463                         m->cached_rindex_part_begin = begin;
2464
2465                         return part;
2466                 }
2467
2468                 begin += part->size;
2469                 part = part->next;
2470         }
2471
2472         return NULL;
2473 }
2474
2475 static int message_peek_body(
2476                 sd_bus_message *m,
2477                 size_t *rindex,
2478                 size_t align,
2479                 size_t nbytes,
2480                 void **ret) {
2481
2482         size_t k, start, end, padding;
2483         struct bus_body_part *part;
2484         uint8_t *q;
2485
2486         assert(m);
2487         assert(rindex);
2488         assert(align > 0);
2489
2490         if (message_end_of_array(m, *rindex))
2491                 return 0;
2492
2493         start = ALIGN_TO((size_t) *rindex, align);
2494         padding = start - *rindex;
2495         end = start + nbytes;
2496
2497         if (end > BUS_MESSAGE_BODY_SIZE(m))
2498                 return -EBADMSG;
2499
2500         part = find_part(m, *rindex, padding, (void**) &q);
2501         if (!part)
2502                 return -EBADMSG;
2503
2504         if (q) {
2505                 /* Verify padding */
2506                 for (k = 0; k < padding; k++)
2507                         if (q[k] != 0)
2508                                 return -EBADMSG;
2509         }
2510
2511         part = find_part(m, start, nbytes, (void**) &q);
2512         if (!part || !q)
2513                 return -EBADMSG;
2514
2515         *rindex = end;
2516
2517         if (ret)
2518                 *ret = q;
2519
2520         return 1;
2521 }
2522
2523 static bool validate_nul(const char *s, size_t l) {
2524
2525         /* Check for NUL chars in the string */
2526         if (memchr(s, 0, l))
2527                 return false;
2528
2529         /* Check for NUL termination */
2530         if (s[l] != 0)
2531                 return false;
2532
2533         return true;
2534 }
2535
2536 static bool validate_string(const char *s, size_t l) {
2537
2538         if (!validate_nul(s, l))
2539                 return false;
2540
2541         /* Check if valid UTF8 */
2542         if (!utf8_is_valid(s))
2543                 return false;
2544
2545         return true;
2546 }
2547
2548 static bool validate_signature(const char *s, size_t l) {
2549
2550         if (!validate_nul(s, l))
2551                 return false;
2552
2553         /* Check if valid signature */
2554         if (!signature_is_valid(s, true))
2555                 return false;
2556
2557         return true;
2558 }
2559
2560 static bool validate_object_path(const char *s, size_t l) {
2561
2562         if (!validate_nul(s, l))
2563                 return false;
2564
2565         if (!object_path_is_valid(s))
2566                 return false;
2567
2568         return true;
2569 }
2570
2571 _public_ int sd_bus_message_read_basic(sd_bus_message *m, char type, void *p) {
2572         struct bus_container *c;
2573         void *q;
2574         int r;
2575
2576         assert_return(m, -EINVAL);
2577         assert_return(m->sealed, -EPERM);
2578         assert_return(bus_type_is_basic(type), -EINVAL);
2579
2580         if (message_end_of_signature(m))
2581                 return -ENXIO;
2582
2583         if (message_end_of_array(m, m->rindex))
2584                 return 0;
2585
2586         c = message_get_container(m);
2587         if (c->signature[c->index] != type)
2588                 return -ENXIO;
2589
2590         switch (type) {
2591
2592         case SD_BUS_TYPE_STRING:
2593         case SD_BUS_TYPE_OBJECT_PATH: {
2594                 uint32_t l;
2595                 size_t rindex;
2596
2597                 rindex = m->rindex;
2598                 r = message_peek_body(m, &rindex, 4, 4, &q);
2599                 if (r <= 0)
2600                         return r;
2601
2602                 l = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2603                 r = message_peek_body(m, &rindex, 1, l+1, &q);
2604                 if (r < 0)
2605                         return r;
2606                 if (r == 0)
2607                         return -EBADMSG;
2608
2609                 if (type == SD_BUS_TYPE_OBJECT_PATH) {
2610                         if (!validate_object_path(q, l))
2611                                 return -EBADMSG;
2612                 } else {
2613                         if (!validate_string(q, l))
2614                                 return -EBADMSG;
2615                 }
2616
2617                 m->rindex = rindex;
2618                 if (p)
2619                         *(const char**) p = q;
2620
2621                 break;
2622         }
2623
2624         case SD_BUS_TYPE_SIGNATURE: {
2625                 uint8_t l;
2626                 size_t rindex;
2627
2628                 rindex = m->rindex;
2629                 r = message_peek_body(m, &rindex, 1, 1, &q);
2630                 if (r <= 0)
2631                         return r;
2632
2633                 l = *(uint8_t*) q;
2634                 r = message_peek_body(m, &rindex, 1, l+1, &q);
2635                 if (r < 0)
2636                         return r;
2637                 if (r == 0)
2638                         return -EBADMSG;
2639
2640                 if (!validate_signature(q, l))
2641                         return -EBADMSG;
2642
2643                 m->rindex = rindex;
2644
2645                 if (p)
2646                         *(const char**) p = q;
2647                 break;
2648         }
2649
2650         default: {
2651                 ssize_t sz, align;
2652                 size_t rindex;
2653
2654                 align = bus_type_get_alignment(type);
2655                 sz = bus_type_get_size(type);
2656                 assert(align > 0 && sz > 0);
2657
2658                 rindex = m->rindex;
2659                 r = message_peek_body(m, &rindex, align, sz, &q);
2660                 if (r <= 0)
2661                         return r;
2662
2663                 switch (type) {
2664
2665                 case SD_BUS_TYPE_BYTE:
2666                         if (p)
2667                                 *(uint8_t*) p = *(uint8_t*) q;
2668                         break;
2669
2670                 case SD_BUS_TYPE_BOOLEAN:
2671                         if (p)
2672                                 *(unsigned*) p = !!*(uint32_t*) q;
2673                         break;
2674
2675                 case SD_BUS_TYPE_INT16:
2676                 case SD_BUS_TYPE_UINT16:
2677                         if (p)
2678                                 *(uint16_t*) p = BUS_MESSAGE_BSWAP16(m, *(uint16_t*) q);
2679                         break;
2680
2681                 case SD_BUS_TYPE_INT32:
2682                 case SD_BUS_TYPE_UINT32:
2683                         if (p)
2684                                 *(uint32_t*) p = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2685                         break;
2686
2687                 case SD_BUS_TYPE_INT64:
2688                 case SD_BUS_TYPE_UINT64:
2689                 case SD_BUS_TYPE_DOUBLE:
2690                         if (p)
2691                                 *(uint64_t*) p = BUS_MESSAGE_BSWAP64(m, *(uint64_t*) q);
2692                         break;
2693
2694                 case SD_BUS_TYPE_UNIX_FD: {
2695                         uint32_t j;
2696
2697                         j = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2698                         if (j >= m->n_fds)
2699                                 return -EBADMSG;
2700
2701                         if (p)
2702                                 *(int*) p = m->fds[j];
2703                         break;
2704                 }
2705
2706                 default:
2707                         assert_not_reached("Unknown basic type...");
2708                 }
2709
2710                 m->rindex = rindex;
2711
2712                 break;
2713         }
2714         }
2715
2716         if (c->enclosing != SD_BUS_TYPE_ARRAY)
2717                 c->index++;
2718
2719         return 1;
2720 }
2721
2722 static int bus_message_enter_array(
2723                 sd_bus_message *m,
2724                 struct bus_container *c,
2725                 const char *contents,
2726                 uint32_t **array_size) {
2727
2728         size_t rindex;
2729         void *q;
2730         int r, alignment;
2731
2732         assert(m);
2733         assert(c);
2734         assert(contents);
2735         assert(array_size);
2736
2737         if (!signature_is_single(contents, true))
2738                 return -EINVAL;
2739
2740         alignment = bus_type_get_alignment(contents[0]);
2741         if (alignment < 0)
2742                 return alignment;
2743
2744         if (!c->signature || c->signature[c->index] == 0)
2745                 return 0;
2746
2747         if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
2748                 return -ENXIO;
2749
2750         if (!startswith(c->signature + c->index + 1, contents))
2751                 return -ENXIO;
2752
2753         rindex = m->rindex;
2754         r = message_peek_body(m, &rindex, 4, 4, &q);
2755         if (r <= 0)
2756                 return r;
2757
2758         if (BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q) > BUS_ARRAY_MAX_SIZE)
2759                 return -EBADMSG;
2760
2761         r = message_peek_body(m, &rindex, alignment, 0, NULL);
2762         if (r < 0)
2763                 return r;
2764         if (r == 0)
2765                 return -EBADMSG;
2766
2767         if (c->enclosing != SD_BUS_TYPE_ARRAY)
2768                 c->index += 1 + strlen(contents);
2769
2770         m->rindex = rindex;
2771
2772         *array_size = (uint32_t*) q;
2773
2774         return 1;
2775 }
2776
2777 static int bus_message_enter_variant(
2778                 sd_bus_message *m,
2779                 struct bus_container *c,
2780                 const char *contents) {
2781
2782         size_t rindex;
2783         uint8_t l;
2784         void *q;
2785         int r;
2786
2787         assert(m);
2788         assert(c);
2789         assert(contents);
2790
2791         if (!signature_is_single(contents, false))
2792                 return -EINVAL;
2793
2794         if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
2795                 return -EINVAL;
2796
2797         if (!c->signature || c->signature[c->index] == 0)
2798                 return 0;
2799
2800         if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
2801                 return -ENXIO;
2802
2803         rindex = m->rindex;
2804         r = message_peek_body(m, &rindex, 1, 1, &q);
2805         if (r <= 0)
2806                 return r;
2807
2808         l = *(uint8_t*) q;
2809         r = message_peek_body(m, &rindex, 1, l+1, &q);
2810         if (r < 0)
2811                 return r;
2812         if (r == 0)
2813                 return -EBADMSG;
2814
2815         if (!validate_signature(q, l))
2816                 return -EBADMSG;
2817
2818         if (!streq(q, contents))
2819                 return -ENXIO;
2820
2821         if (c->enclosing != SD_BUS_TYPE_ARRAY)
2822                 c->index++;
2823
2824         m->rindex = rindex;
2825
2826         return 1;
2827 }
2828
2829 static int bus_message_enter_struct(
2830                 sd_bus_message *m,
2831                 struct bus_container *c,
2832                 const char *contents) {
2833
2834         size_t l;
2835         int r;
2836
2837         assert(m);
2838         assert(c);
2839         assert(contents);
2840
2841         if (!signature_is_valid(contents, false))
2842                 return -EINVAL;
2843
2844         if (!c->signature || c->signature[c->index] == 0)
2845                 return 0;
2846
2847         l = strlen(contents);
2848
2849         if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
2850             !startswith(c->signature + c->index + 1, contents) ||
2851             c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
2852                 return -ENXIO;
2853
2854         r = message_peek_body(m, &m->rindex, 8, 0, NULL);
2855         if (r <= 0)
2856                 return r;
2857
2858         if (c->enclosing != SD_BUS_TYPE_ARRAY)
2859                 c->index += 1 + l + 1;
2860
2861         return 1;
2862 }
2863
2864 static int bus_message_enter_dict_entry(
2865                 sd_bus_message *m,
2866                 struct bus_container *c,
2867                 const char *contents) {
2868
2869         size_t l;
2870         int r;
2871
2872         assert(m);
2873         assert(c);
2874         assert(contents);
2875
2876         if (!signature_is_pair(contents))
2877                 return -EINVAL;
2878
2879         if (c->enclosing != SD_BUS_TYPE_ARRAY)
2880                 return -ENXIO;
2881
2882         if (!c->signature || c->signature[c->index] == 0)
2883                 return 0;
2884
2885         l = strlen(contents);
2886
2887         if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
2888             !startswith(c->signature + c->index + 1, contents) ||
2889             c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
2890                 return -ENXIO;
2891
2892         r = message_peek_body(m, &m->rindex, 8, 0, NULL);
2893         if (r <= 0)
2894                 return r;
2895
2896         if (c->enclosing != SD_BUS_TYPE_ARRAY)
2897                 c->index += 1 + l + 1;
2898
2899         return 1;
2900 }
2901
2902 _public_ int sd_bus_message_enter_container(sd_bus_message *m,
2903                                             char type,
2904                                             const char *contents) {
2905         struct bus_container *c, *w;
2906         uint32_t *array_size = NULL;
2907         char *signature;
2908         size_t before;
2909         int r;
2910
2911         assert_return(m, -EINVAL);
2912         assert_return(m->sealed, -EPERM);
2913         assert_return(type != 0 || !contents, -EINVAL);
2914
2915         if (type == 0 || !contents) {
2916                 const char *cc;
2917                 char tt;
2918
2919                 /* Allow entering into anonymous containers */
2920                 r = sd_bus_message_peek_type(m, &tt, &cc);
2921                 if (r <= 0)
2922                         return r;
2923
2924                 if (type != 0 && type != tt)
2925                         return -ENXIO;
2926
2927                 if (contents && !streq(contents, cc))
2928                         return -ENXIO;
2929
2930                 type = tt;
2931                 contents = cc;
2932         }
2933
2934         /*
2935          * We enforce a global limit on container depth, that is much
2936          * higher than the 32 structs and 32 arrays the specification
2937          * mandates. This is simpler to implement for us, and we need
2938          * this only to ensure our container array doesn't grow
2939          * without bounds. We are happy to return any data from a
2940          * message as long as the data itself is valid, even if the
2941          * overall message might be not.
2942          *
2943          * Note that the message signature is validated when
2944          * parsing the headers, and that validation does check the
2945          * 32/32 limit.
2946          *
2947          * Note that the specification defines no limits on the depth
2948          * of stacked variants, but we do.
2949          */
2950         if (m->n_containers >= BUS_CONTAINER_DEPTH)
2951                 return -EBADMSG;
2952
2953         w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
2954         if (!w)
2955                 return -ENOMEM;
2956         m->containers = w;
2957
2958         if (message_end_of_signature(m))
2959                 return -ENXIO;
2960
2961         if (message_end_of_array(m, m->rindex))
2962                 return 0;
2963
2964         c = message_get_container(m);
2965
2966         signature = strdup(contents);
2967         if (!signature)
2968                 return -ENOMEM;
2969
2970         c->saved_index = c->index;
2971         before = m->rindex;
2972
2973         if (type == SD_BUS_TYPE_ARRAY)
2974                 r = bus_message_enter_array(m, c, contents, &array_size);
2975         else if (type == SD_BUS_TYPE_VARIANT)
2976                 r = bus_message_enter_variant(m, c, contents);
2977         else if (type == SD_BUS_TYPE_STRUCT)
2978                 r = bus_message_enter_struct(m, c, contents);
2979         else if (type == SD_BUS_TYPE_DICT_ENTRY)
2980                 r = bus_message_enter_dict_entry(m, c, contents);
2981         else
2982                 r = -EINVAL;
2983
2984         if (r <= 0) {
2985                 free(signature);
2986                 return r;
2987         }
2988
2989         /* OK, let's fill it in */
2990         w += m->n_containers++;
2991         w->enclosing = type;
2992         w->signature = signature;
2993         w->index = 0;
2994         w->array_size = array_size;
2995         w->before = before;
2996         w->begin = m->rindex;
2997
2998         return 1;
2999 }
3000
3001 _public_ int sd_bus_message_exit_container(sd_bus_message *m) {
3002         struct bus_container *c;
3003
3004         assert_return(m, -EINVAL);
3005         assert_return(m->sealed, -EPERM);
3006         assert_return(m->n_containers > 0, -EINVAL);
3007
3008         c = message_get_container(m);
3009         if (c->enclosing == SD_BUS_TYPE_ARRAY) {
3010                 uint32_t l;
3011
3012                 l = BUS_MESSAGE_BSWAP32(m, *c->array_size);
3013                 if (c->begin + l != m->rindex)
3014                         return -EBUSY;
3015
3016         } else {
3017                 if (c->signature && c->signature[c->index] != 0)
3018                         return -EINVAL;
3019         }
3020
3021         free(c->signature);
3022         m->n_containers--;
3023
3024         return 1;
3025 }
3026
3027 static void message_quit_container(sd_bus_message *m) {
3028         struct bus_container *c;
3029
3030         assert(m);
3031         assert(m->sealed);
3032         assert(m->n_containers > 0);
3033
3034         c = message_get_container(m);
3035
3036         /* Undo seeks */
3037         assert(m->rindex >= c->before);
3038         m->rindex = c->before;
3039
3040         /* Free container */
3041         free(c->signature);
3042         m->n_containers--;
3043
3044         /* Correct index of new top-level container */
3045         c = message_get_container(m);
3046         c->index = c->saved_index;
3047 }
3048
3049 _public_ int sd_bus_message_peek_type(sd_bus_message *m, char *type, const char **contents) {
3050         struct bus_container *c;
3051         int r;
3052
3053         assert_return(m, -EINVAL);
3054         assert_return(m->sealed, -EPERM);
3055
3056         if (message_end_of_signature(m))
3057                 goto eof;
3058
3059         if (message_end_of_array(m, m->rindex))
3060                 goto eof;
3061
3062         c = message_get_container(m);
3063
3064         if (bus_type_is_basic(c->signature[c->index])) {
3065                 if (contents)
3066                         *contents = NULL;
3067                 if (type)
3068                         *type = c->signature[c->index];
3069                 return 1;
3070         }
3071
3072         if (c->signature[c->index] == SD_BUS_TYPE_ARRAY) {
3073
3074                 if (contents) {
3075                         size_t l;
3076                         char *sig;
3077
3078                         r = signature_element_length(c->signature+c->index+1, &l);
3079                         if (r < 0)
3080                                 return r;
3081
3082                         assert(l >= 1);
3083
3084                         sig = strndup(c->signature + c->index + 1, l);
3085                         if (!sig)
3086                                 return -ENOMEM;
3087
3088                         free(m->peeked_signature);
3089                         m->peeked_signature = sig;
3090
3091                         *contents = sig;
3092                 }
3093
3094                 if (type)
3095                         *type = SD_BUS_TYPE_ARRAY;
3096
3097                 return 1;
3098         }
3099
3100         if (c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ||
3101             c->signature[c->index] == SD_BUS_TYPE_DICT_ENTRY_BEGIN) {
3102
3103                 if (contents) {
3104                         size_t l;
3105                         char *sig;
3106
3107                         r = signature_element_length(c->signature+c->index, &l);
3108                         if (r < 0)
3109                                 return r;
3110
3111                         assert(l >= 2);
3112                         sig = strndup(c->signature + c->index + 1, l - 2);
3113                         if (!sig)
3114                                 return -ENOMEM;
3115
3116                         free(m->peeked_signature);
3117                         m->peeked_signature = sig;
3118
3119                         *contents = sig;
3120                 }
3121
3122                 if (type)
3123                         *type = c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY;
3124
3125                 return 1;
3126         }
3127
3128         if (c->signature[c->index] == SD_BUS_TYPE_VARIANT) {
3129                 if (contents) {
3130                         size_t rindex, l;
3131                         void *q;
3132
3133                         rindex = m->rindex;
3134                         r = message_peek_body(m, &rindex, 1, 1, &q);
3135                         if (r < 0)
3136                                 return r;
3137                         if (r == 0)
3138                                 goto eof;
3139
3140                         l = *(uint8_t*) q;
3141                         r = message_peek_body(m, &rindex, 1, l+1, &q);
3142                         if (r < 0)
3143                                 return r;
3144                         if (r == 0)
3145                                 return -EBADMSG;
3146
3147                         if (!validate_signature(q, l))
3148                                 return -EBADMSG;
3149
3150                         *contents = q;
3151                 }
3152
3153                 if (type)
3154                         *type = SD_BUS_TYPE_VARIANT;
3155
3156                 return 1;
3157         }
3158
3159         return -EINVAL;
3160
3161 eof:
3162         if (type)
3163                 *type = 0;
3164         if (contents)
3165                 *contents = NULL;
3166         return 0;
3167 }
3168
3169 _public_ int sd_bus_message_rewind(sd_bus_message *m, int complete) {
3170         struct bus_container *c;
3171
3172         assert_return(m, -EINVAL);
3173         assert_return(m->sealed, -EPERM);
3174
3175         if (complete) {
3176                 message_reset_containers(m);
3177                 m->rindex = 0;
3178                 m->root_container.index = 0;
3179
3180                 c = message_get_container(m);
3181         } else {
3182                 c = message_get_container(m);
3183
3184                 c->index = 0;
3185                 m->rindex = c->begin;
3186         }
3187
3188         return !isempty(c->signature);
3189 }
3190 static int message_read_ap(
3191                 sd_bus_message *m,
3192                 const char *types,
3193                 va_list ap) {
3194
3195         unsigned n_array, n_struct;
3196         TypeStack stack[BUS_CONTAINER_DEPTH];
3197         unsigned stack_ptr = 0;
3198         unsigned n_loop = 0;
3199         int r;
3200
3201         assert(m);
3202
3203         if (isempty(types))
3204                 return 0;
3205
3206         /* Ideally, we'd just call ourselves recursively on every
3207          * complex type. However, the state of a va_list that is
3208          * passed to a function is undefined after that function
3209          * returns. This means we need to docode the va_list linearly
3210          * in a single stackframe. We hence implement our own
3211          * home-grown stack in an array. */
3212
3213         n_array = (unsigned) -1; /* lenght of current array entries */
3214         n_struct = strlen(types); /* length of current struct contents signature */
3215
3216         for (;;) {
3217                 const char *t;
3218
3219                 n_loop++;
3220
3221                 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
3222                         r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
3223                         if (r < 0)
3224                                 return r;
3225                         if (r == 0)
3226                                 break;
3227
3228                         r = sd_bus_message_exit_container(m);
3229                         if (r < 0)
3230                                 return r;
3231
3232                         continue;
3233                 }
3234
3235                 t = types;
3236                 if (n_array != (unsigned) -1)
3237                         n_array --;
3238                 else {
3239                         types ++;
3240                         n_struct--;
3241                 }
3242
3243                 switch (*t) {
3244
3245                 case SD_BUS_TYPE_BYTE:
3246                 case SD_BUS_TYPE_BOOLEAN:
3247                 case SD_BUS_TYPE_INT16:
3248                 case SD_BUS_TYPE_UINT16:
3249                 case SD_BUS_TYPE_INT32:
3250                 case SD_BUS_TYPE_UINT32:
3251                 case SD_BUS_TYPE_INT64:
3252                 case SD_BUS_TYPE_UINT64:
3253                 case SD_BUS_TYPE_DOUBLE:
3254                 case SD_BUS_TYPE_STRING:
3255                 case SD_BUS_TYPE_OBJECT_PATH:
3256                 case SD_BUS_TYPE_SIGNATURE:
3257                 case SD_BUS_TYPE_UNIX_FD: {
3258                         void *p;
3259
3260                         p = va_arg(ap, void*);
3261                         r = sd_bus_message_read_basic(m, *t, p);
3262                         if (r < 0)
3263                                 return r;
3264                         if (r == 0) {
3265                                 if (n_loop <= 1)
3266                                         return 0;
3267
3268                                 return -ENXIO;
3269                         }
3270
3271                         break;
3272                 }
3273
3274                 case SD_BUS_TYPE_ARRAY: {
3275                         size_t k;
3276
3277                         r = signature_element_length(t + 1, &k);
3278                         if (r < 0)
3279                   &