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