chiark / gitweb /
bus: implement sd_bus_message_append_string_memfd()
[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->size > 0)
69                                 assert_se(munmap(part->data, PAGE_ALIGN(part->size)) == 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                 ioctl(m->bus->input_fd, KDBUS_CMD_MSG_RELEASE, m->kdbus);
130
131         if (m->free_fds) {
132                 close_many(m->fds, m->n_fds);
133                 free(m->fds);
134         }
135
136         if (m->bus)
137                 sd_bus_unref(m->bus);
138
139         if (m->iovec != m->iovec_fixed)
140                 free(m->iovec);
141
142         free(m->cmdline_array);
143
144         message_reset_containers(m);
145         free(m->root_container.signature);
146
147         free(m->peeked_signature);
148
149         free(m->unit);
150         free(m->user_unit);
151         free(m->session);
152         free(m);
153 }
154
155 static void *message_extend_fields(sd_bus_message *m, size_t align, size_t sz) {
156         void *op, *np;
157         size_t old_size, new_size, start;
158
159         assert(m);
160
161         if (m->poisoned)
162                 return NULL;
163
164         old_size = sizeof(struct bus_header) + m->header->fields_size;
165         start = ALIGN_TO(old_size, align);
166         new_size = start + sz;
167
168         if (old_size == new_size)
169                 return (uint8_t*) m->header + old_size;
170
171         if (new_size > (size_t) ((uint32_t) -1))
172                 goto poison;
173
174         if (m->free_header) {
175                 np = realloc(m->header, ALIGN8(new_size));
176                 if (!np)
177                         goto poison;
178         } else {
179                 /* Initially, the header is allocated as part of of
180                  * the sd_bus_message itself, let's replace it by
181                  * dynamic data */
182
183                 np = malloc(ALIGN8(new_size));
184                 if (!np)
185                         goto poison;
186
187                 memcpy(np, m->header, sizeof(struct bus_header));
188         }
189
190         /* Zero out padding */
191         if (start > old_size)
192                 memset((uint8_t*) np + old_size, 0, start - old_size);
193
194         op = m->header;
195         m->header = np;
196         m->header->fields_size = new_size - sizeof(struct bus_header);
197
198         /* Adjust quick access pointers */
199         m->path = adjust_pointer(m->path, op, old_size, m->header);
200         m->interface = adjust_pointer(m->interface, op, old_size, m->header);
201         m->member = adjust_pointer(m->member, op, old_size, m->header);
202         m->destination = adjust_pointer(m->destination, op, old_size, m->header);
203         m->sender = adjust_pointer(m->sender, op, old_size, m->header);
204         m->error.name = adjust_pointer(m->error.name, op, old_size, m->header);
205
206         m->free_header = true;
207
208         return (uint8_t*) np + start;
209
210 poison:
211         m->poisoned = true;
212         return NULL;
213 }
214
215 static int message_append_field_string(
216                 sd_bus_message *m,
217                 uint8_t h,
218                 char type,
219                 const char *s,
220                 const char **ret) {
221
222         size_t l;
223         uint8_t *p;
224
225         assert(m);
226
227         l = strlen(s);
228         if (l > (size_t) (uint32_t) -1)
229                 return -EINVAL;
230
231         /* field id byte + signature length + signature 's' + NUL + string length + string + NUL */
232         p = message_extend_fields(m, 8, 4 + 4 + l + 1);
233         if (!p)
234                 return -ENOMEM;
235
236         p[0] = h;
237         p[1] = 1;
238         p[2] = type;
239         p[3] = 0;
240
241         ((uint32_t*) p)[1] = l;
242         memcpy(p + 8, s, l + 1);
243
244         if (ret)
245                 *ret = (char*) p + 8;
246
247         return 0;
248 }
249
250 static int message_append_field_signature(
251                 sd_bus_message *m,
252                 uint8_t h,
253                 const char *s,
254                 const char **ret) {
255
256         size_t l;
257         uint8_t *p;
258
259         assert(m);
260
261         l = strlen(s);
262         if (l > 255)
263                 return -EINVAL;
264
265         /* field id byte + signature length + signature 'g' + NUL + string length + string + NUL */
266         p = message_extend_fields(m, 8, 4 + 1 + l + 1);
267         if (!p)
268                 return -ENOMEM;
269
270         p[0] = h;
271         p[1] = 1;
272         p[2] = SD_BUS_TYPE_SIGNATURE;
273         p[3] = 0;
274         p[4] = l;
275         memcpy(p + 5, s, l + 1);
276
277         if (ret)
278                 *ret = (const char*) p + 5;
279
280         return 0;
281 }
282
283 static int message_append_field_uint32(sd_bus_message *m, uint8_t h, uint32_t x) {
284         uint8_t *p;
285
286         assert(m);
287
288         /* field id byte + signature length + signature 'u' + NUL + value */
289         p = message_extend_fields(m, 8, 4 + 4);
290         if (!p)
291                 return -ENOMEM;
292
293         p[0] = h;
294         p[1] = 1;
295         p[2] = SD_BUS_TYPE_UINT32;
296         p[3] = 0;
297
298         ((uint32_t*) p)[1] = x;
299
300         return 0;
301 }
302
303 int bus_message_from_header(
304                 void *buffer,
305                 size_t length,
306                 int *fds,
307                 unsigned n_fds,
308                 const struct ucred *ucred,
309                 const char *label,
310                 size_t extra,
311                 sd_bus_message **ret) {
312
313         sd_bus_message *m;
314         struct bus_header *h;
315         size_t a, label_sz;
316
317         assert(buffer || length <= 0);
318         assert(fds || n_fds <= 0);
319         assert(ret);
320
321         if (length < sizeof(struct bus_header))
322                 return -EBADMSG;
323
324         h = buffer;
325         if (h->version != 1)
326                 return -EBADMSG;
327
328         if (h->serial == 0)
329                 return -EBADMSG;
330
331         if (h->type == _SD_BUS_MESSAGE_TYPE_INVALID)
332                 return -EBADMSG;
333
334         if (h->endian != SD_BUS_LITTLE_ENDIAN &&
335             h->endian != SD_BUS_BIG_ENDIAN)
336                 return -EBADMSG;
337
338         a = ALIGN(sizeof(sd_bus_message)) + ALIGN(extra);
339
340         if (label) {
341                 label_sz = strlen(label);
342                 a += label_sz + 1;
343         }
344
345         m = malloc0(a);
346         if (!m)
347                 return -ENOMEM;
348
349         m->n_ref = 1;
350         m->sealed = true;
351         m->header = h;
352         m->fds = fds;
353         m->n_fds = n_fds;
354
355         if (ucred) {
356                 m->uid = ucred->uid;
357                 m->pid = ucred->pid;
358                 m->gid = ucred->gid;
359                 m->uid_valid = m->gid_valid = true;
360         }
361
362         if (label) {
363                 m->label = (char*) m + ALIGN(sizeof(sd_bus_message)) + ALIGN(extra);
364                 memcpy(m->label, label, label_sz + 1);
365         }
366
367         *ret = m;
368         return 0;
369 }
370
371 int bus_message_from_malloc(
372                 void *buffer,
373                 size_t length,
374                 int *fds,
375                 unsigned n_fds,
376                 const struct ucred *ucred,
377                 const char *label,
378                 sd_bus_message **ret) {
379
380         sd_bus_message *m;
381         int r;
382
383         r = bus_message_from_header(buffer, length, fds, n_fds, ucred, label, 0, &m);
384         if (r < 0)
385                 return r;
386
387         if (length != BUS_MESSAGE_SIZE(m)) {
388                 r = -EBADMSG;
389                 goto fail;
390         }
391
392         m->n_body_parts = 1;
393         m->body.data = (uint8_t*) buffer + sizeof(struct bus_header) + ALIGN8(BUS_MESSAGE_FIELDS_SIZE(m));
394         m->body.size = length - sizeof(struct bus_header) - ALIGN8(BUS_MESSAGE_FIELDS_SIZE(m));
395         m->body.sealed = true;
396         m->body.memfd = -1;
397
398         m->n_iovec = 1;
399         m->iovec = m->iovec_fixed;
400         m->iovec[0].iov_base = buffer;
401         m->iovec[0].iov_len = length;
402
403         r = bus_message_parse_fields(m);
404         if (r < 0)
405                 goto fail;
406
407         /* We take possession of the memory and fds now */
408         m->free_header = true;
409         m->free_fds = true;
410
411         *ret = m;
412         return 0;
413
414 fail:
415         message_free(m);
416         return r;
417 }
418
419 static sd_bus_message *message_new(sd_bus *bus, uint8_t type) {
420         sd_bus_message *m;
421
422         m = malloc0(ALIGN(sizeof(sd_bus_message)) + sizeof(struct bus_header));
423         if (!m)
424                 return NULL;
425
426         m->n_ref = 1;
427         m->header = (struct bus_header*) ((uint8_t*) m + ALIGN(sizeof(struct sd_bus_message)));
428         m->header->endian = SD_BUS_NATIVE_ENDIAN;
429         m->header->type = type;
430         m->header->version = bus ? bus->message_version : 1;
431         m->allow_fds = !bus || bus->can_fds || (bus->state != BUS_HELLO && bus->state != BUS_RUNNING);
432
433         if (bus)
434                 m->bus = sd_bus_ref(bus);
435
436         return m;
437 }
438
439 int sd_bus_message_new_signal(
440                 sd_bus *bus,
441                 const char *path,
442                 const char *interface,
443                 const char *member,
444                 sd_bus_message **m) {
445
446         sd_bus_message *t;
447         int r;
448
449         if (!path)
450                 return -EINVAL;
451         if (!interface)
452                 return -EINVAL;
453         if (!member)
454                 return -EINVAL;
455         if (!m)
456                 return -EINVAL;
457         if (bus && bus->state == BUS_UNSET)
458                 return -ENOTCONN;
459
460         t = message_new(bus, SD_BUS_MESSAGE_TYPE_SIGNAL);
461         if (!t)
462                 return -ENOMEM;
463
464         t->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
465
466         r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_PATH, SD_BUS_TYPE_OBJECT_PATH, path, &t->path);
467         if (r < 0)
468                 goto fail;
469         r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_INTERFACE, SD_BUS_TYPE_STRING, interface, &t->interface);
470         if (r < 0)
471                 goto fail;
472         r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_MEMBER, SD_BUS_TYPE_STRING, member, &t->member);
473         if (r < 0)
474                 goto fail;
475
476         *m = t;
477         return 0;
478
479 fail:
480         sd_bus_message_unref(t);
481         return r;
482 }
483
484 int sd_bus_message_new_method_call(
485                 sd_bus *bus,
486                 const char *destination,
487                 const char *path,
488                 const char *interface,
489                 const char *member,
490                 sd_bus_message **m) {
491
492         sd_bus_message *t;
493         int r;
494
495         if (!path)
496                 return -EINVAL;
497         if (!member)
498                 return -EINVAL;
499         if (!m)
500                 return -EINVAL;
501         if (bus && bus->state == BUS_UNSET)
502                 return -ENOTCONN;
503
504         t = message_new(bus, SD_BUS_MESSAGE_TYPE_METHOD_CALL);
505         if (!t)
506                 return -ENOMEM;
507
508         r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_PATH, SD_BUS_TYPE_OBJECT_PATH, path, &t->path);
509         if (r < 0)
510                 goto fail;
511         r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_MEMBER, SD_BUS_TYPE_STRING, member, &t->member);
512         if (r < 0)
513                 goto fail;
514
515         if (interface) {
516                 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_INTERFACE, SD_BUS_TYPE_STRING, interface, &t->interface);
517                 if (r < 0)
518                         goto fail;
519         }
520
521         if (destination) {
522                 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &t->destination);
523                 if (r < 0)
524                         goto fail;
525         }
526
527         *m = t;
528         return 0;
529
530 fail:
531         message_free(t);
532         return r;
533 }
534
535 static int message_new_reply(
536                 sd_bus *bus,
537                 sd_bus_message *call,
538                 uint8_t type,
539                 sd_bus_message **m) {
540
541         sd_bus_message *t;
542         int r;
543
544         if (!call)
545                 return -EINVAL;
546         if (!call->sealed)
547                 return -EPERM;
548         if (call->header->type != SD_BUS_MESSAGE_TYPE_METHOD_CALL)
549                 return -EINVAL;
550         if (!m)
551                 return -EINVAL;
552         if (bus && bus->state == BUS_UNSET)
553                 return -ENOTCONN;
554
555         t = message_new(bus, type);
556         if (!t)
557                 return -ENOMEM;
558
559         t->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
560         t->reply_serial = BUS_MESSAGE_SERIAL(call);
561
562         r = message_append_field_uint32(t, SD_BUS_MESSAGE_HEADER_REPLY_SERIAL, t->reply_serial);
563         if (r < 0)
564                 goto fail;
565
566         if (call->sender) {
567                 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, call->sender, &t->sender);
568                 if (r < 0)
569                         goto fail;
570         }
571
572         t->dont_send = !!(call->header->flags & SD_BUS_MESSAGE_NO_REPLY_EXPECTED);
573
574         *m = t;
575         return 0;
576
577 fail:
578         message_free(t);
579         return r;
580 }
581
582 int sd_bus_message_new_method_return(
583                 sd_bus *bus,
584                 sd_bus_message *call,
585                 sd_bus_message **m) {
586
587         return message_new_reply(bus, call, SD_BUS_MESSAGE_TYPE_METHOD_RETURN, m);
588 }
589
590 int sd_bus_message_new_method_error(
591                 sd_bus *bus,
592                 sd_bus_message *call,
593                 const sd_bus_error *e,
594                 sd_bus_message **m) {
595
596         sd_bus_message *t;
597         int r;
598
599         if (!sd_bus_error_is_set(e))
600                 return -EINVAL;
601         if (!m)
602                 return -EINVAL;
603
604         r = message_new_reply(bus, call, SD_BUS_MESSAGE_TYPE_METHOD_ERROR, &t);
605         if (r < 0)
606                 return r;
607
608         r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_ERROR_NAME, SD_BUS_TYPE_STRING, e->name, &t->error.name);
609         if (r < 0)
610                 goto fail;
611
612         if (e->message) {
613                 r = message_append_basic(t, SD_BUS_TYPE_STRING, e->message, (const void**) &t->error.message);
614                 if (r < 0)
615                         goto fail;
616         }
617
618         *m = t;
619         return 0;
620
621 fail:
622         message_free(t);
623         return r;
624 }
625
626 sd_bus_message* sd_bus_message_ref(sd_bus_message *m) {
627         if (!m)
628                 return NULL;
629
630         assert(m->n_ref > 0);
631         m->n_ref++;
632
633         return m;
634 }
635
636 sd_bus_message* sd_bus_message_unref(sd_bus_message *m) {
637         if (!m)
638                 return NULL;
639
640         assert(m->n_ref > 0);
641         m->n_ref--;
642
643         if (m->n_ref <= 0)
644                 message_free(m);
645
646         return NULL;
647 }
648
649 int sd_bus_message_get_type(sd_bus_message *m, uint8_t *type) {
650         if (!m)
651                 return -EINVAL;
652         if (!type)
653                 return -EINVAL;
654
655         *type = m->header->type;
656         return 0;
657 }
658
659 int sd_bus_message_get_serial(sd_bus_message *m, uint64_t *serial) {
660         if (!m)
661                 return -EINVAL;
662         if (!serial)
663                 return -EINVAL;
664         if (m->header->serial == 0)
665                 return -ENOENT;
666
667         *serial = BUS_MESSAGE_SERIAL(m);
668         return 0;
669 }
670
671 int sd_bus_message_get_reply_serial(sd_bus_message *m, uint64_t *serial) {
672         if (!m)
673                 return -EINVAL;
674         if (!serial)
675                 return -EINVAL;
676         if (m->reply_serial == 0)
677                 return -ENOENT;
678
679         *serial = m->reply_serial;
680         return 0;
681 }
682
683 int sd_bus_message_get_no_reply(sd_bus_message *m) {
684         if (!m)
685                 return -EINVAL;
686
687         return m->header->type == SD_BUS_MESSAGE_TYPE_METHOD_CALL ? !!(m->header->flags & SD_BUS_MESSAGE_NO_REPLY_EXPECTED) : 0;
688 }
689
690 const char *sd_bus_message_get_path(sd_bus_message *m) {
691         if (!m)
692                 return NULL;
693
694         return m->path;
695 }
696
697 const char *sd_bus_message_get_interface(sd_bus_message *m) {
698         if (!m)
699                 return NULL;
700
701         return m->interface;
702 }
703
704 const char *sd_bus_message_get_member(sd_bus_message *m) {
705         if (!m)
706                 return NULL;
707
708         return m->member;
709 }
710 const char *sd_bus_message_get_destination(sd_bus_message *m) {
711         if (!m)
712                 return NULL;
713
714         return m->destination;
715 }
716
717 const char *sd_bus_message_get_sender(sd_bus_message *m) {
718         if (!m)
719                 return NULL;
720
721         return m->sender;
722 }
723
724 const sd_bus_error *sd_bus_message_get_error(sd_bus_message *m) {
725         if (!m)
726                 return NULL;
727
728         if (!sd_bus_error_is_set(&m->error))
729                 return NULL;
730
731         return &m->error;
732 }
733
734 int sd_bus_message_get_uid(sd_bus_message *m, uid_t *uid) {
735         if (!m)
736                 return -EINVAL;
737         if (!uid)
738                 return -EINVAL;
739         if (!m->uid_valid)
740                 return -ESRCH;
741
742         *uid = m->uid;
743         return 0;
744 }
745
746 int sd_bus_message_get_gid(sd_bus_message *m, gid_t *gid) {
747         if (!m)
748                 return -EINVAL;
749         if (!gid)
750                 return -EINVAL;
751         if (!m->gid_valid)
752                 return -ESRCH;
753
754         *gid = m->gid;
755         return 0;
756 }
757
758 int sd_bus_message_get_pid(sd_bus_message *m, pid_t *pid) {
759         if (!m)
760                 return -EINVAL;
761         if (!pid)
762                 return -EINVAL;
763         if (m->pid <= 0)
764                 return -ESRCH;
765
766         *pid = m->pid;
767         return 0;
768 }
769
770 int sd_bus_message_get_tid(sd_bus_message *m, pid_t *tid) {
771         if (!m)
772                 return -EINVAL;
773         if (!tid)
774                 return -EINVAL;
775         if (m->tid <= 0)
776                 return -ESRCH;
777
778         *tid = m->tid;
779         return 0;
780 }
781
782 int sd_bus_message_get_pid_starttime(sd_bus_message *m, uint64_t *usec) {
783         if (!m)
784                 return -EINVAL;
785         if (!usec)
786                 return -EINVAL;
787         if (m->pid_starttime <= 0)
788                 return -ESRCH;
789
790         *usec = m->pid_starttime;
791         return 0;
792 }
793
794 int sd_bus_message_get_selinux_context(sd_bus_message *m, const char **ret) {
795         if (!m)
796                 return -EINVAL;
797         if (!m->label)
798                 return -ESRCH;
799
800         *ret = m->label;
801         return 0;
802 }
803
804 int sd_bus_message_get_monotonic_timestamp(sd_bus_message *m, uint64_t *usec) {
805         if (!m)
806                 return -EINVAL;
807         if (!usec)
808                 return -EINVAL;
809         if (m->monotonic <= 0)
810                 return -ESRCH;
811
812         *usec = m->monotonic;
813         return 0;
814 }
815
816 int sd_bus_message_get_realtime_timestamp(sd_bus_message *m, uint64_t *usec) {
817         if (!m)
818                 return -EINVAL;
819         if (!usec)
820                 return -EINVAL;
821         if (m->realtime <= 0)
822                 return -ESRCH;
823
824         *usec = m->realtime;
825         return 0;
826 }
827
828 int sd_bus_message_get_comm(sd_bus_message *m, const char **ret) {
829         if (!m)
830                 return -EINVAL;
831         if (!ret)
832                 return -EINVAL;
833         if (!m->comm)
834                 return -ESRCH;
835
836         *ret = m->comm;
837         return 0;
838 }
839
840 int sd_bus_message_get_tid_comm(sd_bus_message *m, const char **ret) {
841         if (!m)
842                 return -EINVAL;
843         if (!ret)
844                 return -EINVAL;
845         if (!m->tid_comm)
846                 return -ESRCH;
847
848         *ret = m->tid_comm;
849         return 0;
850 }
851
852 int sd_bus_message_get_exe(sd_bus_message *m, const char **ret) {
853         if (!m)
854                 return -EINVAL;
855         if (!ret)
856                 return -EINVAL;
857         if (!m->exe)
858                 return -ESRCH;
859
860         *ret = m->exe;
861         return 0;
862 }
863
864 int sd_bus_message_get_cgroup(sd_bus_message *m, const char **ret) {
865         if (!m)
866                 return -EINVAL;
867         if (!ret)
868                 return -EINVAL;
869         if (!m->cgroup)
870                 return -ESRCH;
871
872         *ret = m->cgroup;
873         return 0;
874 }
875
876 int sd_bus_message_get_unit(sd_bus_message *m, const char **ret) {
877         int r;
878
879         if (!m)
880                 return -EINVAL;
881         if (!ret)
882                 return -EINVAL;
883         if (!m->cgroup)
884                 return -ESRCH;
885
886         if (!m->unit) {
887                 r = cg_path_get_unit(m->cgroup, &m->unit);
888                 if (r < 0)
889                         return r;
890         }
891
892         *ret = m->unit;
893         return 0;
894 }
895
896 int sd_bus_message_get_user_unit(sd_bus_message *m, const char **ret) {
897         int r;
898
899         if (!m)
900                 return -EINVAL;
901         if (!ret)
902                 return -EINVAL;
903         if (!m->cgroup)
904                 return -ESRCH;
905
906         if (!m->user_unit) {
907                 r = cg_path_get_user_unit(m->cgroup, &m->user_unit);
908                 if (r < 0)
909                         return r;
910         }
911
912         *ret = m->user_unit;
913         return 0;
914 }
915
916 int sd_bus_message_get_session(sd_bus_message *m, const char **ret) {
917         int r;
918
919         if (!m)
920                 return -EINVAL;
921         if (!ret)
922                 return -EINVAL;
923         if (!m->cgroup)
924                 return -ESRCH;
925
926         if (!m->session) {
927                 r = cg_path_get_session(m->cgroup, &m->session);
928                 if (r < 0)
929                         return r;
930         }
931
932         *ret = m->session;
933         return 0;
934 }
935
936 int sd_bus_message_get_owner_uid(sd_bus_message *m, uid_t *uid) {
937         if (!m)
938                 return -EINVAL;
939         if (!uid)
940                 return -EINVAL;
941         if (!m->cgroup)
942                 return -ESRCH;
943
944         return cg_path_get_owner_uid(m->cgroup, uid);
945 }
946
947 int sd_bus_message_get_cmdline(sd_bus_message *m, char ***cmdline) {
948         size_t n, i;
949         const char *p;
950         bool first;
951
952         if (!m)
953                 return -EINVAL;
954
955         if (!m->cmdline)
956                 return -ENOENT;
957
958         for (p = m->cmdline, n = 0; p < m->cmdline + m->cmdline_length; p++)
959                 if (*p == 0)
960                         n++;
961
962         m->cmdline_array = new(char*, n + 1);
963         if (!m->cmdline_array)
964                 return -ENOMEM;
965
966         for (p = m->cmdline, i = 0, first = true; p < m->cmdline + m->cmdline_length; p++) {
967                 if (first)
968                         m->cmdline_array[i++] = (char*) p;
969
970                 first = *p == 0;
971         }
972
973         m->cmdline_array[i] = NULL;
974         *cmdline = m->cmdline_array;
975
976         return 0;
977 }
978
979 int sd_bus_message_get_audit_sessionid(sd_bus_message *m, uint32_t *sessionid) {
980         if (!m)
981                 return -EINVAL;
982         if (!sessionid)
983                 return -EINVAL;
984         if (!m->audit)
985                 return -ESRCH;
986
987         *sessionid = m->audit->sessionid;
988         return 0;
989 }
990
991 int sd_bus_message_get_audit_loginuid(sd_bus_message *m, uid_t *uid) {
992         if (!m)
993                 return -EINVAL;
994         if (!uid)
995                 return -EINVAL;
996         if (!m->audit)
997                 return -ESRCH;
998
999         *uid = m->audit->loginuid;
1000         return 0;
1001 }
1002
1003 int sd_bus_message_has_effective_cap(sd_bus_message *m, int capability) {
1004         unsigned sz;
1005
1006         if (!m)
1007                 return -EINVAL;
1008         if (capability < 0)
1009                 return -EINVAL;
1010         if (!m->capability)
1011                 return -ESRCH;
1012
1013         sz = m->capability_size / 4;
1014         if ((unsigned) capability >= sz*8)
1015                 return 0;
1016
1017         return !!(m->capability[2 * sz + (capability / 8)] & (1 << (capability % 8)));
1018 }
1019
1020 int sd_bus_message_is_signal(sd_bus_message *m, const char *interface, const char *member) {
1021         if (!m)
1022                 return -EINVAL;
1023
1024         if (m->header->type != SD_BUS_MESSAGE_TYPE_SIGNAL)
1025                 return 0;
1026
1027         if (interface && (!m->interface || !streq(m->interface, interface)))
1028                 return 0;
1029
1030         if (member &&  (!m->member || !streq(m->member, member)))
1031                 return 0;
1032
1033         return 1;
1034 }
1035
1036 int sd_bus_message_is_method_call(sd_bus_message *m, const char *interface, const char *member) {
1037         if (!m)
1038                 return -EINVAL;
1039
1040         if (m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_CALL)
1041                 return 0;
1042
1043         if (interface && (!m->interface || !streq(m->interface, interface)))
1044                 return 0;
1045
1046         if (member &&  (!m->member || !streq(m->member, member)))
1047                 return 0;
1048
1049         return 1;
1050 }
1051
1052 int sd_bus_message_is_method_error(sd_bus_message *m, const char *name) {
1053         if (!m)
1054                 return -EINVAL;
1055
1056         if (m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_ERROR)
1057                 return 0;
1058
1059         if (name && (!m->error.name || !streq(m->error.name, name)))
1060                 return 0;
1061
1062         return 1;
1063 }
1064
1065 int sd_bus_message_set_no_reply(sd_bus_message *m, int b) {
1066         if (!m)
1067                 return -EINVAL;
1068         if (m->sealed)
1069                 return -EPERM;
1070         if (m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_CALL)
1071                 return -EPERM;
1072
1073         if (b)
1074                 m->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
1075         else
1076                 m->header->flags &= ~SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
1077
1078         return 0;
1079 }
1080
1081 static struct bus_container *message_get_container(sd_bus_message *m) {
1082         assert(m);
1083
1084         if (m->n_containers == 0)
1085                 return &m->root_container;
1086
1087         assert(m->containers);
1088         return m->containers + m->n_containers - 1;
1089 }
1090
1091 struct bus_body_part *message_append_part(sd_bus_message *m) {
1092         struct bus_body_part *part;
1093
1094         assert(m);
1095
1096         if (m->poisoned)
1097                 return NULL;
1098
1099         if (m->n_body_parts <= 0) {
1100                 part = &m->body;
1101                 zero(*part);
1102         } else {
1103                 assert(m->body_end);
1104
1105                 part = new0(struct bus_body_part, 1);
1106                 if (!part) {
1107                         m->poisoned = true;
1108                         return NULL;
1109                 }
1110
1111                 m->body_end->next = part;
1112         }
1113
1114         part->memfd = -1;
1115         m->body_end = part;
1116         m->n_body_parts ++;
1117
1118         return part;
1119 }
1120
1121 static void part_zero(struct bus_body_part *part, size_t sz) {
1122         assert(part);
1123         assert(sz > 0);
1124         assert(sz < 8);
1125
1126         /* All other fields can be left in their defaults */
1127         assert(!part->data);
1128         assert(part->memfd < 0);
1129
1130         part->size = sz;
1131         part->is_zero = true;
1132         part->sealed = true;
1133 }
1134
1135 static int part_make_space(
1136                 struct sd_bus_message *m,
1137                 struct bus_body_part *part,
1138                 size_t sz,
1139                 void **q) {
1140
1141         void *n;
1142         int r;
1143
1144         assert(m);
1145         assert(part);
1146         assert(!part->sealed);
1147
1148         if (m->poisoned)
1149                 return -ENOMEM;
1150
1151         if (!part->data && part->memfd < 0)
1152                 part->memfd = bus_kernel_pop_memfd(m->bus, &part->data, &part->mapped);
1153
1154         if (part->memfd >= 0) {
1155                 uint64_t u = sz;
1156
1157                 r = ioctl(part->memfd, KDBUS_CMD_MEMFD_SIZE_SET, &u);
1158                 if (r < 0) {
1159                         m->poisoned = true;
1160                         return -errno;
1161                 }
1162
1163                 if (!part->data || sz > part->mapped) {
1164                         size_t psz = PAGE_ALIGN(sz > 0 ? sz : 1);
1165
1166                         if (part->mapped <= 0)
1167                                 n = mmap(NULL, psz, PROT_READ|PROT_WRITE, MAP_SHARED, part->memfd, 0);
1168                         else
1169                                 n = mremap(part->data, part->mapped, psz, MREMAP_MAYMOVE);
1170
1171                         if (n == MAP_FAILED) {
1172                                 m->poisoned = true;
1173                                 return -errno;
1174                         }
1175
1176                         part->mapped = psz;
1177                         part->data = n;
1178                         part->munmap_this = true;
1179                 }
1180         } else {
1181                 n = realloc(part->data, sz);
1182                 if (!n) {
1183                         m->poisoned = true;
1184                         return -ENOMEM;
1185                 }
1186
1187                 part->data = n;
1188                 part->free_this = true;
1189         }
1190
1191         if (q)
1192                 *q = part->data ? (uint8_t*) part->data + part->size : NULL;
1193
1194         part->size = sz;
1195         return 0;
1196 }
1197
1198 static void message_extend_containers(sd_bus_message *m, size_t expand) {
1199         struct bus_container *c;
1200
1201         assert(m);
1202
1203         if (expand <= 0)
1204                 return;
1205
1206         /* Update counters */
1207         for (c = m->containers; c < m->containers + m->n_containers; c++)
1208                 if (c->array_size)
1209                         *c->array_size += expand;
1210
1211 }
1212
1213 static void *message_extend_body(sd_bus_message *m, size_t align, size_t sz) {
1214         struct bus_body_part *part = NULL;
1215         size_t start_body, end_body, padding, start_part, end_part, added;
1216         bool add_new_part;
1217         void *p;
1218         int r;
1219
1220         assert(m);
1221         assert(align > 0);
1222         assert(!m->sealed);
1223
1224         if (m->poisoned)
1225                 return NULL;
1226
1227         start_body = ALIGN_TO((size_t) m->header->body_size, align);
1228         end_body = start_body + sz;
1229
1230         padding = start_body - m->header->body_size;
1231         added = padding + sz;
1232
1233         /* Check for 32bit overflows */
1234         if (end_body > (size_t) ((uint32_t) -1)) {
1235                 m->poisoned = true;
1236                 return NULL;
1237         }
1238
1239         add_new_part =
1240                 m->n_body_parts <= 0 ||
1241                 m->body_end->sealed ||
1242                 padding != ALIGN_TO(m->body_end->size, align) - m->body_end->size;
1243
1244         if (add_new_part) {
1245                 if (padding > 0) {
1246                         part = message_append_part(m);
1247                         if (!part)
1248                                 return NULL;
1249
1250                         part_zero(part, padding);
1251                 }
1252
1253                 part = message_append_part(m);
1254                 if (!part)
1255                         return NULL;
1256
1257                 r = part_make_space(m, part, sz, &p);
1258                 if (r < 0)
1259                         return NULL;
1260         } else {
1261                 struct bus_container *c;
1262                 void *op;
1263                 size_t os;
1264
1265                 part = m->body_end;
1266                 op = part->data;
1267                 os = part->size;
1268
1269                 start_part = ALIGN_TO(part->size, align);
1270                 end_part = start_part + sz;
1271
1272                 r = part_make_space(m, part, end_part, &p);
1273                 if (r < 0)
1274                         return NULL;
1275
1276                 if (padding > 0) {
1277                         memset(p, 0, padding);
1278                         p = (uint8_t*) p + padding;
1279                 }
1280
1281                 /* Readjust pointers */
1282                 for (c = m->containers; c < m->containers + m->n_containers; c++)
1283                         c->array_size = adjust_pointer(c->array_size, op, os, part->data);
1284
1285                 m->error.message = (const char*) adjust_pointer(m->error.message, op, os, part->data);
1286         }
1287
1288         m->header->body_size = end_body;
1289         message_extend_containers(m, added);
1290
1291         return p;
1292 }
1293
1294 int message_append_basic(sd_bus_message *m, char type, const void *p, const void **stored) {
1295         struct bus_container *c;
1296         ssize_t align, sz;
1297         uint32_t k;
1298         void *a;
1299         int fd = -1;
1300         uint32_t fdi = 0;
1301         int r;
1302
1303         if (!m)
1304                 return -EINVAL;
1305         if (!p)
1306                 return -EINVAL;
1307         if (m->sealed)
1308                 return -EPERM;
1309         if (!bus_type_is_basic(type))
1310                 return -EINVAL;
1311         if (m->poisoned)
1312                 return -ESTALE;
1313
1314         c = message_get_container(m);
1315
1316         if (c->signature && c->signature[c->index]) {
1317                 /* Container signature is already set */
1318
1319                 if (c->signature[c->index] != type)
1320                         return -ENXIO;
1321         } else {
1322                 char *e;
1323
1324                 /* Maybe we can append to the signature? But only if this is the top-level container*/
1325                 if (c->enclosing != 0)
1326                         return -ENXIO;
1327
1328                 e = strextend(&c->signature, CHAR_TO_STR(type), NULL);
1329                 if (!e) {
1330                         m->poisoned = true;
1331                         return -ENOMEM;
1332                 }
1333         }
1334
1335         switch (type) {
1336
1337         case SD_BUS_TYPE_STRING:
1338         case SD_BUS_TYPE_OBJECT_PATH:
1339
1340                 align = 4;
1341                 sz = 4 + strlen(p) + 1;
1342                 break;
1343
1344         case SD_BUS_TYPE_SIGNATURE:
1345
1346                 align = 1;
1347                 sz = 1 + strlen(p) + 1;
1348                 break;
1349
1350         case SD_BUS_TYPE_BOOLEAN:
1351                 align = sz = 4;
1352
1353                 assert_cc(sizeof(int) == sizeof(uint32_t));
1354                 memcpy(&k, p, 4);
1355                 k = !!k;
1356                 p = &k;
1357                 break;
1358
1359         case SD_BUS_TYPE_UNIX_FD: {
1360                 int z, *f;
1361
1362                 if (!m->allow_fds) {
1363                         r = -ENOTSUP;
1364                         goto fail;
1365                 }
1366
1367                 align = sz = 4;
1368
1369                 z = *(int*) p;
1370                 if (z < 0) {
1371                         r = -EINVAL;
1372                         goto fail;
1373                 }
1374
1375                 fd = fcntl(z, F_DUPFD_CLOEXEC, 3);
1376                 if (fd < 0) {
1377                         r = -errno;
1378                         goto fail;
1379                 }
1380
1381                 f = realloc(m->fds, sizeof(int) * (m->n_fds + 1));
1382                 if (!f) {
1383                         m->poisoned = true;
1384                         r = -ENOMEM;
1385                         goto fail;
1386                 }
1387
1388                 fdi = m->n_fds;
1389                 f[fdi] = fd;
1390                 m->fds = f;
1391                 m->free_fds = true;
1392                 break;
1393         }
1394
1395         default:
1396                 align = bus_type_get_alignment(type);
1397                 sz = bus_type_get_size(type);
1398                 break;
1399         }
1400
1401         assert(align > 0);
1402         assert(sz > 0);
1403
1404         a = message_extend_body(m, align, sz);
1405         if (!a) {
1406                 r = -ENOMEM;
1407                 goto fail;
1408         }
1409
1410         if (type == SD_BUS_TYPE_STRING || type == SD_BUS_TYPE_OBJECT_PATH) {
1411                 *(uint32_t*) a = sz - 5;
1412                 memcpy((uint8_t*) a + 4, p, sz - 4);
1413
1414                 if (stored)
1415                         *stored = (const uint8_t*) a + 4;
1416
1417         } else if (type == SD_BUS_TYPE_SIGNATURE) {
1418                 *(uint8_t*) a = sz - 1;
1419                 memcpy((uint8_t*) a + 1, p, sz - 1);
1420
1421                 if (stored)
1422                         *stored = (const uint8_t*) a + 1;
1423         } else if (type == SD_BUS_TYPE_UNIX_FD) {
1424                 *(uint32_t*) a = fdi;
1425
1426                 if (stored)
1427                         *stored = a;
1428
1429                 m->n_fds ++;
1430
1431         } else {
1432                 memcpy(a, p, sz);
1433
1434                 if (stored)
1435                         *stored = a;
1436         }
1437
1438         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1439                 c->index++;
1440
1441         return 0;
1442
1443 fail:
1444         if (fd >= 0)
1445                 close_nointr_nofail(fd);
1446
1447         return r;
1448 }
1449
1450 int sd_bus_message_append_basic(sd_bus_message *m, char type, const void *p) {
1451         return message_append_basic(m, type, p, NULL);
1452 }
1453
1454 int sd_bus_message_append_string_space(sd_bus_message *m, size_t size, char **s) {
1455         struct bus_container *c;
1456         void *a;
1457
1458         if (!m)
1459                 return -EINVAL;
1460         if (!s)
1461                 return -EINVAL;
1462         if (m->sealed)
1463                 return -EPERM;
1464         if (m->poisoned)
1465                 return -ESTALE;
1466
1467         c = message_get_container(m);
1468
1469         if (c->signature && c->signature[c->index]) {
1470                 /* Container signature is already set */
1471
1472                 if (c->signature[c->index] != SD_BUS_TYPE_STRING)
1473                         return -ENXIO;
1474         } else {
1475                 char *e;
1476
1477                 /* Maybe we can append to the signature? But only if this is the top-level container*/
1478                 if (c->enclosing != 0)
1479                         return -ENXIO;
1480
1481                 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRING), NULL);
1482                 if (!e) {
1483                         m->poisoned = true;
1484                         return -ENOMEM;
1485                 }
1486         }
1487
1488         a = message_extend_body(m, 4, 4 + size + 1);
1489         if (!a)
1490                 return -ENOMEM;
1491
1492         *(uint32_t*) a = size;
1493         *s = (char*) a + 4;
1494
1495         (*s)[size] = 0;
1496
1497         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1498                 c->index++;
1499
1500         return 0;
1501 }
1502
1503 static int bus_message_open_array(
1504                 sd_bus_message *m,
1505                 struct bus_container *c,
1506                 const char *contents,
1507                 uint32_t **array_size) {
1508
1509         unsigned nindex;
1510         void *a, *op;
1511         int alignment;
1512         size_t os;
1513         struct bus_body_part *o;
1514
1515         assert(m);
1516         assert(c);
1517         assert(contents);
1518         assert(array_size);
1519
1520         if (!signature_is_single(contents))
1521                 return -EINVAL;
1522
1523         alignment = bus_type_get_alignment(contents[0]);
1524         if (alignment < 0)
1525                 return alignment;
1526
1527         if (c->signature && c->signature[c->index]) {
1528
1529                 /* Verify the existing signature */
1530
1531                 if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
1532                         return -ENXIO;
1533
1534                 if (!startswith(c->signature + c->index + 1, contents))
1535                         return -ENXIO;
1536
1537                 nindex = c->index + 1 + strlen(contents);
1538         } else {
1539                 char *e;
1540
1541                 if (c->enclosing != 0)
1542                         return -ENXIO;
1543
1544                 /* Extend the existing signature */
1545
1546                 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_ARRAY), contents, NULL);
1547                 if (!e) {
1548                         m->poisoned = true;
1549                         return -ENOMEM;
1550                 }
1551
1552                 nindex = e - c->signature;
1553         }
1554
1555         a = message_extend_body(m, 4, 4);
1556         if (!a)
1557                 return -ENOMEM;
1558
1559         o = m->body_end;
1560         op = m->body_end->data;
1561         os = m->body_end->size;
1562
1563         /* Add alignment between size and first element */
1564         if (!message_extend_body(m, alignment, 0))
1565                 return -ENOMEM;
1566
1567         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1568                 c->index = nindex;
1569
1570         /* location of array size might have changed so let's readjust a */
1571         if (o == m->body_end)
1572                 a = adjust_pointer(a, op, os, m->body_end->data);
1573
1574         *(uint32_t*) a = 0;
1575         *array_size = a;
1576         return 0;
1577 }
1578
1579 static int bus_message_open_variant(
1580                 sd_bus_message *m,
1581                 struct bus_container *c,
1582                 const char *contents) {
1583
1584         size_t l;
1585         void *a;
1586
1587         assert(m);
1588         assert(c);
1589         assert(contents);
1590
1591         if (!signature_is_single(contents))
1592                 return -EINVAL;
1593
1594         if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
1595                 return -EINVAL;
1596
1597         if (c->signature && c->signature[c->index]) {
1598
1599                 if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
1600                         return -ENXIO;
1601
1602         } else {
1603                 char *e;
1604
1605                 if (c->enclosing != 0)
1606                         return -ENXIO;
1607
1608                 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_VARIANT), NULL);
1609                 if (!e) {
1610                         m->poisoned = true;
1611                         return -ENOMEM;
1612                 }
1613         }
1614
1615         l = strlen(contents);
1616         a = message_extend_body(m, 1, 1 + l + 1);
1617         if (!a)
1618                 return -ENOMEM;
1619
1620         *(uint8_t*) a = l;
1621         memcpy((uint8_t*) a + 1, contents, l + 1);
1622
1623         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1624                 c->index++;
1625
1626         return 0;
1627 }
1628
1629 static int bus_message_open_struct(
1630                 sd_bus_message *m,
1631                 struct bus_container *c,
1632                 const char *contents) {
1633
1634         size_t nindex;
1635
1636         assert(m);
1637         assert(c);
1638         assert(contents);
1639
1640         if (!signature_is_valid(contents, false))
1641                 return -EINVAL;
1642
1643         if (c->signature && c->signature[c->index]) {
1644                 size_t l;
1645
1646                 l = strlen(contents);
1647
1648                 if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
1649                     !startswith(c->signature + c->index + 1, contents) ||
1650                     c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
1651                         return -ENXIO;
1652
1653                 nindex = c->index + 1 + l + 1;
1654         } else {
1655                 char *e;
1656
1657                 if (c->enclosing != 0)
1658                         return -ENXIO;
1659
1660                 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_BEGIN), contents, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_END), NULL);
1661                 if (!e) {
1662                         m->poisoned = true;
1663                         return -ENOMEM;
1664                 }
1665
1666                 nindex = e - c->signature;
1667         }
1668
1669         /* Align contents to 8 byte boundary */
1670         if (!message_extend_body(m, 8, 0))
1671                 return -ENOMEM;
1672
1673         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1674                 c->index = nindex;
1675
1676         return 0;
1677 }
1678
1679 static int bus_message_open_dict_entry(
1680                 sd_bus_message *m,
1681                 struct bus_container *c,
1682                 const char *contents) {
1683
1684         size_t nindex;
1685
1686         assert(m);
1687         assert(c);
1688         assert(contents);
1689
1690         if (!signature_is_pair(contents))
1691                 return -EINVAL;
1692
1693         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1694                 return -ENXIO;
1695
1696         if (c->signature && c->signature[c->index]) {
1697                 size_t l;
1698
1699                 l = strlen(contents);
1700
1701                 if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
1702                     !startswith(c->signature + c->index + 1, contents) ||
1703                     c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
1704                         return -ENXIO;
1705
1706                 nindex = c->index + 1 + l + 1;
1707         } else
1708                 return -ENXIO;
1709
1710         /* Align contents to 8 byte boundary */
1711         if (!message_extend_body(m, 8, 0))
1712                 return -ENOMEM;
1713
1714         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1715                 c->index = nindex;
1716
1717         return 0;
1718 }
1719
1720 int sd_bus_message_open_container(
1721                 sd_bus_message *m,
1722                 char type,
1723                 const char *contents) {
1724
1725         struct bus_container *c, *w;
1726         uint32_t *array_size = NULL;
1727         char *signature;
1728         size_t before;
1729         int r;
1730
1731         if (!m)
1732                 return -EINVAL;
1733         if (m->sealed)
1734                 return -EPERM;
1735         if (!contents)
1736                 return -EINVAL;
1737         if (m->poisoned)
1738                 return -ESTALE;
1739
1740         /* Make sure we have space for one more container */
1741         w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
1742         if (!w) {
1743                 m->poisoned = true;
1744                 return -ENOMEM;
1745         }
1746
1747         m->containers = w;
1748
1749         c = message_get_container(m);
1750
1751         signature = strdup(contents);
1752         if (!signature) {
1753                 m->poisoned = true;
1754                 return -ENOMEM;
1755         }
1756
1757         /* Save old index in the parent container, in case we have to
1758          * abort this container */
1759         c->saved_index = c->index;
1760         before = m->header->body_size;
1761
1762         if (type == SD_BUS_TYPE_ARRAY)
1763                 r = bus_message_open_array(m, c, contents, &array_size);
1764         else if (type == SD_BUS_TYPE_VARIANT)
1765                 r = bus_message_open_variant(m, c, contents);
1766         else if (type == SD_BUS_TYPE_STRUCT)
1767                 r = bus_message_open_struct(m, c, contents);
1768         else if (type == SD_BUS_TYPE_DICT_ENTRY)
1769                 r = bus_message_open_dict_entry(m, c, contents);
1770         else
1771                 r = -EINVAL;
1772
1773         if (r < 0) {
1774                 free(signature);
1775                 return r;
1776         }
1777
1778         /* OK, let's fill it in */
1779         w += m->n_containers++;
1780         w->enclosing = type;
1781         w->signature = signature;
1782         w->index = 0;
1783         w->array_size = array_size;
1784         w->before = before;
1785         w->begin = m->rindex;
1786
1787         return 0;
1788 }
1789
1790 int sd_bus_message_close_container(sd_bus_message *m) {
1791         struct bus_container *c;
1792
1793         if (!m)
1794                 return -EINVAL;
1795         if (m->sealed)
1796                 return -EPERM;
1797         if (m->n_containers <= 0)
1798                 return -EINVAL;
1799         if (m->poisoned)
1800                 return -ESTALE;
1801
1802         c = message_get_container(m);
1803         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1804                 if (c->signature && c->signature[c->index] != 0)
1805                         return -EINVAL;
1806
1807         free(c->signature);
1808         m->n_containers--;
1809
1810         return 0;
1811 }
1812
1813 typedef struct {
1814         const char *types;
1815         unsigned n_struct;
1816         unsigned n_array;
1817 } TypeStack;
1818
1819 static int type_stack_push(TypeStack *stack, unsigned max, unsigned *i, const char *types, unsigned n_struct, unsigned n_array) {
1820         assert(stack);
1821         assert(max > 0);
1822
1823         if (*i >= max)
1824                 return -EINVAL;
1825
1826         stack[*i].types = types;
1827         stack[*i].n_struct = n_struct;
1828         stack[*i].n_array = n_array;
1829         (*i)++;
1830
1831         return 0;
1832 }
1833
1834 static int type_stack_pop(TypeStack *stack, unsigned max, unsigned *i, const char **types, unsigned *n_struct, unsigned *n_array) {
1835         assert(stack);
1836         assert(max > 0);
1837         assert(types);
1838         assert(n_struct);
1839         assert(n_array);
1840
1841         if (*i <= 0)
1842                 return 0;
1843
1844         (*i)--;
1845         *types = stack[*i].types;
1846         *n_struct = stack[*i].n_struct;
1847         *n_array = stack[*i].n_array;
1848
1849         return 1;
1850 }
1851
1852 int bus_message_append_ap(
1853                 sd_bus_message *m,
1854                 const char *types,
1855                 va_list ap) {
1856
1857         unsigned n_array, n_struct;
1858         TypeStack stack[BUS_CONTAINER_DEPTH];
1859         unsigned stack_ptr = 0;
1860         int r;
1861
1862         assert(m);
1863
1864         if (!types)
1865                 return 0;
1866
1867         n_array = (unsigned) -1;
1868         n_struct = strlen(types);
1869
1870         for (;;) {
1871                 const char *t;
1872
1873                 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
1874                         r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
1875                         if (r < 0)
1876                                 return r;
1877                         if (r == 0)
1878                                 break;
1879
1880                         r = sd_bus_message_close_container(m);
1881                         if (r < 0)
1882                                 return r;
1883
1884                         continue;
1885                 }
1886
1887                 t = types;
1888                 if (n_array != (unsigned) -1)
1889                         n_array --;
1890                 else {
1891                         types ++;
1892                         n_struct--;
1893                 }
1894
1895                 switch (*t) {
1896
1897                 case SD_BUS_TYPE_BYTE: {
1898                         uint8_t x;
1899
1900                         x = (uint8_t) va_arg(ap, int);
1901                         r = sd_bus_message_append_basic(m, *t, &x);
1902                         break;
1903                 }
1904
1905                 case SD_BUS_TYPE_BOOLEAN:
1906                 case SD_BUS_TYPE_INT32:
1907                 case SD_BUS_TYPE_UINT32:
1908                 case SD_BUS_TYPE_UNIX_FD: {
1909                         uint32_t x;
1910
1911                         /* We assume a boolean is the same as int32_t */
1912                         assert_cc(sizeof(int32_t) == sizeof(int));
1913
1914                         x = va_arg(ap, uint32_t);
1915                         r = sd_bus_message_append_basic(m, *t, &x);
1916                         break;
1917                 }
1918
1919                 case SD_BUS_TYPE_INT16:
1920                 case SD_BUS_TYPE_UINT16: {
1921                         uint16_t x;
1922
1923                         x = (uint16_t) va_arg(ap, int);
1924                         r = sd_bus_message_append_basic(m, *t, &x);
1925                         break;
1926                 }
1927
1928                 case SD_BUS_TYPE_INT64:
1929                 case SD_BUS_TYPE_UINT64:
1930                 case SD_BUS_TYPE_DOUBLE: {
1931                         uint64_t x;
1932
1933                         x = va_arg(ap, uint64_t);
1934                         r = sd_bus_message_append_basic(m, *t, &x);
1935                         break;
1936                 }
1937
1938                 case SD_BUS_TYPE_STRING:
1939                 case SD_BUS_TYPE_OBJECT_PATH:
1940                 case SD_BUS_TYPE_SIGNATURE: {
1941                         const char *x;
1942
1943                         x = va_arg(ap, const char*);
1944                         r = sd_bus_message_append_basic(m, *t, x);
1945                         break;
1946                 }
1947
1948                 case SD_BUS_TYPE_ARRAY: {
1949                         size_t k;
1950
1951                         r = signature_element_length(t + 1, &k);
1952                         if (r < 0)
1953                                 return r;
1954
1955                         {
1956                                 char s[k + 1];
1957                                 memcpy(s, t + 1, k);
1958                                 s[k] = 0;
1959
1960                                 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, s);
1961                                 if (r < 0)
1962                                         return r;
1963                         }
1964
1965                         if (n_array == (unsigned) -1) {
1966                                 types += k;
1967                                 n_struct -= k;
1968                         }
1969
1970                         r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
1971                         if (r < 0)
1972                                 return r;
1973
1974                         types = t + 1;
1975                         n_struct = k;
1976                         n_array = va_arg(ap, unsigned);
1977
1978                         break;
1979                 }
1980
1981                 case SD_BUS_TYPE_VARIANT: {
1982                         const char *s;
1983
1984                         s = va_arg(ap, const char*);
1985                         if (!s)
1986                                 return -EINVAL;
1987
1988                         r = sd_bus_message_open_container(m, SD_BUS_TYPE_VARIANT, s);
1989                         if (r < 0)
1990                                 return r;
1991
1992                         r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
1993                         if (r < 0)
1994                                 return r;
1995
1996                         types = s;
1997                         n_struct = strlen(s);
1998                         n_array = (unsigned) -1;
1999
2000                         break;
2001                 }
2002
2003                 case SD_BUS_TYPE_STRUCT_BEGIN:
2004                 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
2005                         size_t k;
2006
2007                         r = signature_element_length(t, &k);
2008                         if (r < 0)
2009                                 return r;
2010
2011                         {
2012                                 char s[k - 1];
2013
2014                                 memcpy(s, t + 1, k - 2);
2015                                 s[k - 2] = 0;
2016
2017                                 r = sd_bus_message_open_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
2018                                 if (r < 0)
2019                                         return r;
2020                         }
2021
2022                         if (n_array == (unsigned) -1) {
2023                                 types += k - 1;
2024                                 n_struct -= k - 1;
2025                         }
2026
2027                         r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2028                         if (r < 0)
2029                                 return r;
2030
2031                         types = t + 1;
2032                         n_struct = k - 2;
2033                         n_array = (unsigned) -1;
2034
2035                         break;
2036                 }
2037
2038                 default:
2039                         r = -EINVAL;
2040                 }
2041
2042                 if (r < 0)
2043                         return r;
2044         }
2045
2046         return 0;
2047 }
2048
2049 int sd_bus_message_append(sd_bus_message *m, const char *types, ...) {
2050         va_list ap;
2051         int r;
2052
2053         if (!m)
2054                 return -EINVAL;
2055         if (m->sealed)
2056                 return -EPERM;
2057         if (m->poisoned)
2058                 return -ESTALE;
2059         if (!types)
2060                 return 0;
2061
2062         va_start(ap, types);
2063         r = bus_message_append_ap(m, types, ap);
2064         va_end(ap);
2065
2066         return r;
2067 }
2068
2069 int sd_bus_message_append_array_space(sd_bus_message *m, char type, size_t size, void **ptr) {
2070         ssize_t align, sz;
2071         void *a;
2072         int r;
2073
2074         if (!m)
2075                 return -EINVAL;
2076         if (m->sealed)
2077                 return -EPERM;
2078         if (!bus_type_is_trivial(type))
2079                 return -EINVAL;
2080         if (!ptr && size > 0)
2081                 return -EINVAL;
2082         if (m->poisoned)
2083                 return -ESTALE;
2084
2085         align = bus_type_get_alignment(type);
2086         sz = bus_type_get_size(type);
2087
2088         assert_se(align > 0);
2089         assert_se(sz > 0);
2090
2091         if (size % sz != 0)
2092                 return -EINVAL;
2093
2094         r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
2095         if (r < 0)
2096                 return r;
2097
2098         a = message_extend_body(m, align, size);
2099         if (!a)
2100                 return -ENOMEM;
2101
2102         r = sd_bus_message_close_container(m);
2103         if (r < 0)
2104                 return r;
2105
2106         *ptr = a;
2107         return 0;
2108 }
2109
2110 int sd_bus_message_append_array(sd_bus_message *m, char type, const void *ptr, size_t size) {
2111         int r;
2112         void *p;
2113
2114         if (!ptr && size > 0)
2115                 return -EINVAL;
2116
2117         r = sd_bus_message_append_array_space(m, type, size, &p);
2118         if (r < 0)
2119                 return r;
2120
2121         if (size > 0)
2122                 memcpy(p, ptr, size);
2123
2124         return 0;
2125 }
2126
2127 int sd_bus_message_append_array_memfd(sd_bus_message *m, char type, sd_memfd *memfd) {
2128         _cleanup_close_ int copy_fd = -1;
2129         struct bus_body_part *part;
2130         ssize_t align, sz;
2131         uint64_t size;
2132         void *a;
2133         int r;
2134
2135         if (!m)
2136                 return -EINVAL;
2137         if (!memfd)
2138                 return -EINVAL;
2139         if (m->sealed)
2140                 return -EPERM;
2141         if (!bus_type_is_trivial(type))
2142                 return -EINVAL;
2143         if (m->poisoned)
2144                 return -ESTALE;
2145
2146         r = sd_memfd_set_sealed(memfd, true);
2147         if (r < 0)
2148                 return r;
2149
2150         copy_fd = sd_memfd_dup_fd(memfd);
2151         if (copy_fd < 0)
2152                 return copy_fd;
2153
2154         r = sd_memfd_get_size(memfd, &size);
2155         if (r < 0)
2156                 return r;
2157
2158         align = bus_type_get_alignment(type);
2159         sz = bus_type_get_size(type);
2160
2161         assert_se(align > 0);
2162         assert_se(sz > 0);
2163
2164         if (size % sz != 0)
2165                 return -EINVAL;
2166
2167         if (size > (uint64_t) (uint32_t) -1)
2168                 return -EINVAL;
2169
2170         r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
2171         if (r < 0)
2172                 return r;
2173
2174         a = message_extend_body(m, align, 0);
2175         if (!a)
2176                 return -ENOMEM;
2177
2178         part = message_append_part(m);
2179         if (!part)
2180                 return -ENOMEM;
2181
2182         part->memfd = copy_fd;
2183         part->sealed = true;
2184         part->size = size;
2185         copy_fd = -1;
2186
2187         message_extend_containers(m, size);
2188         m->header->body_size += size;
2189
2190         return sd_bus_message_close_container(m);
2191 }
2192
2193 int sd_bus_message_append_string_memfd(sd_bus_message *m, sd_memfd *memfd) {
2194         _cleanup_close_ int copy_fd = -1;
2195         struct bus_body_part *part;
2196         struct bus_container *c;
2197         uint64_t size;
2198         void *a;
2199         int r;
2200
2201         if (!m)
2202                 return -EINVAL;
2203         if (!memfd)
2204                 return -EINVAL;
2205         if (m->sealed)
2206                 return -EPERM;
2207         if (m->poisoned)
2208                 return -ESTALE;
2209
2210         r = sd_memfd_set_sealed(memfd, true);
2211         if (r < 0)
2212                 return r;
2213
2214         copy_fd = sd_memfd_dup_fd(memfd);
2215         if (copy_fd < 0)
2216                 return copy_fd;
2217
2218         r = sd_memfd_get_size(memfd, &size);
2219         if (r < 0)
2220                 return r;
2221
2222         /* We require this to be NUL terminated */
2223         if (size == 0)
2224                 return -EINVAL;
2225
2226         if (size > (uint64_t) (uint32_t) -1)
2227                 return -EINVAL;
2228
2229         c = message_get_container(m);
2230         if (c->signature && c->signature[c->index]) {
2231                 /* Container signature is already set */
2232
2233                 if (c->signature[c->index] != SD_BUS_TYPE_STRING)
2234                         return -ENXIO;
2235         } else {
2236                 char *e;
2237
2238                 /* Maybe we can append to the signature? But only if this is the top-level container*/
2239                 if (c->enclosing != 0)
2240                         return -ENXIO;
2241
2242                 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRING), NULL);
2243                 if (!e) {
2244                         m->poisoned = true;
2245                         return -ENOMEM;
2246                 }
2247         }
2248
2249         a = message_extend_body(m, 4, 4);
2250         if (!a)
2251                 return -ENOMEM;
2252
2253         *(uint32_t*) a = size - 1;
2254
2255         part = message_append_part(m);
2256         if (!part)
2257                 return -ENOMEM;
2258
2259         part->memfd = copy_fd;
2260         part->sealed = true;
2261         part->size = size;
2262         copy_fd = -1;
2263
2264         message_extend_containers(m, size);
2265         m->header->body_size += size;
2266
2267         if (c->enclosing != SD_BUS_TYPE_ARRAY)
2268                 c->index++;
2269
2270         return 0;
2271 }
2272
2273 int bus_body_part_map(struct bus_body_part *part) {
2274         void *p;
2275         size_t psz;
2276
2277         assert_se(part);
2278
2279         if (part->data)
2280                 return 0;
2281
2282         if (part->size <= 0)
2283                 return 0;
2284
2285         /* For smaller zero parts (as used for padding) we don't need to map anything... */
2286         if (part->memfd < 0 && part->is_zero && part->size < 8) {
2287                 static const uint8_t zeroes[7] = { };
2288                 part->data = (void*) zeroes;
2289                 return 0;
2290         }
2291
2292         psz = PAGE_ALIGN(part->size);
2293
2294         if (part->memfd >= 0)
2295                 p = mmap(NULL, psz, PROT_READ, MAP_SHARED, part->memfd, 0);
2296         else if (part->is_zero)
2297                 p = mmap(NULL, psz, PROT_READ, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
2298         else
2299                 return -EINVAL;
2300
2301         if (p == MAP_FAILED)
2302                 return -errno;
2303
2304         part->mapped = psz;
2305         part->data = p;
2306         part->munmap_this = true;
2307
2308         return 0;
2309 }
2310
2311 void bus_body_part_unmap(struct bus_body_part *part) {
2312
2313         assert_se(part);
2314
2315         if (part->memfd < 0)
2316                 return;
2317
2318         if (!part->data)
2319                 return;
2320
2321         if (!part->munmap_this)
2322                 return;
2323
2324         assert_se(munmap(part->data, part->mapped) == 0);
2325
2326         part->data = NULL;
2327         part->mapped = 0;
2328         part->munmap_this = false;
2329
2330         return;
2331 }
2332
2333 static int buffer_peek(const void *p, uint32_t sz, size_t *rindex, size_t align, size_t nbytes, void **r) {
2334         size_t k, start, end;
2335
2336         assert(rindex);
2337         assert(align > 0);
2338
2339         start = ALIGN_TO((size_t) *rindex, align);
2340         end = start + nbytes;
2341
2342         if (end > sz)
2343                 return -EBADMSG;
2344
2345         /* Verify that padding is 0 */
2346         for (k = *rindex; k < start; k++)
2347                 if (((const uint8_t*) p)[k] != 0)
2348                         return -EBADMSG;
2349
2350         if (r)
2351                 *r = (uint8_t*) p + start;
2352
2353         *rindex = end;
2354
2355         return 1;
2356 }
2357
2358 static bool message_end_of_array(sd_bus_message *m, size_t index) {
2359         struct bus_container *c;
2360
2361         assert(m);
2362
2363         c = message_get_container(m);
2364         if (!c->array_size)
2365                 return false;
2366
2367         return index >= c->begin + BUS_MESSAGE_BSWAP32(m, *c->array_size);
2368 }
2369
2370 static struct bus_body_part* find_part(sd_bus_message *m, size_t index, size_t sz, void **p) {
2371         struct bus_body_part *part;
2372         size_t begin;
2373         int r;
2374
2375         assert(m);
2376
2377         if (m->cached_rindex_part && index >= m->cached_rindex_part_begin) {
2378                 part = m->cached_rindex_part;
2379                 begin = m->cached_rindex_part_begin;
2380         } else {
2381                 part = &m->body;
2382                 begin = 0;
2383         }
2384
2385         while (part) {
2386                 if (index < begin)
2387                         return NULL;
2388
2389                 if (index + sz <= begin + part->size) {
2390
2391                         r = bus_body_part_map(part);
2392                         if (r < 0)
2393                                 return NULL;
2394
2395                         if (p)
2396                                 *p = (uint8_t*) part->data + index - begin;
2397
2398                         m->cached_rindex_part = part;
2399                         m->cached_rindex_part_begin = begin;
2400
2401                         return part;
2402                 }
2403
2404                 begin += part->size;
2405                 part = part->next;
2406         }
2407
2408         return NULL;
2409 }
2410
2411 static int message_peek_body(
2412                 sd_bus_message *m,
2413                 size_t *rindex,
2414                 size_t align,
2415                 size_t nbytes,
2416                 void **ret) {
2417
2418         size_t k, start, end, padding;
2419         struct bus_body_part *part;
2420         uint8_t *q;
2421
2422         assert(m);
2423         assert(rindex);
2424         assert(align > 0);
2425
2426         if (message_end_of_array(m, *rindex))
2427                 return 0;
2428
2429         start = ALIGN_TO((size_t) *rindex, align);
2430         padding = start - *rindex;
2431         end = start + nbytes;
2432
2433         if (end > BUS_MESSAGE_BODY_SIZE(m))
2434                 return -EBADMSG;
2435
2436         part = find_part(m, *rindex, padding, (void**) &q);
2437         if (!part)
2438                 return -EBADMSG;
2439
2440         if (q) {
2441                 /* Verify padding */
2442                 for (k = 0; k < padding; k++)
2443                         if (q[k] != 0)
2444                                 return -EBADMSG;
2445         }
2446
2447         part = find_part(m, start, nbytes, (void**) &q);
2448         if (!part || !q)
2449                 return -EBADMSG;
2450
2451         *rindex = end;
2452
2453         if (ret)
2454                 *ret = q;
2455
2456         return 1;
2457 }
2458
2459 static bool validate_nul(const char *s, size_t l) {
2460
2461         /* Check for NUL chars in the string */
2462         if (memchr(s, 0, l))
2463                 return false;
2464
2465         /* Check for NUL termination */
2466         if (s[l] != 0)
2467                 return false;
2468
2469         return true;
2470 }
2471
2472 static bool validate_string(const char *s, size_t l) {
2473
2474         if (!validate_nul(s, l))
2475                 return false;
2476
2477         /* Check if valid UTF8 */
2478         if (!utf8_is_valid(s))
2479                 return false;
2480
2481         return true;
2482 }
2483
2484 static bool validate_signature(const char *s, size_t l) {
2485
2486         if (!validate_nul(s, l))
2487                 return false;
2488
2489         /* Check if valid signature */
2490         if (!signature_is_valid(s, true))
2491                 return false;
2492
2493         return true;
2494 }
2495
2496 static bool validate_object_path(const char *s, size_t l) {
2497
2498         if (!validate_nul(s, l))
2499                 return false;
2500
2501         if (!object_path_is_valid(s))
2502                 return false;
2503
2504         return true;
2505 }
2506
2507 int sd_bus_message_read_basic(sd_bus_message *m, char type, void *p) {
2508         struct bus_container *c;
2509         int r;
2510         void *q;
2511
2512         if (!m)
2513                 return -EINVAL;
2514         if (!m->sealed)
2515                 return -EPERM;
2516         if (!bus_type_is_basic(type))
2517                 return -EINVAL;
2518         if (!p)
2519                 return -EINVAL;
2520
2521         c = message_get_container(m);
2522
2523         if (!c->signature || c->signature[c->index] == 0)
2524                 return 0;
2525
2526         if (c->signature[c->index] != type)
2527                 return -ENXIO;
2528
2529         switch (type) {
2530
2531         case SD_BUS_TYPE_STRING:
2532         case SD_BUS_TYPE_OBJECT_PATH: {
2533                 uint32_t l;
2534                 size_t rindex;
2535
2536                 rindex = m->rindex;
2537                 r = message_peek_body(m, &rindex, 4, 4, &q);
2538                 if (r <= 0)
2539                         return r;
2540
2541                 l = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2542                 r = message_peek_body(m, &rindex, 1, l+1, &q);
2543                 if (r < 0)
2544                         return r;
2545                 if (r == 0)
2546                         return -EBADMSG;
2547
2548                 if (type == SD_BUS_TYPE_OBJECT_PATH) {
2549                         if (!validate_object_path(q, l))
2550                                 return -EBADMSG;
2551                 } else {
2552                         if (!validate_string(q, l))
2553                                 return -EBADMSG;
2554                 }
2555
2556                 m->rindex = rindex;
2557                 *(const char**) p = q;
2558                 break;
2559         }
2560
2561         case SD_BUS_TYPE_SIGNATURE: {
2562                 uint8_t l;
2563                 size_t rindex;
2564
2565                 rindex = m->rindex;
2566                 r = message_peek_body(m, &rindex, 1, 1, &q);
2567                 if (r <= 0)
2568                         return r;
2569
2570                 l = *(uint8_t*) q;
2571                 r = message_peek_body(m, &rindex, 1, l+1, &q);
2572                 if (r < 0)
2573                         return r;
2574                 if (r == 0)
2575                         return -EBADMSG;
2576
2577                 if (!validate_signature(q, l))
2578                         return -EBADMSG;
2579
2580                 m->rindex = rindex;
2581                 *(const char**) p = q;
2582                 break;
2583         }
2584
2585         default: {
2586                 ssize_t sz, align;
2587                 size_t rindex;
2588
2589                 align = bus_type_get_alignment(type);
2590                 sz = bus_type_get_size(type);
2591                 assert(align > 0 && sz > 0);
2592
2593                 rindex = m->rindex;
2594                 r = message_peek_body(m, &rindex, align, sz, &q);
2595                 if (r <= 0)
2596                         return r;
2597
2598                 switch (type) {
2599
2600                 case SD_BUS_TYPE_BYTE:
2601                         *(uint8_t*) p = *(uint8_t*) q;
2602                         break;
2603
2604                 case SD_BUS_TYPE_BOOLEAN:
2605                         *(int*) p = !!*(uint32_t*) q;
2606                         break;
2607
2608                 case SD_BUS_TYPE_INT16:
2609                 case SD_BUS_TYPE_UINT16:
2610                         *(uint16_t*) p = BUS_MESSAGE_BSWAP16(m, *(uint16_t*) q);
2611                         break;
2612
2613                 case SD_BUS_TYPE_INT32:
2614                 case SD_BUS_TYPE_UINT32:
2615                         *(uint32_t*) p = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2616                         break;
2617
2618                 case SD_BUS_TYPE_INT64:
2619                 case SD_BUS_TYPE_UINT64:
2620                 case SD_BUS_TYPE_DOUBLE:
2621                         *(uint64_t*) p = BUS_MESSAGE_BSWAP64(m, *(uint64_t*) q);
2622                         break;
2623
2624                 case SD_BUS_TYPE_UNIX_FD: {
2625                         uint32_t j;
2626
2627                         j = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2628                         if (j >= m->n_fds)
2629                                 return -EBADMSG;
2630
2631                         *(int*) p = m->fds[j];
2632                         break;
2633                 }
2634
2635                 default:
2636                         assert_not_reached("Unknown basic type...");
2637                 }
2638
2639                 m->rindex = rindex;
2640
2641                 break;
2642         }
2643         }
2644
2645         if (c->enclosing != SD_BUS_TYPE_ARRAY)
2646                 c->index++;
2647
2648         return 1;
2649 }
2650
2651 static int bus_message_enter_array(
2652                 sd_bus_message *m,
2653                 struct bus_container *c,
2654                 const char *contents,
2655                 uint32_t **array_size) {
2656
2657         size_t rindex;
2658         void *q;
2659         int r, alignment;
2660
2661         assert(m);
2662         assert(c);
2663         assert(contents);
2664         assert(array_size);
2665
2666         if (!signature_is_single(contents))
2667                 return -EINVAL;
2668
2669         alignment = bus_type_get_alignment(contents[0]);
2670         if (alignment < 0)
2671                 return alignment;
2672
2673         if (!c->signature || c->signature[c->index] == 0)
2674                 return 0;
2675
2676         if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
2677                 return -ENXIO;
2678
2679         if (!startswith(c->signature + c->index + 1, contents))
2680                 return -ENXIO;
2681
2682         rindex = m->rindex;
2683         r = message_peek_body(m, &rindex, 4, 4, &q);
2684         if (r <= 0)
2685                 return r;
2686
2687         if (BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q) > BUS_ARRAY_MAX_SIZE)
2688                 return -EBADMSG;
2689
2690         r = message_peek_body(m, &rindex, alignment, 0, NULL);
2691         if (r < 0)
2692                 return r;
2693         if (r == 0)
2694                 return -EBADMSG;
2695
2696         if (c->enclosing != SD_BUS_TYPE_ARRAY)
2697                 c->index += 1 + strlen(contents);
2698
2699         m->rindex = rindex;
2700
2701         *array_size = (uint32_t*) q;
2702
2703         return 1;
2704 }
2705
2706 static int bus_message_enter_variant(
2707                 sd_bus_message *m,
2708                 struct bus_container *c,
2709                 const char *contents) {
2710
2711         size_t rindex;
2712         uint8_t l;
2713         void *q;
2714         int r;
2715
2716         assert(m);
2717         assert(c);
2718         assert(contents);
2719
2720         if (!signature_is_single(contents))
2721                 return -EINVAL;
2722
2723         if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
2724                 return -EINVAL;
2725
2726         if (!c->signature || c->signature[c->index] == 0)
2727                 return 0;
2728
2729         if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
2730                 return -ENXIO;
2731
2732         rindex = m->rindex;
2733         r = message_peek_body(m, &rindex, 1, 1, &q);
2734         if (r <= 0)
2735                 return r;
2736
2737         l = *(uint8_t*) q;
2738         r = message_peek_body(m, &rindex, 1, l+1, &q);
2739         if (r < 0)
2740                 return r;
2741         if (r == 0)
2742                 return -EBADMSG;
2743
2744         if (!validate_signature(q, l))
2745                 return -EBADMSG;
2746
2747         if (!streq(q, contents))
2748                 return -ENXIO;
2749
2750         if (c->enclosing != SD_BUS_TYPE_ARRAY)
2751                 c->index++;
2752
2753         m->rindex = rindex;
2754
2755         return 1;
2756 }
2757
2758 static int bus_message_enter_struct(
2759                 sd_bus_message *m,
2760                 struct bus_container *c,
2761                 const char *contents) {
2762
2763         size_t l;
2764         int r;
2765
2766         assert(m);
2767         assert(c);
2768         assert(contents);
2769
2770         if (!signature_is_valid(contents, false))
2771                 return -EINVAL;
2772
2773         if (!c->signature || c->signature[c->index] == 0)
2774                 return 0;
2775
2776         l = strlen(contents);
2777
2778         if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
2779             !startswith(c->signature + c->index + 1, contents) ||
2780             c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
2781                 return -ENXIO;
2782
2783         r = message_peek_body(m, &m->rindex, 8, 0, NULL);
2784         if (r <= 0)
2785                 return r;
2786
2787         if (c->enclosing != SD_BUS_TYPE_ARRAY)
2788                 c->index += 1 + l + 1;
2789
2790         return 1;
2791 }
2792
2793 static int bus_message_enter_dict_entry(
2794                 sd_bus_message *m,
2795                 struct bus_container *c,
2796                 const char *contents) {
2797
2798         size_t l;
2799         int r;
2800
2801         assert(m);
2802         assert(c);
2803         assert(contents);
2804
2805         if (!signature_is_pair(contents))
2806                 return -EINVAL;
2807
2808         if (c->enclosing != SD_BUS_TYPE_ARRAY)
2809                 return -ENXIO;
2810
2811         if (!c->signature || c->signature[c->index] == 0)
2812                 return 0;
2813
2814         l = strlen(contents);
2815
2816         if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
2817             !startswith(c->signature + c->index + 1, contents) ||
2818             c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
2819                 return -ENXIO;
2820
2821         r = message_peek_body(m, &m->rindex, 8, 0, NULL);
2822         if (r <= 0)
2823                 return r;
2824
2825         if (c->enclosing != SD_BUS_TYPE_ARRAY)
2826                 c->index += 1 + l + 1;
2827
2828         return 1;
2829 }
2830
2831 int sd_bus_message_enter_container(sd_bus_message *m, char type, const char *contents) {
2832         struct bus_container *c, *w;
2833         uint32_t *array_size = NULL;
2834         char *signature;
2835         size_t before;
2836         int r;
2837
2838         if (!m)
2839                 return -EINVAL;
2840         if (!m->sealed)
2841                 return -EPERM;
2842         if (!contents)
2843                 return -EINVAL;
2844
2845         /*
2846          * We enforce a global limit on container depth, that is much
2847          * higher than the 32 structs and 32 arrays the specification
2848          * mandates. This is simpler to implement for us, and we need
2849          * this only to ensure our container array doesn't grow
2850          * without bounds. We are happy to return any data from a
2851          * message as long as the data itself is valid, even if the
2852          * overall message might be not.
2853          *
2854          * Note that the message signature is validated when
2855          * parsing the headers, and that validation does check the
2856          * 32/32 limit.
2857          *
2858          * Note that the specification defines no limits on the depth
2859          * of stacked variants, but we do.
2860          */
2861         if (m->n_containers >= BUS_CONTAINER_DEPTH)
2862                 return -EBADMSG;
2863
2864         w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
2865         if (!w)
2866                 return -ENOMEM;
2867         m->containers = w;
2868
2869         c = message_get_container(m);
2870
2871         if (!c->signature || c->signature[c->index] == 0)
2872                 return 0;
2873
2874         signature = strdup(contents);
2875         if (!signature)
2876                 return -ENOMEM;
2877
2878         c->saved_index = c->index;
2879         before = m->rindex;
2880
2881         if (type == SD_BUS_TYPE_ARRAY)
2882                 r = bus_message_enter_array(m, c, contents, &array_size);
2883         else if (type == SD_BUS_TYPE_VARIANT)
2884                 r = bus_message_enter_variant(m, c, contents);
2885         else if (type == SD_BUS_TYPE_STRUCT)
2886                 r = bus_message_enter_struct(m, c, contents);
2887         else if (type == SD_BUS_TYPE_DICT_ENTRY)
2888                 r = bus_message_enter_dict_entry(m, c, contents);
2889         else
2890                 r = -EINVAL;
2891
2892         if (r <= 0) {
2893                 free(signature);
2894                 return r;
2895         }
2896
2897         /* OK, let's fill it in */
2898         w += m->n_containers++;
2899         w->enclosing = type;
2900         w->signature = signature;
2901         w->index = 0;
2902         w->array_size = array_size;
2903         w->before = before;
2904         w->begin = m->rindex;
2905
2906         return 1;
2907 }
2908
2909 int sd_bus_message_exit_container(sd_bus_message *m) {
2910         struct bus_container *c;
2911
2912         if (!m)
2913                 return -EINVAL;
2914         if (!m->sealed)
2915                 return -EPERM;
2916         if (m->n_containers <= 0)
2917                 return -EINVAL;
2918
2919         c = message_get_container(m);
2920         if (c->enclosing == SD_BUS_TYPE_ARRAY) {
2921                 uint32_t l;
2922
2923                 l = BUS_MESSAGE_BSWAP32(m, *c->array_size);
2924                 if (c->begin + l != m->rindex)
2925                         return -EBUSY;
2926
2927         } else {
2928                 if (c->signature && c->signature[c->index] != 0)
2929                         return -EINVAL;
2930         }
2931
2932         free(c->signature);
2933         m->n_containers--;
2934
2935         return 1;
2936 }
2937
2938 static void message_quit_container(sd_bus_message *m) {
2939         struct bus_container *c;
2940
2941         assert(m);
2942         assert(m->sealed);
2943         assert(m->n_containers > 0);
2944
2945         c = message_get_container(m);
2946
2947         /* Undo seeks */
2948         assert(m->rindex >= c->before);
2949         m->rindex = c->before;
2950
2951         /* Free container */
2952         free(c->signature);
2953         m->n_containers--;
2954
2955         /* Correct index of new top-level container */
2956         c = message_get_container(m);
2957         c->index = c->saved_index;
2958 }
2959
2960 int sd_bus_message_peek_type(sd_bus_message *m, char *type, const char **contents) {
2961         struct bus_container *c;
2962         int r;
2963
2964         if (!m)
2965                 return -EINVAL;
2966         if (!m->sealed)
2967                 return -EPERM;
2968
2969         c = message_get_container(m);
2970
2971         if (!c->signature || c->signature[c->index] == 0)
2972                 goto eof;
2973
2974         if (message_end_of_array(m, m->rindex))
2975                 goto eof;
2976
2977         if (bus_type_is_basic(c->signature[c->index])) {
2978                 if (contents)
2979                         *contents = NULL;
2980                 if (type)
2981                         *type = c->signature[c->index];
2982                 return 1;
2983         }
2984
2985         if (c->signature[c->index] == SD_BUS_TYPE_ARRAY) {
2986
2987                 if (contents) {
2988                         size_t l;
2989                         char *sig;
2990
2991                         r = signature_element_length(c->signature+c->index+1, &l);
2992                         if (r < 0)
2993                                 return r;
2994
2995                         assert(l >= 1);
2996
2997                         sig = strndup(c->signature + c->index + 1, l);
2998                         if (!sig)
2999                                 return -ENOMEM;
3000
3001                         free(m->peeked_signature);
3002                         m->peeked_signature = sig;
3003
3004                         *contents = sig;
3005                 }
3006
3007                 if (type)
3008                         *type = SD_BUS_TYPE_ARRAY;
3009
3010                 return 1;
3011         }
3012
3013         if (c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ||
3014             c->signature[c->index] == SD_BUS_TYPE_DICT_ENTRY_BEGIN) {
3015
3016                 if (contents) {
3017                         size_t l;
3018                         char *sig;
3019
3020                         r = signature_element_length(c->signature+c->index, &l);
3021                         if (r < 0)
3022                                 return r;
3023
3024                         assert(l >= 2);
3025                         sig = strndup(c->signature + c->index + 1, l - 2);
3026                         if (!sig)
3027                                 return -ENOMEM;
3028
3029                         free(m->peeked_signature);
3030                         m->peeked_signature = sig;
3031
3032                         *contents = sig;
3033                 }
3034
3035                 if (type)
3036                         *type = c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY;
3037
3038                 return 1;
3039         }
3040
3041         if (c->signature[c->index] == SD_BUS_TYPE_VARIANT) {
3042                 if (contents) {
3043                         size_t rindex, l;
3044                         void *q;
3045
3046                         rindex = m->rindex;
3047                         r = message_peek_body(m, &rindex, 1, 1, &q);
3048                         if (r < 0)
3049                                 return r;
3050                         if (r == 0)
3051                                 goto eof;
3052
3053                         l = *(uint8_t*) q;
3054                         r = message_peek_body(m, &rindex, 1, l+1, &q);
3055                         if (r < 0)
3056                                 return r;
3057                         if (r == 0)
3058                                 return -EBADMSG;
3059
3060                         if (!validate_signature(q, l))
3061                                 return -EBADMSG;
3062
3063                         *contents = q;
3064                 }
3065
3066                 if (type)
3067                         *type = SD_BUS_TYPE_VARIANT;
3068
3069                 return 1;
3070         }
3071
3072         return -EINVAL;
3073
3074 eof:
3075         if (type)
3076                 *type = c->enclosing;
3077         if (contents)
3078                 *contents = NULL;
3079         return 0;
3080 }
3081
3082 int sd_bus_message_rewind(sd_bus_message *m, int complete) {
3083         struct bus_container *c;
3084
3085         if (!m)
3086                 return -EINVAL;
3087         if (!m->sealed)
3088                 return -EPERM;
3089
3090         if (complete) {
3091                 message_reset_containers(m);
3092                 m->rindex = 0;
3093                 m->root_container.index = 0;
3094
3095                 c = message_get_container(m);
3096         } else {
3097                 c = message_get_container(m);
3098
3099                 c->index = 0;
3100                 m->rindex = c->begin;
3101         }
3102
3103         return !isempty(c->signature);
3104 }
3105 static int message_read_ap(
3106                 sd_bus_message *m,
3107                 const char *types,
3108                 va_list ap) {
3109
3110         unsigned n_array, n_struct;
3111         TypeStack stack[BUS_CONTAINER_DEPTH];
3112         unsigned stack_ptr = 0;
3113         int r;
3114
3115         assert(m);
3116
3117         if (!types)
3118                 return 0;
3119
3120         /* Ideally, we'd just call ourselves recursively on every
3121          * complex type. However, the state of a va_list that is
3122          * passed to a function is undefined after that function
3123          * returns. This means we need to docode the va_list linearly
3124          * in a single stackframe. We hence implement our own
3125          * home-grown stack in an array. */
3126
3127         n_array = (unsigned) -1;
3128         n_struct = strlen(types);
3129
3130         for (;;) {
3131                 const char *t;
3132
3133                 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
3134                         r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
3135                         if (r < 0)
3136                                 return r;
3137                         if (r == 0)
3138                                 break;
3139
3140                         r = sd_bus_message_exit_container(m);
3141                         if (r < 0)
3142                                 return r;
3143
3144                         continue;
3145                 }
3146
3147                 t = types;
3148                 if (n_array != (unsigned) -1)
3149                         n_array --;
3150                 else {
3151                         types ++;
3152                         n_struct--;
3153                 }
3154
3155                 switch (*t) {
3156
3157                 case SD_BUS_TYPE_BYTE:
3158                 case SD_BUS_TYPE_BOOLEAN:
3159                 case SD_BUS_TYPE_INT16:
3160                 case SD_BUS_TYPE_UINT16:
3161                 case SD_BUS_TYPE_INT32:
3162                 case SD_BUS_TYPE_UINT32:
3163                 case SD_BUS_TYPE_INT64:
3164                 case SD_BUS_TYPE_UINT64:
3165                 case SD_BUS_TYPE_DOUBLE:
3166                 case SD_BUS_TYPE_STRING:
3167                 case SD_BUS_TYPE_OBJECT_PATH:
3168                 case SD_BUS_TYPE_SIGNATURE:
3169                 case SD_BUS_TYPE_UNIX_FD: {
3170                         void *p;
3171
3172                         p = va_arg(ap, void*);
3173                         r = sd_bus_message_read_basic(m, *t, p);
3174                         if (r < 0)
3175                                 return r;
3176                         if (r == 0)
3177                                 return -ENXIO;
3178
3179                         break;
3180                 }
3181
3182                 case SD_BUS_TYPE_ARRAY: {
3183                         size_t k;
3184
3185                         r = signature_element_length(t + 1, &k);
3186                         if (r < 0)
3187                                 return r;
3188
3189                         {
3190                                 char s[k + 1];
3191                                 memcpy(s, t + 1, k);
3192                                 s[k] = 0;
3193
3194                                 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, s);
3195                                 if (r < 0)
3196                                         return r;
3197                                 if (r == 0)
3198                                         return -ENXIO;
3199                         }
3200
3201                         if (n_array == (unsigned) -1) {
3202                                 types += k;
3203                                 n_struct -= k;
3204                         }
3205
3206                         r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
3207                         if (r < 0)
3208                                 return r;
3209
3210                         types = t + 1;
3211                         n_struct = k;
3212                         n_array = va_arg(ap, unsigned);
3213
3214                         break;
3215                 }
3216
3217                 case SD_BUS_TYPE_VARIANT: {
3218                         const char *s;
3219
3220                         s = va_arg(ap, const char *);
3221                         if (!s)
3222                                 return -EINVAL;
3223
3224                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, s);
3225                         if (r < 0)
3226                                 return r;
3227                         if (r == 0)
3228                                 return -ENXIO;
3229
3230                         r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
3231                         if (r < 0)
3232                                 return r;
3233
3234                         types = s;
3235                         n_struct = strlen(s);
3236                         n_array = (unsigned) -1;
3237
3238                         break;
3239                 }
3240
3241                 case SD_BUS_TYPE_STRUCT_BEGIN:
3242                 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
3243                         size_t k;
3244
3245                         r = signature_element_length(t, &k);
3246                         if (r < 0)
3247                                 return r;
3248
3249                         {
3250                                 char s[k - 1];
3251                                 memcpy(s, t + 1, k - 2);
3252                                 s[k - 2] = 0;
3253
3254                                 r = sd_bus_message_enter_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
3255                                 if (r < 0)
3256                                         return r;
3257                                 if (r == 0)
3258                                         return -ENXIO;
3259                         }
3260
3261                         if (n_array == (unsigned) -1) {
3262                                 types += k - 1;
3263                                 n_struct -= k - 1;
3264                         }
3265
3266                         r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
3267                         if (r < 0)
3268                                 return r;
3269
3270                         types = t + 1;
3271                         n_struct = k - 2;
3272                         n_array = (unsigned) -1;
3273
3274                         break;
3275                 }
3276
3277                 default:
3278                         return -EINVAL;
3279                 }
3280         }
3281
3282         return 1;
3283 }
3284
3285 int sd_bus_message_read(sd_bus_message *m, const char *types, ...) {
3286         va_list ap;
3287         int r;
3288
3289         if (!m)
3290                 return -EINVAL;
3291         if (!m->sealed)
3292                 return -EPERM;
3293         if (!types)
3294                 return -EINVAL;
3295
3296         va_start(ap, types);
3297         r = message_read_ap(m, types, ap);
3298         va_end(ap);
3299
3300         return r;
3301 }
3302
3303 int sd_bus_message_read_array(sd_bus_message *m, char type, const void **ptr, size_t *size) {
3304         struct bus_container *c;
3305         void *p;
3306         size_t sz;
3307         ssize_t align;
3308         int r;
3309
3310         if (!m)
3311                 return -EINVAL;
3312         if (!m->sealed)
3313                 return -EPERM;
3314         if (!bus_type_is_trivial(type))
3315                 return -EINVAL;
3316         if (!ptr)
3317                 return -EINVAL;
3318         if (!size)
3319                 return -EINVAL;
3320         if (BUS_MESSAGE_NEED_BSWAP(m))
3321                 return -ENOTSUP;
3322
3323         align = bus_type_get_alignment(type);
3324         if (align < 0)
3325                 return align;
3326
3327         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
3328         if (r <= 0)
3329                 return r;
3330
3331         c = message_get_container(m);
3332         sz = BUS_MESSAGE_BSWAP32(m, *c->array_size);
3333
3334         r = message_peek_body(m, &m->rindex, align, sz, &p);
3335         if (r < 0)
3336                 goto fail;
3337         if (r == 0) {
3338                 r = -EBADMSG;
3339                 goto fail;
3340         }
3341
3342         r = sd_bus_message_exit_container(m);
3343         if (r < 0)
3344                 goto fail;
3345
3346         *ptr = (const void*) p;
3347         *size = sz;
3348
3349         return 1;
3350
3351 fail:
3352         message_quit_container(m);
3353         return r;
3354 }
3355
3356 static int message_peek_fields(
3357                 sd_bus_message *m,
3358                 size_t *rindex,
3359                 size_t align,
3360                 size_t nbytes,
3361                 void **ret) {
3362
3363         assert(m);
3364         assert(rindex);
3365         assert(align > 0);
3366
3367         return buffer_peek(BUS_MESSAGE_FIELDS(m), BUS_MESSAGE_FIELDS_SIZE(m), rindex, align, nbytes, ret);
3368 }
3369
3370 static int message_peek_field_uint32(
3371                 sd_bus_message *m,
3372                 size_t *ri,
3373                 uint32_t *ret) {
3374
3375         int r;
3376         void *q;
3377
3378         assert(m);
3379         assert(ri);
3380
3381         r = message_peek_fields(m, ri, 4, 4, &q);
3382         if (r < 0)
3383                 return r;
3384
3385         if (ret)
3386                 *ret = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
3387
3388         return 0;
3389 }
3390
3391 static int message_peek_field_string(
3392                 sd_bus_message *m,
3393                 bool (*validate)(const char *p),
3394                 size_t *ri,
3395                 const char **ret) {
3396
3397         uint32_t l;
3398         int r;
3399         void *q;
3400
3401         assert(m);
3402         assert(ri);
3403
3404         r = message_peek_field_uint32(m, ri, &l);
3405         if (r < 0)
3406                 return r;
3407
3408         r = message_peek_fields(m, ri, 1, l+1, &q);
3409         if (r < 0)
3410                 return r;
3411
3412         if (validate) {
3413                 if (!validate_nul(q, l))
3414                         return -EBADMSG;
3415
3416                 if (!validate(q))
3417                         return -EBADMSG;
3418         } else {
3419                 if (!validate_string(q, l))
3420                         return -EBADMSG;
3421         }
3422
3423         if (ret)
3424                 *ret = q;
3425
3426         return 0;
3427 }
3428
3429 static int message_peek_field_signature(
3430                 sd_bus_message *m,
3431                 size_t *ri,
3432                 const char **ret) {
3433
3434         size_t l;
3435         int r;
3436         void *q;
3437
3438         assert(m);
3439         assert(ri);
3440
3441         r = message_peek_fields(m, ri, 1, 1, &q);
3442         if (r < 0)
3443                 return r;
3444
3445         l = *(uint8_t*) q;
3446         r = message_peek_fields(m, ri, 1, l+1, &q);
3447         if (r < 0)
3448                 return r;
3449
3450         if (!validate_signature(q, l))
3451                 return -EBADMSG;
3452
3453         if (ret)
3454                 *ret = q;
3455
3456         return 0;
3457 }
3458
3459 static int message_skip_fields(
3460                 sd_bus_message *m,
3461                 size_t *ri,
3462                 uint32_t array_size,
3463                 const char **signature) {
3464
3465         size_t original_index;
3466         int r;
3467
3468         assert(m);
3469         assert(ri);
3470         assert(signature);
3471
3472         original_index = *ri;
3473
3474         for (;;) {
3475                 char t;
3476                 size_t l;
3477
3478                 if (array_size != (uint32_t) -1 &&
3479                     array_size <= *ri - original_index)
3480                         return 0;
3481
3482                 t = **signature;
3483                 if (!t)
3484                         return 0;
3485
3486                 if (t == SD_BUS_TYPE_STRING) {
3487
3488                         r = message_peek_field_string(m, NULL, ri, NULL);
3489                         if (r < 0)
3490                                 return r;
3491
3492                         (*signature)++;
3493
3494                 } else if (t == SD_BUS_TYPE_OBJECT_PATH) {
3495
3496                         r = message_peek_field_string(m, object_path_is_valid, ri, NULL);
3497                         if (r < 0)
3498                                 return r;
3499
3500                         (*signature)++;
3501
3502                 } else if (t == SD_BUS_TYPE_SIGNATURE) {
3503
3504                         r = message_peek_field_signature(m, ri, NULL);
3505                         if (r < 0)
3506                                 return r;
3507
3508                         (*signature)++;
3509
3510                 } else if (bus_type_is_basic(t)) {
3511                         ssize_t align, k;
3512
3513                         align = bus_type_get_alignment(t);
3514                         k = bus_type_get_size(t);
3515                         assert(align > 0 && k > 0);
3516
3517                         r = message_peek_fields(m, ri, align, k, NULL);
3518                         if (r < 0)
3519                                 return r;
3520
3521                         (*signature)++;
3522
3523                 } else if (t == SD_BUS_TYPE_ARRAY) {
3524
3525                         r = signature_element_length(*signature+1, &l);
3526                         if (r < 0)
3527                                 return r;
3528
3529                         assert(l >= 1);
3530                         {
3531                                 char sig[l-1], *s;
3532                                 uint32_t nas;
3533                                 int alignment;
3534
3535                                 strncpy(sig, *signature + 1, l-1);
3536                                 s = sig;
3537
3538                                 alignment = bus_type_get_alignment(sig[0]);
3539                                 if (alignment < 0)
3540                                         return alignment;
3541
3542                                 r = message_peek_field_uint32(m, ri, &nas);
3543                                 if (r < 0)
3544                                         return r;
3545                                 if (nas > BUS_ARRAY_MAX_SIZE)
3546                                         return -EBADMSG;
3547
3548                                 r = message_peek_fields(m, ri, alignment, 0, NULL);
3549                                 if (r < 0)
3550                                         return r;
3551
3552                                 r = message_skip_fields(m, ri, nas, (const char**) &s);
3553                                 if (r < 0)
3554                                         return r;
3555                         }
3556
3557                         (*signature) += 1 + l;
3558
3559                 } else if (t == SD_BUS_TYPE_VARIANT) {
3560                         const char *s;
3561
3562                         r = message_peek_field_signature(m, ri, &s);
3563                         if (r < 0)
3564                                 return r;
3565
3566                         r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
3567                         if (r < 0)
3568                                 return r;
3569
3570                         (*signature)++;
3571
3572                 } else if (t == SD_BUS_TYPE_STRUCT ||
3573                            t == SD_BUS_TYPE_DICT_ENTRY) {
3574
3575                         r = signature_element_length(*signature, &l);
3576                         if (r < 0)
3577                                 return r;
3578
3579                         assert(l >= 2);
3580                         {
3581                                 char sig[l-1], *s;
3582                                 strncpy(sig, *signature + 1, l-1);
3583                                 s = sig;
3584
3585                                 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
3586                                 if (r < 0)
3587                                         return r;
3588                         }
3589
3590                         *signature += l;
3591                 } else
3592                         return -EINVAL;
3593         }
3594 }
3595
3596 int bus_message_parse_fields(sd_bus_message *m) {
3597         size_t ri;
3598         int r;
3599         uint32_t unix_fds = 0;
3600
3601         assert(m);
3602
3603         for (ri = 0; ri < BUS_MESSAGE_FIELDS_SIZE(m); ) {
3604                 const char *signature;
3605                 uint8_t *header;
3606
3607                 r = message_peek_fields(m, &ri, 8, 1, (void**) &header);
3608                 if (r < 0)
3609                         return r;
3610
3611                 r = message_peek_field_signature(m, &ri, &signature);
3612                 if (r < 0)
3613                         return r;
3614
3615                 switch (*header) {
3616                 case _SD_BUS_MESSAGE_HEADER_INVALID:
3617                         return -EBADMSG;
3618
3619                 case SD_BUS_MESSAGE_HEADER_PATH:
3620
3621                         if (m->path)
3622                                 return -EBADMSG;
3623
3624                         if (!streq(signature, "o"))
3625                                 return -EBADMSG;
3626
3627                         r = message_peek_field_string(m, object_path_is_valid, &ri, &m->path);
3628                         break;
3629
3630                 case SD_BUS_MESSAGE_HEADER_INTERFACE:
3631
3632                         if (m->interface)
3633                                 return -EBADMSG;
3634
3635                         if (!streq(signature, "s"))
3636                                 return -EBADMSG;
3637
3638                         r = message_peek_field_string(m, interface_name_is_valid, &ri, &m->interface);
3639                         break;
3640
3641                 case SD_BUS_MESSAGE_HEADER_MEMBER:
3642
3643                         if (m->member)
3644                                 return -EBADMSG;
3645
3646                         if (!streq(signature, "s"))
3647                                 return -EBADMSG;
3648
3649                         r = message_peek_field_string(m, member_name_is_valid, &ri, &m->member);
3650                         break;
3651
3652                 case SD_BUS_MESSAGE_HEADER_ERROR_NAME:
3653
3654                         if (m->error.name)
3655                                 return -EBADMSG;
3656
3657                         if (!streq(signature, "s"))
3658                                 return -EBADMSG;
3659
3660                         r = message_peek_field_string(m, error_name_is_valid, &ri, &m->error.name);
3661                         break;
3662
3663                 case SD_BUS_MESSAGE_HEADER_DESTINATION:
3664
3665                         if (m->destination)
3666                                 return -EBADMSG;
3667
3668                         if (!streq(signature, "s"))
3669                                 return -EBADMSG;
3670
3671                         r = message_peek_field_string(m, service_name_is_valid, &ri, &m->destination);
3672                         break;
3673
3674                 case SD_BUS_MESSAGE_HEADER_SENDER:
3675
3676                         if (m->sender)
3677                                 return -EBADMSG;
3678
3679                         if (!streq(signature, "s"))
3680                                 return -EBADMSG;
3681
3682                         r = message_peek_field_string(m, service_name_is_valid, &ri, &m->sender);
3683                         break;
3684
3685
3686                 case SD_BUS_MESSAGE_HEADER_SIGNATURE: {
3687                         const char *s;
3688                         char *c;
3689
3690                         if (m->root_container.signature)
3691                                 return -EBADMSG;
3692
3693                         if (!streq(signature, "g"))
3694                                 return -EBADMSG;
3695
3696                         r = message_peek_field_signature(m, &ri, &s);
3697                         if (r < 0)
3698                                 return r;
3699
3700                         c = strdup(s);
3701                         if (!c)
3702                                 return -ENOMEM;
3703
3704                         free(m->root_container.signature);
3705                         m->root_container.signature = c;
3706                         break;
3707                 }
3708
3709                 case SD_BUS_MESSAGE_HEADER_REPLY_SERIAL:
3710                         if (m->reply_serial != 0)
3711                                 return -EBADMSG;
3712
3713                         if (!streq(signature, "u"))
3714                                 return -EBADMSG;
3715
3716                         r = message_peek_field_uint32(m, &ri, &m->reply_serial);
3717                         if (r < 0)
3718                                 return r;
3719
3720                         if (m->reply_serial == 0)
3721                                 return -EBADMSG;
3722
3723                         break;
3724
3725                 case SD_BUS_MESSAGE_HEADER_UNIX_FDS:
3726                         if (unix_fds != 0)
3727                                 return -EBADMSG;
3728
3729                         if (!streq(signature, "u"))
3730                                 return -EBADMSG;
3731
3732                         r = message_peek_field_uint32(m, &ri, &unix_fds);
3733                         if (r < 0)
3734                                 return -EBADMSG;
3735
3736                         if (unix_fds == 0)
3737                                 return -EBADMSG;
3738
3739                         break;
3740
3741                 default:
3742                         r = message_skip_fields(m, &ri, (uint32_t) -1, (const char **) &signature);
3743                 }
3744
3745                 if (r < 0)
3746                         return r;
3747         }
3748
3749         if (m->n_fds != unix_fds)
3750                 return -EBADMSG;
3751
3752         if (isempty(m->root_container.signature) != (BUS_MESSAGE_BODY_SIZE(m) == 0))
3753                 return -EBADMSG;
3754
3755         switch (m->header->type) {
3756
3757         case SD_BUS_MESSAGE_TYPE_SIGNAL:
3758                 if (!m->path || !m->interface || !m->member)
3759                         return -EBADMSG;
3760                 break;
3761
3762         case SD_BUS_MESSAGE_TYPE_METHOD_CALL:
3763
3764                 if (!m->path || !m->member)
3765                         return -EBADMSG;
3766
3767                 break;
3768
3769         case SD_BUS_MESSAGE_TYPE_METHOD_RETURN:
3770
3771                 if (m->reply_serial == 0)
3772                         return -EBADMSG;
3773                 break;
3774
3775         case SD_BUS_MESSAGE_TYPE_METHOD_ERROR:
3776
3777                 if (m->reply_serial == 0 || !m->error.name)
3778                         return -EBADMSG;
3779                 break;
3780         }
3781
3782         /* Try to read the error message, but if we can't it's a non-issue */
3783         if (m->header->type == SD_BUS_MESSAGE_TYPE_METHOD_ERROR)
3784                 sd_bus_message_read(m, "s", &m->error.message);
3785
3786         return 0;
3787 }
3788
3789 int bus_message_seal(sd_bus_message *m, uint64_t serial) {
3790         struct bus_body_part *part;
3791         size_t l, a;
3792         unsigned i;
3793         int r;
3794
3795         assert(m);
3796
3797         if (m->sealed)
3798                 return -EPERM;
3799
3800         if (m->n_containers > 0)
3801                 return -EBADMSG;
3802
3803         if (m->poisoned)
3804                 return -ESTALE;
3805
3806         /* If there's a non-trivial signature set, then add it in here */
3807         if (!isempty(m->root_container.signature)) {
3808                 r = message_append_field_signature(m, SD_BUS_MESSAGE_HEADER_SIGNATURE, m->root_container.signature, NULL);
3809                 if (r < 0)
3810                         return r;
3811         }
3812
3813         if (m->n_fds > 0) {
3814                 r = message_append_field_uint32(m, SD_BUS_MESSAGE_HEADER_UNIX_FDS, m->n_fds);
3815                 if (r < 0)
3816                         return r;
3817         }
3818
3819         /* Add padding at the end of the fields part, since we know
3820          * the body needs to start at an 8 byte alignment. We made
3821          * sure we allocated enough space for this, so all we need to
3822          * do here is to zero it out. */
3823         l = BUS_MESSAGE_FIELDS_SIZE(m);
3824         a = ALIGN8(l) - l;
3825         if (a > 0)
3826                 memset((uint8_t*) BUS_MESSAGE_FIELDS(m) + l, 0, a);
3827
3828         /* If this is something we can send as memfd, then let's seal
3829         the memfd now. Note that we can send memfds as payload only
3830         for directed messages, and not for broadcasts. */
3831         if (m->destination) {
3832                 MESSAGE_FOREACH_PART(part, i, m)
3833                         if (part->memfd >= 0 && !part->sealed && part->size > MEMFD_MIN_SIZE) {
3834                                 bus_body_part_unmap(part);
3835
3836                                 if (ioctl(part->memfd, KDBUS_CMD_MEMFD_SEAL_SET, 1) >= 0)
3837                                         part->sealed = true;
3838                         }
3839         }
3840
3841         m->header->serial = serial;
3842         m->sealed = true;
3843
3844         return 0;
3845 }
3846
3847 int sd_bus_message_set_destination(sd_bus_message *m, const char *destination) {
3848         if (!m)
3849                 return -EINVAL;
3850         if (!destination)
3851                 return -EINVAL;
3852         if (m->sealed)
3853                 return -EPERM;
3854         if (m->destination)
3855                 return -EEXIST;
3856
3857         return message_append_field_string(m, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &m->destination);
3858 }
3859
3860 int bus_message_dump(sd_bus_message *m) {
3861         const char *u = NULL, *uu = NULL, *s = NULL;
3862         char **cmdline = NULL;
3863         unsigned level = 1;
3864         int r;
3865         uid_t owner, audit_loginuid;
3866         uint32_t audit_sessionid;
3867
3868         assert(m);
3869
3870         printf("Message %p\n"
3871                "\tn_ref=%u\n"
3872                "\tendian=%c\n"
3873                "\ttype=%i\n"
3874                "\tflags=%u\n"
3875                "\tversion=%u\n"
3876                "\tserial=%u\n"
3877                "\tfields_size=%u\n"
3878                "\tbody_size=%u\n"
3879                "\tpath=%s\n"
3880                "\tinterface=%s\n"
3881                "\tmember=%s\n"
3882                "\tdestination=%s\n"
3883                "\tsender=%s\n"
3884                "\tsignature=%s\n"
3885                "\treply_serial=%u\n"
3886                "\terror.name=%s\n"
3887                "\terror.message=%s\n"
3888                "\tsealed=%s\n"
3889                "\tn_body_parts=%u\n",
3890                m,
3891                m->n_ref,
3892                m->header->endian,
3893                m->header->type,
3894                m->header->flags,
3895                m->header->version,
3896                BUS_MESSAGE_SERIAL(m),
3897                BUS_MESSAGE_FIELDS_SIZE(m),
3898                BUS_MESSAGE_BODY_SIZE(m),
3899                strna(m->path),
3900                strna(m->interface),
3901                strna(m->member),
3902                strna(m->destination),
3903                strna(m->sender),
3904                strna(m->root_container.signature),
3905                m->reply_serial,
3906                strna(m->error.name),
3907                strna(m->error.message),
3908                yes_no(m->sealed),
3909                m->n_body_parts);
3910
3911         if (m->pid != 0)
3912                 printf("\tpid=%lu\n", (unsigned long) m->pid);
3913         if (m->tid != 0)
3914                 printf("\ttid=%lu\n", (unsigned long) m->tid);
3915         if (m->uid_valid)
3916                 printf("\tuid=%lu\n", (unsigned long) m->uid);
3917         if (m->gid_valid)
3918                 printf("\tgid=%lu\n", (unsigned long) m->gid);
3919         if (m->pid_starttime != 0)
3920                 printf("\tpid_starttime=%llu\n", (unsigned long long) m->pid_starttime);
3921         if (m->monotonic != 0)
3922                 printf("\tmonotonic=%llu\n", (unsigned long long) m->monotonic);
3923         if (m->realtime != 0)
3924                 printf("\trealtime=%llu\n", (unsigned long long) m->realtime);
3925         if (m->exe)
3926                 printf("\texe=[%s]\n", m->exe);
3927         if (m->comm)
3928                 printf("\tcomm=[%s]\n", m->comm);
3929         if (m->tid_comm)
3930                 printf("\ttid_comm=[%s]\n", m->tid_comm);
3931         if (m->label)
3932                 printf("\tlabel=[%s]\n", m->label);
3933         if (m->cgroup)
3934                 printf("\tcgroup=[%s]\n", m->cgroup);
3935
3936         sd_bus_message_get_unit(m, &u);
3937         if (u)
3938                 printf("\tunit=[%s]\n", u);
3939         sd_bus_message_get_user_unit(m, &uu);
3940         if (uu)
3941                 printf("\tuser_unit=[%s]\n", uu);
3942         sd_bus_message_get_session(m, &s);
3943         if (s)
3944                 printf("\tsession=[%s]\n", s);
3945         if (sd_bus_message_get_owner_uid(m, &owner) >= 0)
3946                 printf("\towner_uid=%lu\n", (unsigned long) owner);
3947         if (sd_bus_message_get_audit_loginuid(m, &audit_loginuid) >= 0)
3948                 printf("\taudit_loginuid=%lu\n", (unsigned long) audit_loginuid);
3949         if (sd_bus_message_get_audit_sessionid(m, &audit_sessionid) >= 0)
3950                 printf("\taudit_sessionid=%lu\n", (unsigned long) audit_sessionid);
3951
3952         printf("\tCAP_KILL=%i\n", sd_bus_message_has_effective_cap(m, 5));
3953
3954         if (sd_bus_message_get_cmdline(m, &cmdline) >= 0) {
3955                 char **c;
3956
3957                 fputs("\tcmdline=[", stdout);
3958                 STRV_FOREACH(c, cmdline) {
3959                         if (c != cmdline)
3960                                 putchar(' ');
3961
3962                         fputs(*c, stdout);
3963                 }
3964
3965                 fputs("]\n", stdout);
3966         }
3967
3968         r = sd_bus_message_rewind(m, true);
3969         if (r < 0) {
3970                 log_error("Failed to rewind: %s", strerror(-r));
3971                 return r;
3972         }
3973
3974         printf("BEGIN_MESSAGE \"%s\" {\n", strempty(m->root_container.signature));
3975
3976         for(;;) {
3977                 _cleanup_free_ char *prefix = NULL;
3978                 const char *contents = NULL;
3979                 char type;
3980                 union {
3981                         uint8_t u8;
3982                         uint16_t u16;
3983                         int16_t s16;
3984                         uint32_t u32;
3985                         int32_t s32;
3986                         uint64_t u64;
3987                         int64_t s64;
3988                         double d64;
3989                         const char *string;
3990                         int i;
3991                 } basic;
3992
3993                 r = sd_bus_message_peek_type(m, &type, &contents);
3994                 if (r < 0) {
3995                         log_error("Failed to peek type: %s", strerror(-r));
3996                         return r;
3997                 }
3998                 if (r == 0) {
3999                         if (level <= 1)
4000                                 break;
4001
4002                         r = sd_bus_message_exit_container(m);
4003                         if (r < 0) {
4004                                 log_error("Failed to exit container: %s", strerror(-r));
4005                                 return r;
4006                         }
4007
4008                         level--;
4009
4010                         prefix = strrep("\t", level);
4011                         if (!prefix)
4012                                 return log_oom();
4013
4014                         if (type == SD_BUS_TYPE_ARRAY)
4015                                 printf("%s} END_ARRAY \n", prefix);
4016                         else if (type == SD_BUS_TYPE_VARIANT)
4017                                 printf("%s} END_VARIANT\n", prefix);
4018                         else if (type == SD_BUS_TYPE_STRUCT)
4019                                 printf("%s} END_STRUCT\n", prefix);
4020                         else if (type == SD_BUS_TYPE_DICT_ENTRY)
4021                                 printf("%s} END_DICT_ENTRY\n", prefix);
4022
4023                         continue;
4024                 }
4025
4026                 prefix = strrep("\t", level);
4027                 if (!prefix)
4028                         return log_oom();
4029
4030                 if (bus_type_is_container(type) > 0) {
4031                         r = sd_bus_message_enter_container(m, type, contents);
4032                         if (r < 0) {
4033                                 log_error("Failed to enter container: %s", strerror(-r));
4034                                 return r;
4035                         }
4036
4037                         if (type == SD_BUS_TYPE_ARRAY)
4038                                 printf("%sBEGIN_ARRAY \"%s\" {\n", prefix, contents);
4039                         else if (type == SD_BUS_TYPE_VARIANT)
4040                                 printf("%sBEGIN_VARIANT \"%s\" {\n", prefix, contents);
4041                         else if (type == SD_BUS_TYPE_STRUCT)
4042                                 printf("%sBEGIN_STRUCT \"%s\" {\n", prefix, contents);
4043                         else if (type == SD_BUS_TYPE_DICT_ENTRY)
4044                                 printf("%sBEGIN_DICT_ENTRY \"%s\" {\n", prefix, contents);
4045
4046                         level ++;
4047
4048                         continue;
4049                 }
4050
4051                 r = sd_bus_message_read_basic(m, type, &basic);
4052                 if (r < 0) {
4053                         log_error("Failed to get basic: %s", strerror(-r));
4054                         return r;
4055                 }
4056
4057                 switch (type) {
4058
4059                 case SD_BUS_TYPE_BYTE:
4060                         printf("%sBYTE: %u\n", prefix, basic.u8);
4061                         break;
4062
4063                 case SD_BUS_TYPE_BOOLEAN:
4064                         printf("%sBOOLEAN: %s\n", prefix, yes_no(basic.i));
4065                         break;
4066
4067                 case SD_BUS_TYPE_INT16:
4068                         printf("%sINT16: %i\n", prefix, basic.s16);
4069                         break;
4070
4071                 case SD_BUS_TYPE_UINT16:
4072                         printf("%sUINT16: %u\n", prefix, basic.u16);
4073                         break;
4074
4075                 case SD_BUS_TYPE_INT32:
4076                         printf("%sINT32: %i\n", prefix, basic.s32);
4077                         break;
4078
4079                 case SD_BUS_TYPE_UINT32:
4080                         printf("%sUINT32: %u\n", prefix, basic.u32);
4081                         break;
4082
4083                 case SD_BUS_TYPE_INT64:
4084                         printf("%sINT64: %lli\n", prefix, (long long) basic.s64);
4085                         break;
4086
4087                 case SD_BUS_TYPE_UINT64:
4088                         printf("%sUINT64: %llu\n", prefix, (unsigned long long) basic.u64);
4089                         break;
4090
4091                 case SD_BUS_TYPE_DOUBLE:
4092                         printf("%sDOUBLE: %g\n", prefix, basic.d64);
4093                         break;
4094
4095                 case SD_BUS_TYPE_STRING:
4096                         printf("%sSTRING: \"%s\"\n", prefix, basic.string);
4097                         break;
4098
4099                 case SD_BUS_TYPE_OBJECT_PATH:
4100                         printf("%sOBJECT_PATH: \"%s\"\n", prefix, basic.string);
4101                         break;
4102
4103                 case SD_BUS_TYPE_SIGNATURE:
4104                         printf("%sSIGNATURE: \"%s\"\n", prefix, basic.string);
4105                         break;
4106
4107                 case SD_BUS_TYPE_UNIX_FD:
4108                         printf("%sUNIX_FD: %i\n", prefix, basic.i);
4109                         break;
4110
4111                 default:
4112                         assert_not_reached("Unknown basic type.");
4113                 }
4114         }
4115
4116         printf("} END_MESSAGE\n");
4117         return 0;
4118 }
4119
4120 int bus_message_get_blob(sd_bus_message *m, void **buffer, size_t *sz) {
4121         size_t total;
4122         void *p, *e;
4123         unsigned i;
4124         struct bus_body_part *part;
4125
4126         assert(m);
4127         assert(buffer);
4128         assert(sz);
4129
4130         total = BUS_MESSAGE_SIZE(m);
4131
4132         p = malloc(total);
4133         if (!p)
4134                 return -ENOMEM;
4135
4136         e = mempcpy(p, m->header, BUS_MESSAGE_BODY_BEGIN(m));
4137         MESSAGE_FOREACH_PART(part, i, m)
4138                 e = mempcpy(e, part->data, part->size);
4139
4140         assert(total == (size_t) ((uint8_t*) e - (uint8_t*) p));
4141
4142         *buffer = p;
4143         *sz = total;
4144
4145         return 0;
4146 }
4147
4148 int bus_message_read_strv_extend(sd_bus_message *m, char ***l) {
4149         int r;
4150
4151         assert(m);
4152         assert(l);
4153
4154         r = sd_bus_message_enter_container(m, 'a', "s");
4155         if (r < 0)
4156                 return r;
4157
4158         for (;;) {
4159                 const char *s;
4160
4161                 r = sd_bus_message_read_basic(m, 's', &s);
4162                 if (r < 0)
4163                         return r;
4164                 if (r == 0)
4165                         break;
4166
4167                 r = strv_extend(l, s);
4168                 if (r < 0)
4169                         return r;
4170         }
4171
4172         r = sd_bus_message_exit_container(m);
4173         if (r < 0)
4174                 return r;
4175
4176         return 0;
4177 }
4178
4179 const char* bus_message_get_arg(sd_bus_message *m, unsigned i) {
4180         int r;
4181         const char *t = NULL;
4182         unsigned j;
4183
4184         assert(m);
4185
4186         r = sd_bus_message_rewind(m, true);
4187         if (r < 0)
4188                 return NULL;
4189
4190         for (j = 0; j <= i; j++) {
4191                 char type;
4192
4193                 r = sd_bus_message_peek_type(m, &type, NULL);
4194                 if (r < 0)
4195                         return NULL;
4196
4197                 if (type != SD_BUS_TYPE_STRING &&
4198                     type != SD_BUS_TYPE_OBJECT_PATH &&
4199                     type != SD_BUS_TYPE_SIGNATURE)
4200                         return NULL;
4201
4202                 r = sd_bus_message_read_basic(m, type, &t);
4203                 if (r < 0)
4204                         return NULL;
4205         }
4206
4207         return t;
4208 }
4209
4210 bool bus_header_is_complete(struct bus_header *h, size_t size) {
4211         size_t full;
4212
4213         assert(h);
4214         assert(size);
4215
4216         if (size < sizeof(struct bus_header))
4217                 return false;
4218
4219         full = sizeof(struct bus_header) +
4220                 (h->endian == SD_BUS_NATIVE_ENDIAN ? h->fields_size : bswap_32(h->fields_size));
4221
4222         return size >= full;
4223 }
4224
4225 int bus_header_message_size(struct bus_header *h, size_t *sum) {
4226         size_t fs, bs;
4227
4228         assert(h);
4229         assert(sum);
4230
4231         if (h->endian == SD_BUS_NATIVE_ENDIAN) {
4232                 fs = h->fields_size;
4233                 bs = h->body_size;
4234         } else if (h->endian == SD_BUS_REVERSE_ENDIAN) {
4235                 fs = bswap_32(h->fields_size);
4236                 bs = bswap_32(h->body_size);
4237         } else
4238                 return -EBADMSG;
4239
4240         *sum = sizeof(struct bus_header) + ALIGN8(fs) + bs;
4241         return 0;
4242 }