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