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