chiark / gitweb /
209fd71c13ffad7318724f618cb51a10c2d6d3d0
[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 int bus_body_part_map(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         /* For smaller zero parts (as used for padding) we don't need to map anything... */
2200         if (part->memfd < 0 && part->is_zero && part->size < 8) {
2201                 static const uint8_t zeroes[7] = { };
2202                 part->data = (void*) zeroes;
2203                 return 0;
2204         }
2205
2206         psz = PAGE_ALIGN(part->size);
2207
2208         if (part->memfd >= 0)
2209                 p = mmap(NULL, psz, PROT_READ, MAP_SHARED, part->memfd, 0);
2210         else if (part->is_zero)
2211                 p = mmap(NULL, psz, PROT_READ, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
2212         else
2213                 return -EINVAL;
2214
2215         if (p == MAP_FAILED)
2216                 return -errno;
2217
2218         part->mapped = psz;
2219         part->data = p;
2220         part->munmap_this = true;
2221
2222         return 0;
2223 }
2224
2225 void bus_body_part_unmap(struct bus_body_part *part) {
2226
2227         assert_se(part);
2228
2229         if (part->memfd < 0)
2230                 return;
2231
2232         if (!part->data)
2233                 return;
2234
2235         if (!part->munmap_this)
2236                 return;
2237
2238         assert_se(munmap(part->data, part->mapped) == 0);
2239
2240         part->data = NULL;
2241         part->mapped = 0;
2242         part->munmap_this = false;
2243
2244         return;
2245 }
2246
2247 static int buffer_peek(const void *p, uint32_t sz, size_t *rindex, size_t align, size_t nbytes, void **r) {
2248         size_t k, start, end;
2249
2250         assert(rindex);
2251         assert(align > 0);
2252
2253         start = ALIGN_TO((size_t) *rindex, align);
2254         end = start + nbytes;
2255
2256         if (end > sz)
2257                 return -EBADMSG;
2258
2259         /* Verify that padding is 0 */
2260         for (k = *rindex; k < start; k++)
2261                 if (((const uint8_t*) p)[k] != 0)
2262                         return -EBADMSG;
2263
2264         if (r)
2265                 *r = (uint8_t*) p + start;
2266
2267         *rindex = end;
2268
2269         return 1;
2270 }
2271
2272 static bool message_end_of_array(sd_bus_message *m, size_t index) {
2273         struct bus_container *c;
2274
2275         assert(m);
2276
2277         c = message_get_container(m);
2278         if (!c->array_size)
2279                 return false;
2280
2281         return index >= c->begin + BUS_MESSAGE_BSWAP32(m, *c->array_size);
2282 }
2283
2284 static struct bus_body_part* find_part(sd_bus_message *m, size_t index, size_t sz, void **p) {
2285         struct bus_body_part *part;
2286         size_t begin;
2287         int r;
2288
2289         assert(m);
2290
2291         if (m->cached_rindex_part && index >= m->cached_rindex_part_begin) {
2292                 part = m->cached_rindex_part;
2293                 begin = m->cached_rindex_part_begin;
2294         } else {
2295                 part = &m->body;
2296                 begin = 0;
2297         }
2298
2299         while (part) {
2300                 if (index < begin)
2301                         return NULL;
2302
2303                 if (index + sz <= begin + part->size) {
2304
2305                         r = bus_body_part_map(part);
2306                         if (r < 0)
2307                                 return NULL;
2308
2309                         if (p)
2310                                 *p = (uint8_t*) part->data + index - begin;
2311
2312                         m->cached_rindex_part = part;
2313                         m->cached_rindex_part_begin = begin;
2314
2315                         return part;
2316                 }
2317
2318                 begin += part->size;
2319                 part = part->next;
2320         }
2321
2322         return NULL;
2323 }
2324
2325 static int message_peek_body(
2326                 sd_bus_message *m,
2327                 size_t *rindex,
2328                 size_t align,
2329                 size_t nbytes,
2330                 void **ret) {
2331
2332         size_t k, start, end, padding;
2333         struct bus_body_part *part;
2334         uint8_t *q;
2335
2336         assert(m);
2337         assert(rindex);
2338         assert(align > 0);
2339
2340         if (message_end_of_array(m, *rindex))
2341                 return 0;
2342
2343         start = ALIGN_TO((size_t) *rindex, align);
2344         padding = start - *rindex;
2345         end = start + nbytes;
2346
2347         if (end > BUS_MESSAGE_BODY_SIZE(m))
2348                 return -EBADMSG;
2349
2350         part = find_part(m, *rindex, padding, (void**) &q);
2351         if (!part)
2352                 return -EBADMSG;
2353
2354         if (q) {
2355                 /* Verify padding */
2356                 for (k = 0; k < padding; k++)
2357                         if (q[k] != 0)
2358                                 return -EBADMSG;
2359         }
2360
2361         part = find_part(m, start, nbytes, (void**) &q);
2362         if (!part || !q)
2363                 return -EBADMSG;
2364
2365         *rindex = end;
2366
2367         if (ret)
2368                 *ret = q;
2369
2370         return 1;
2371 }
2372
2373 static bool validate_nul(const char *s, size_t l) {
2374
2375         /* Check for NUL chars in the string */
2376         if (memchr(s, 0, l))
2377                 return false;
2378
2379         /* Check for NUL termination */
2380         if (s[l] != 0)
2381                 return false;
2382
2383         return true;
2384 }
2385
2386 static bool validate_string(const char *s, size_t l) {
2387
2388         if (!validate_nul(s, l))
2389                 return false;
2390
2391         /* Check if valid UTF8 */
2392         if (!utf8_is_valid(s))
2393                 return false;
2394
2395         return true;
2396 }
2397
2398 static bool validate_signature(const char *s, size_t l) {
2399
2400         if (!validate_nul(s, l))
2401                 return false;
2402
2403         /* Check if valid signature */
2404         if (!signature_is_valid(s, true))
2405                 return false;
2406
2407         return true;
2408 }
2409
2410 static bool validate_object_path(const char *s, size_t l) {
2411
2412         if (!validate_nul(s, l))
2413                 return false;
2414
2415         if (!object_path_is_valid(s))
2416                 return false;
2417
2418         return true;
2419 }
2420
2421 int sd_bus_message_read_basic(sd_bus_message *m, char type, void *p) {
2422         struct bus_container *c;
2423         int r;
2424         void *q;
2425
2426         if (!m)
2427                 return -EINVAL;
2428         if (!m->sealed)
2429                 return -EPERM;
2430         if (!bus_type_is_basic(type))
2431                 return -EINVAL;
2432         if (!p)
2433                 return -EINVAL;
2434
2435         c = message_get_container(m);
2436
2437         if (!c->signature || c->signature[c->index] == 0)
2438                 return 0;
2439
2440         if (c->signature[c->index] != type)
2441                 return -ENXIO;
2442
2443         switch (type) {
2444
2445         case SD_BUS_TYPE_STRING:
2446         case SD_BUS_TYPE_OBJECT_PATH: {
2447                 uint32_t l;
2448                 size_t rindex;
2449
2450                 rindex = m->rindex;
2451                 r = message_peek_body(m, &rindex, 4, 4, &q);
2452                 if (r <= 0)
2453                         return r;
2454
2455                 l = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2456                 r = message_peek_body(m, &rindex, 1, l+1, &q);
2457                 if (r < 0)
2458                         return r;
2459                 if (r == 0)
2460                         return -EBADMSG;
2461
2462                 if (type == SD_BUS_TYPE_OBJECT_PATH) {
2463                         if (!validate_object_path(q, l))
2464                                 return -EBADMSG;
2465                 } else {
2466                         if (!validate_string(q, l))
2467                                 return -EBADMSG;
2468                 }
2469
2470                 m->rindex = rindex;
2471                 *(const char**) p = q;
2472                 break;
2473         }
2474
2475         case SD_BUS_TYPE_SIGNATURE: {
2476                 uint8_t l;
2477                 size_t rindex;
2478
2479                 rindex = m->rindex;
2480                 r = message_peek_body(m, &rindex, 1, 1, &q);
2481                 if (r <= 0)
2482                         return r;
2483
2484                 l = *(uint8_t*) q;
2485                 r = message_peek_body(m, &rindex, 1, l+1, &q);
2486                 if (r < 0)
2487                         return r;
2488                 if (r == 0)
2489                         return -EBADMSG;
2490
2491                 if (!validate_signature(q, l))
2492                         return -EBADMSG;
2493
2494                 m->rindex = rindex;
2495                 *(const char**) p = q;
2496                 break;
2497         }
2498
2499         default: {
2500                 ssize_t sz, align;
2501                 size_t rindex;
2502
2503                 align = bus_type_get_alignment(type);
2504                 sz = bus_type_get_size(type);
2505                 assert(align > 0 && sz > 0);
2506
2507                 rindex = m->rindex;
2508                 r = message_peek_body(m, &rindex, align, sz, &q);
2509                 if (r <= 0)
2510                         return r;
2511
2512                 switch (type) {
2513
2514                 case SD_BUS_TYPE_BYTE:
2515                         *(uint8_t*) p = *(uint8_t*) q;
2516                         break;
2517
2518                 case SD_BUS_TYPE_BOOLEAN:
2519                         *(int*) p = !!*(uint32_t*) q;
2520                         break;
2521
2522                 case SD_BUS_TYPE_INT16:
2523                 case SD_BUS_TYPE_UINT16:
2524                         *(uint16_t*) p = BUS_MESSAGE_BSWAP16(m, *(uint16_t*) q);
2525                         break;
2526
2527                 case SD_BUS_TYPE_INT32:
2528                 case SD_BUS_TYPE_UINT32:
2529                         *(uint32_t*) p = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2530                         break;
2531
2532                 case SD_BUS_TYPE_INT64:
2533                 case SD_BUS_TYPE_UINT64:
2534                 case SD_BUS_TYPE_DOUBLE:
2535                         *(uint64_t*) p = BUS_MESSAGE_BSWAP64(m, *(uint64_t*) q);
2536                         break;
2537
2538                 case SD_BUS_TYPE_UNIX_FD: {
2539                         uint32_t j;
2540
2541                         j = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2542                         if (j >= m->n_fds)
2543                                 return -EBADMSG;
2544
2545                         *(int*) p = m->fds[j];
2546                         break;
2547                 }
2548
2549                 default:
2550                         assert_not_reached("Unknown basic type...");
2551                 }
2552
2553                 m->rindex = rindex;
2554
2555                 break;
2556         }
2557         }
2558
2559         if (c->enclosing != SD_BUS_TYPE_ARRAY)
2560                 c->index++;
2561
2562         return 1;
2563 }
2564
2565 static int bus_message_enter_array(
2566                 sd_bus_message *m,
2567                 struct bus_container *c,
2568                 const char *contents,
2569                 uint32_t **array_size) {
2570
2571         size_t rindex;
2572         void *q;
2573         int r, alignment;
2574
2575         assert(m);
2576         assert(c);
2577         assert(contents);
2578         assert(array_size);
2579
2580         if (!signature_is_single(contents))
2581                 return -EINVAL;
2582
2583         alignment = bus_type_get_alignment(contents[0]);
2584         if (alignment < 0)
2585                 return alignment;
2586
2587         if (!c->signature || c->signature[c->index] == 0)
2588                 return 0;
2589
2590         if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
2591                 return -ENXIO;
2592
2593         if (!startswith(c->signature + c->index + 1, contents))
2594                 return -ENXIO;
2595
2596         rindex = m->rindex;
2597         r = message_peek_body(m, &rindex, 4, 4, &q);
2598         if (r <= 0)
2599                 return r;
2600
2601         if (BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q) > BUS_ARRAY_MAX_SIZE)
2602                 return -EBADMSG;
2603
2604         r = message_peek_body(m, &rindex, alignment, 0, NULL);
2605         if (r < 0)
2606                 return r;
2607         if (r == 0)
2608                 return -EBADMSG;
2609
2610         if (c->enclosing != SD_BUS_TYPE_ARRAY)
2611                 c->index += 1 + strlen(contents);
2612
2613         m->rindex = rindex;
2614
2615         *array_size = (uint32_t*) q;
2616
2617         return 1;
2618 }
2619
2620 static int bus_message_enter_variant(
2621                 sd_bus_message *m,
2622                 struct bus_container *c,
2623                 const char *contents) {
2624
2625         size_t rindex;
2626         uint8_t l;
2627         void *q;
2628         int r;
2629
2630         assert(m);
2631         assert(c);
2632         assert(contents);
2633
2634         if (!signature_is_single(contents))
2635                 return -EINVAL;
2636
2637         if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
2638                 return -EINVAL;
2639
2640         if (!c->signature || c->signature[c->index] == 0)
2641                 return 0;
2642
2643         if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
2644                 return -ENXIO;
2645
2646         rindex = m->rindex;
2647         r = message_peek_body(m, &rindex, 1, 1, &q);
2648         if (r <= 0)
2649                 return r;
2650
2651         l = *(uint8_t*) q;
2652         r = message_peek_body(m, &rindex, 1, l+1, &q);
2653         if (r < 0)
2654                 return r;
2655         if (r == 0)
2656                 return -EBADMSG;
2657
2658         if (!validate_signature(q, l))
2659                 return -EBADMSG;
2660
2661         if (!streq(q, contents))
2662                 return -ENXIO;
2663
2664         if (c->enclosing != SD_BUS_TYPE_ARRAY)
2665                 c->index++;
2666
2667         m->rindex = rindex;
2668
2669         return 1;
2670 }
2671
2672 static int bus_message_enter_struct(
2673                 sd_bus_message *m,
2674                 struct bus_container *c,
2675                 const char *contents) {
2676
2677         size_t l;
2678         int r;
2679
2680         assert(m);
2681         assert(c);
2682         assert(contents);
2683
2684         if (!signature_is_valid(contents, false))
2685                 return -EINVAL;
2686
2687         if (!c->signature || c->signature[c->index] == 0)
2688                 return 0;
2689
2690         l = strlen(contents);
2691
2692         if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
2693             !startswith(c->signature + c->index + 1, contents) ||
2694             c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
2695                 return -ENXIO;
2696
2697         r = message_peek_body(m, &m->rindex, 8, 0, NULL);
2698         if (r <= 0)
2699                 return r;
2700
2701         if (c->enclosing != SD_BUS_TYPE_ARRAY)
2702                 c->index += 1 + l + 1;
2703
2704         return 1;
2705 }
2706
2707 static int bus_message_enter_dict_entry(
2708                 sd_bus_message *m,
2709                 struct bus_container *c,
2710                 const char *contents) {
2711
2712         size_t l;
2713         int r;
2714
2715         assert(m);
2716         assert(c);
2717         assert(contents);
2718
2719         if (!signature_is_pair(contents))
2720                 return -EINVAL;
2721
2722         if (c->enclosing != SD_BUS_TYPE_ARRAY)
2723                 return -ENXIO;
2724
2725         if (!c->signature || c->signature[c->index] == 0)
2726                 return 0;
2727
2728         l = strlen(contents);
2729
2730         if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
2731             !startswith(c->signature + c->index + 1, contents) ||
2732             c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
2733                 return -ENXIO;
2734
2735         r = message_peek_body(m, &m->rindex, 8, 0, NULL);
2736         if (r <= 0)
2737                 return r;
2738
2739         if (c->enclosing != SD_BUS_TYPE_ARRAY)
2740                 c->index += 1 + l + 1;
2741
2742         return 1;
2743 }
2744
2745 int sd_bus_message_enter_container(sd_bus_message *m, char type, const char *contents) {
2746         struct bus_container *c, *w;
2747         uint32_t *array_size = NULL;
2748         char *signature;
2749         size_t before;
2750         int r;
2751
2752         if (!m)
2753                 return -EINVAL;
2754         if (!m->sealed)
2755                 return -EPERM;
2756         if (!contents)
2757                 return -EINVAL;
2758
2759         /*
2760          * We enforce a global limit on container depth, that is much
2761          * higher than the 32 structs and 32 arrays the specification
2762          * mandates. This is simpler to implement for us, and we need
2763          * this only to ensure our container array doesn't grow
2764          * without bounds. We are happy to return any data from a
2765          * message as long as the data itself is valid, even if the
2766          * overall message might be not.
2767          *
2768          * Note that the message signature is validated when
2769          * parsing the headers, and that validation does check the
2770          * 32/32 limit.
2771          *
2772          * Note that the specification defines no limits on the depth
2773          * of stacked variants, but we do.
2774          */
2775         if (m->n_containers >= BUS_CONTAINER_DEPTH)
2776                 return -EBADMSG;
2777
2778         w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
2779         if (!w)
2780                 return -ENOMEM;
2781         m->containers = w;
2782
2783         c = message_get_container(m);
2784
2785         if (!c->signature || c->signature[c->index] == 0)
2786                 return 0;
2787
2788         signature = strdup(contents);
2789         if (!signature)
2790                 return -ENOMEM;
2791
2792         c->saved_index = c->index;
2793         before = m->rindex;
2794
2795         if (type == SD_BUS_TYPE_ARRAY)
2796                 r = bus_message_enter_array(m, c, contents, &array_size);
2797         else if (type == SD_BUS_TYPE_VARIANT)
2798                 r = bus_message_enter_variant(m, c, contents);
2799         else if (type == SD_BUS_TYPE_STRUCT)
2800                 r = bus_message_enter_struct(m, c, contents);
2801         else if (type == SD_BUS_TYPE_DICT_ENTRY)
2802                 r = bus_message_enter_dict_entry(m, c, contents);
2803         else
2804                 r = -EINVAL;
2805
2806         if (r <= 0) {
2807                 free(signature);
2808                 return r;
2809         }
2810
2811         /* OK, let's fill it in */
2812         w += m->n_containers++;
2813         w->enclosing = type;
2814         w->signature = signature;
2815         w->index = 0;
2816         w->array_size = array_size;
2817         w->before = before;
2818         w->begin = m->rindex;
2819
2820         return 1;
2821 }
2822
2823 int sd_bus_message_exit_container(sd_bus_message *m) {
2824         struct bus_container *c;
2825
2826         if (!m)
2827                 return -EINVAL;
2828         if (!m->sealed)
2829                 return -EPERM;
2830         if (m->n_containers <= 0)
2831                 return -EINVAL;
2832
2833         c = message_get_container(m);
2834         if (c->enclosing == SD_BUS_TYPE_ARRAY) {
2835                 uint32_t l;
2836
2837                 l = BUS_MESSAGE_BSWAP32(m, *c->array_size);
2838                 if (c->begin + l != m->rindex)
2839                         return -EBUSY;
2840
2841         } else {
2842                 if (c->signature && c->signature[c->index] != 0)
2843                         return -EINVAL;
2844         }
2845
2846         free(c->signature);
2847         m->n_containers--;
2848
2849         return 1;
2850 }
2851
2852 static void message_quit_container(sd_bus_message *m) {
2853         struct bus_container *c;
2854
2855         assert(m);
2856         assert(m->sealed);
2857         assert(m->n_containers > 0);
2858
2859         c = message_get_container(m);
2860
2861         /* Undo seeks */
2862         assert(m->rindex >= c->before);
2863         m->rindex = c->before;
2864
2865         /* Free container */
2866         free(c->signature);
2867         m->n_containers--;
2868
2869         /* Correct index of new top-level container */
2870         c = message_get_container(m);
2871         c->index = c->saved_index;
2872 }
2873
2874 int sd_bus_message_peek_type(sd_bus_message *m, char *type, const char **contents) {
2875         struct bus_container *c;
2876         int r;
2877
2878         if (!m)
2879                 return -EINVAL;
2880         if (!m->sealed)
2881                 return -EPERM;
2882
2883         c = message_get_container(m);
2884
2885         if (!c->signature || c->signature[c->index] == 0)
2886                 goto eof;
2887
2888         if (message_end_of_array(m, m->rindex))
2889                 goto eof;
2890
2891         if (bus_type_is_basic(c->signature[c->index])) {
2892                 if (contents)
2893                         *contents = NULL;
2894                 if (type)
2895                         *type = c->signature[c->index];
2896                 return 1;
2897         }
2898
2899         if (c->signature[c->index] == SD_BUS_TYPE_ARRAY) {
2900
2901                 if (contents) {
2902                         size_t l;
2903                         char *sig;
2904
2905                         r = signature_element_length(c->signature+c->index+1, &l);
2906                         if (r < 0)
2907                                 return r;
2908
2909                         assert(l >= 1);
2910
2911                         sig = strndup(c->signature + c->index + 1, l);
2912                         if (!sig)
2913                                 return -ENOMEM;
2914
2915                         free(m->peeked_signature);
2916                         m->peeked_signature = sig;
2917
2918                         *contents = sig;
2919                 }
2920
2921                 if (type)
2922                         *type = SD_BUS_TYPE_ARRAY;
2923
2924                 return 1;
2925         }
2926
2927         if (c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ||
2928             c->signature[c->index] == SD_BUS_TYPE_DICT_ENTRY_BEGIN) {
2929
2930                 if (contents) {
2931                         size_t l;
2932                         char *sig;
2933
2934                         r = signature_element_length(c->signature+c->index, &l);
2935                         if (r < 0)
2936                                 return r;
2937
2938                         assert(l >= 2);
2939                         sig = strndup(c->signature + c->index + 1, l - 2);
2940                         if (!sig)
2941                                 return -ENOMEM;
2942
2943                         free(m->peeked_signature);
2944                         m->peeked_signature = sig;
2945
2946                         *contents = sig;
2947                 }
2948
2949                 if (type)
2950                         *type = c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY;
2951
2952                 return 1;
2953         }
2954
2955         if (c->signature[c->index] == SD_BUS_TYPE_VARIANT) {
2956                 if (contents) {
2957                         size_t rindex, l;
2958                         void *q;
2959
2960                         rindex = m->rindex;
2961                         r = message_peek_body(m, &rindex, 1, 1, &q);
2962                         if (r < 0)
2963                                 return r;
2964                         if (r == 0)
2965                                 goto eof;
2966
2967                         l = *(uint8_t*) q;
2968                         r = message_peek_body(m, &rindex, 1, l+1, &q);
2969                         if (r < 0)
2970                                 return r;
2971                         if (r == 0)
2972                                 return -EBADMSG;
2973
2974                         if (!validate_signature(q, l))
2975                                 return -EBADMSG;
2976
2977                         *contents = q;
2978                 }
2979
2980                 if (type)
2981                         *type = SD_BUS_TYPE_VARIANT;
2982
2983                 return 1;
2984         }
2985
2986         return -EINVAL;
2987
2988 eof:
2989         if (type)
2990                 *type = c->enclosing;
2991         if (contents)
2992                 *contents = NULL;
2993         return 0;
2994 }
2995
2996 int sd_bus_message_rewind(sd_bus_message *m, int complete) {
2997         struct bus_container *c;
2998
2999         if (!m)
3000                 return -EINVAL;
3001         if (!m->sealed)
3002                 return -EPERM;
3003
3004         if (complete) {
3005                 message_reset_containers(m);
3006                 m->rindex = 0;
3007                 m->root_container.index = 0;
3008
3009                 c = message_get_container(m);
3010         } else {
3011                 c = message_get_container(m);
3012
3013                 c->index = 0;
3014                 m->rindex = c->begin;
3015         }
3016
3017         return !isempty(c->signature);
3018 }
3019 static int message_read_ap(
3020                 sd_bus_message *m,
3021                 const char *types,
3022                 va_list ap) {
3023
3024         unsigned n_array, n_struct;
3025         TypeStack stack[BUS_CONTAINER_DEPTH];
3026         unsigned stack_ptr = 0;
3027         int r;
3028
3029         assert(m);
3030
3031         if (!types)
3032                 return 0;
3033
3034         /* Ideally, we'd just call ourselves recursively on every
3035          * complex type. However, the state of a va_list that is
3036          * passed to a function is undefined after that function
3037          * returns. This means we need to docode the va_list linearly
3038          * in a single stackframe. We hence implement our own
3039          * home-grown stack in an array. */
3040
3041         n_array = (unsigned) -1;
3042         n_struct = strlen(types);
3043
3044         for (;;) {
3045                 const char *t;
3046
3047                 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
3048                         r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
3049                         if (r < 0)
3050                                 return r;
3051                         if (r == 0)
3052                                 break;
3053
3054                         r = sd_bus_message_exit_container(m);
3055                         if (r < 0)
3056                                 return r;
3057
3058                         continue;
3059                 }
3060
3061                 t = types;
3062                 if (n_array != (unsigned) -1)
3063                         n_array --;
3064                 else {
3065                         types ++;
3066                         n_struct--;
3067                 }
3068
3069                 switch (*t) {
3070
3071                 case SD_BUS_TYPE_BYTE:
3072                 case SD_BUS_TYPE_BOOLEAN:
3073                 case SD_BUS_TYPE_INT16:
3074                 case SD_BUS_TYPE_UINT16:
3075                 case SD_BUS_TYPE_INT32:
3076                 case SD_BUS_TYPE_UINT32:
3077                 case SD_BUS_TYPE_INT64:
3078                 case SD_BUS_TYPE_UINT64:
3079                 case SD_BUS_TYPE_DOUBLE:
3080                 case SD_BUS_TYPE_STRING:
3081                 case SD_BUS_TYPE_OBJECT_PATH:
3082                 case SD_BUS_TYPE_SIGNATURE:
3083                 case SD_BUS_TYPE_UNIX_FD: {
3084                         void *p;
3085
3086                         p = va_arg(ap, void*);
3087                         r = sd_bus_message_read_basic(m, *t, p);
3088                         if (r < 0)
3089                                 return r;
3090                         if (r == 0)
3091                                 return -ENXIO;
3092
3093                         break;
3094                 }
3095
3096                 case SD_BUS_TYPE_ARRAY: {
3097                         size_t k;
3098
3099                         r = signature_element_length(t + 1, &k);
3100                         if (r < 0)
3101                                 return r;
3102
3103                         {
3104                                 char s[k + 1];
3105                                 memcpy(s, t + 1, k);
3106                                 s[k] = 0;
3107
3108                                 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, s);
3109                                 if (r < 0)
3110                                         return r;
3111                                 if (r == 0)
3112                                         return -ENXIO;
3113                         }
3114
3115                         if (n_array == (unsigned) -1) {
3116                                 types += k;
3117                                 n_struct -= k;
3118                         }
3119
3120                         r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
3121                         if (r < 0)
3122                                 return r;
3123
3124                         types = t + 1;
3125                         n_struct = k;
3126                         n_array = va_arg(ap, unsigned);
3127
3128                         break;
3129                 }
3130
3131                 case SD_BUS_TYPE_VARIANT: {
3132                         const char *s;
3133
3134                         s = va_arg(ap, const char *);
3135                         if (!s)
3136                                 return -EINVAL;
3137
3138                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, s);
3139                         if (r < 0)
3140                                 return r;
3141                         if (r == 0)
3142                                 return -ENXIO;
3143
3144                         r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
3145                         if (r < 0)
3146                                 return r;
3147
3148                         types = s;
3149                         n_struct = strlen(s);
3150                         n_array = (unsigned) -1;
3151
3152                         break;
3153                 }
3154
3155                 case SD_BUS_TYPE_STRUCT_BEGIN:
3156                 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
3157                         size_t k;
3158
3159                         r = signature_element_length(t, &k);
3160                         if (r < 0)
3161                                 return r;
3162
3163                         {
3164                                 char s[k - 1];
3165                                 memcpy(s, t + 1, k - 2);
3166                                 s[k - 2] = 0;
3167
3168                                 r = sd_bus_message_enter_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
3169                                 if (r < 0)
3170                                         return r;
3171                                 if (r == 0)
3172                                         return -ENXIO;
3173                         }
3174
3175                         if (n_array == (unsigned) -1) {
3176                                 types += k - 1;
3177                                 n_struct -= k - 1;
3178                         }
3179
3180                         r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
3181                         if (r < 0)
3182                                 return r;
3183
3184                         types = t + 1;
3185                         n_struct = k - 2;
3186                         n_array = (unsigned) -1;
3187
3188                         break;
3189                 }
3190
3191                 default:
3192                         return -EINVAL;
3193                 }
3194         }
3195
3196         return 1;
3197 }
3198
3199 int sd_bus_message_read(sd_bus_message *m, const char *types, ...) {
3200         va_list ap;
3201         int r;
3202
3203         if (!m)
3204                 return -EINVAL;
3205         if (!m->sealed)
3206                 return -EPERM;
3207         if (!types)
3208                 return -EINVAL;
3209
3210         va_start(ap, types);
3211         r = message_read_ap(m, types, ap);
3212         va_end(ap);
3213
3214         return r;
3215 }
3216
3217 int sd_bus_message_read_array(sd_bus_message *m, char type, const void **ptr, size_t *size) {
3218         struct bus_container *c;
3219         void *p;
3220         size_t sz;
3221         ssize_t align;
3222         int r;
3223
3224         if (!m)
3225                 return -EINVAL;
3226         if (!m->sealed)
3227                 return -EPERM;
3228         if (!bus_type_is_trivial(type))
3229                 return -EINVAL;
3230         if (!ptr)
3231                 return -EINVAL;
3232         if (!size)
3233                 return -EINVAL;
3234         if (BUS_MESSAGE_NEED_BSWAP(m))
3235                 return -ENOTSUP;
3236
3237         align = bus_type_get_alignment(type);
3238         if (align < 0)
3239                 return align;
3240
3241         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
3242         if (r < 0)
3243                 return r;
3244
3245         c = message_get_container(m);
3246         sz = BUS_MESSAGE_BSWAP32(m, *c->array_size);
3247
3248         r = message_peek_body(m, &m->rindex, align, sz, &p);
3249         if (r < 0)
3250                 goto fail;
3251         if (r == 0) {
3252                 r = -EBADMSG;
3253                 goto fail;
3254         }
3255
3256         r = sd_bus_message_exit_container(m);
3257         if (r < 0)
3258                 goto fail;
3259
3260         *ptr = (const void*) p;
3261         *size = sz;
3262
3263         return 1;
3264
3265 fail:
3266         message_quit_container(m);
3267         return r;
3268 }
3269
3270 static int message_peek_fields(
3271                 sd_bus_message *m,
3272                 size_t *rindex,
3273                 size_t align,
3274                 size_t nbytes,
3275                 void **ret) {
3276
3277         assert(m);
3278         assert(rindex);
3279         assert(align > 0);
3280
3281         return buffer_peek(BUS_MESSAGE_FIELDS(m), BUS_MESSAGE_FIELDS_SIZE(m), rindex, align, nbytes, ret);
3282 }
3283
3284 static int message_peek_field_uint32(
3285                 sd_bus_message *m,
3286                 size_t *ri,
3287                 uint32_t *ret) {
3288
3289         int r;
3290         void *q;
3291
3292         assert(m);
3293         assert(ri);
3294
3295         r = message_peek_fields(m, ri, 4, 4, &q);
3296         if (r < 0)
3297                 return r;
3298
3299         if (ret)
3300                 *ret = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
3301
3302         return 0;
3303 }
3304
3305 static int message_peek_field_string(
3306                 sd_bus_message *m,
3307                 bool (*validate)(const char *p),
3308                 size_t *ri,
3309                 const char **ret) {
3310
3311         uint32_t l;
3312         int r;
3313         void *q;
3314
3315         assert(m);
3316         assert(ri);
3317
3318         r = message_peek_field_uint32(m, ri, &l);
3319         if (r < 0)
3320                 return r;
3321
3322         r = message_peek_fields(m, ri, 1, l+1, &q);
3323         if (r < 0)
3324                 return r;
3325
3326         if (validate) {
3327                 if (!validate_nul(q, l))
3328                         return -EBADMSG;
3329
3330                 if (!validate(q))
3331                         return -EBADMSG;
3332         } else {
3333                 if (!validate_string(q, l))
3334                         return -EBADMSG;
3335         }
3336
3337         if (ret)
3338                 *ret = q;
3339
3340         return 0;
3341 }
3342
3343 static int message_peek_field_signature(
3344                 sd_bus_message *m,
3345                 size_t *ri,
3346                 const char **ret) {
3347
3348         size_t l;
3349         int r;
3350         void *q;
3351
3352         assert(m);
3353         assert(ri);
3354
3355         r = message_peek_fields(m, ri, 1, 1, &q);
3356         if (r < 0)
3357                 return r;
3358
3359         l = *(uint8_t*) q;
3360         r = message_peek_fields(m, ri, 1, l+1, &q);
3361         if (r < 0)
3362                 return r;
3363
3364         if (!validate_signature(q, l))
3365                 return -EBADMSG;
3366
3367         if (ret)
3368                 *ret = q;
3369
3370         return 0;
3371 }
3372
3373 static int message_skip_fields(
3374                 sd_bus_message *m,
3375                 size_t *ri,
3376                 uint32_t array_size,
3377                 const char **signature) {
3378
3379         size_t original_index;
3380         int r;
3381
3382         assert(m);
3383         assert(ri);
3384         assert(signature);
3385
3386         original_index = *ri;
3387
3388         for (;;) {
3389                 char t;
3390                 size_t l;
3391
3392                 if (array_size != (uint32_t) -1 &&
3393                     array_size <= *ri - original_index)
3394                         return 0;
3395
3396                 t = **signature;
3397                 if (!t)
3398                         return 0;
3399
3400                 if (t == SD_BUS_TYPE_STRING) {
3401
3402                         r = message_peek_field_string(m, NULL, ri, NULL);
3403                         if (r < 0)
3404                                 return r;
3405
3406                         (*signature)++;
3407
3408                 } else if (t == SD_BUS_TYPE_OBJECT_PATH) {
3409
3410                         r = message_peek_field_string(m, object_path_is_valid, ri, NULL);
3411                         if (r < 0)
3412                                 return r;
3413
3414                         (*signature)++;
3415
3416                 } else if (t == SD_BUS_TYPE_SIGNATURE) {
3417
3418                         r = message_peek_field_signature(m, ri, NULL);
3419                         if (r < 0)
3420                                 return r;
3421
3422                         (*signature)++;
3423
3424                 } else if (bus_type_is_basic(t)) {
3425                         ssize_t align, k;
3426
3427                         align = bus_type_get_alignment(t);
3428                         k = bus_type_get_size(t);
3429                         assert(align > 0 && k > 0);
3430
3431                         r = message_peek_fields(m, ri, align, k, NULL);
3432                         if (r < 0)
3433                                 return r;
3434
3435                         (*signature)++;
3436
3437                 } else if (t == SD_BUS_TYPE_ARRAY) {
3438
3439                         r = signature_element_length(*signature+1, &l);
3440                         if (r < 0)
3441                                 return r;
3442
3443                         assert(l >= 1);
3444                         {
3445                                 char sig[l-1], *s;
3446                                 uint32_t nas;
3447                                 int alignment;
3448
3449                                 strncpy(sig, *signature + 1, l-1);
3450                                 s = sig;
3451
3452                                 alignment = bus_type_get_alignment(sig[0]);
3453                                 if (alignment < 0)
3454                                         return alignment;
3455
3456                                 r = message_peek_field_uint32(m, ri, &nas);
3457                                 if (r < 0)
3458                                         return r;
3459                                 if (nas > BUS_ARRAY_MAX_SIZE)
3460                                         return -EBADMSG;
3461
3462                                 r = message_peek_fields(m, ri, alignment, 0, NULL);
3463                                 if (r < 0)
3464                                         return r;
3465
3466                                 r = message_skip_fields(m, ri, nas, (const char**) &s);
3467                                 if (r < 0)
3468                                         return r;
3469                         }
3470
3471                         (*signature) += 1 + l;
3472
3473                 } else if (t == SD_BUS_TYPE_VARIANT) {
3474                         const char *s;
3475
3476                         r = message_peek_field_signature(m, ri, &s);
3477                         if (r < 0)
3478                                 return r;
3479
3480                         r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
3481                         if (r < 0)
3482                                 return r;
3483
3484                         (*signature)++;
3485
3486                 } else if (t == SD_BUS_TYPE_STRUCT ||
3487                            t == SD_BUS_TYPE_DICT_ENTRY) {
3488
3489                         r = signature_element_length(*signature, &l);
3490                         if (r < 0)
3491                                 return r;
3492
3493                         assert(l >= 2);
3494                         {
3495                                 char sig[l-1], *s;
3496                                 strncpy(sig, *signature + 1, l-1);
3497                                 s = sig;
3498
3499                                 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
3500                                 if (r < 0)
3501                                         return r;
3502                         }
3503
3504                         *signature += l;
3505                 } else
3506                         return -EINVAL;
3507         }
3508 }
3509
3510 int bus_message_parse_fields(sd_bus_message *m) {
3511         size_t ri;
3512         int r;
3513         uint32_t unix_fds = 0;
3514
3515         assert(m);
3516
3517         for (ri = 0; ri < BUS_MESSAGE_FIELDS_SIZE(m); ) {
3518                 const char *signature;
3519                 uint8_t *header;
3520
3521                 r = message_peek_fields(m, &ri, 8, 1, (void**) &header);
3522                 if (r < 0)
3523                         return r;
3524
3525                 r = message_peek_field_signature(m, &ri, &signature);
3526                 if (r < 0)
3527                         return r;
3528
3529                 switch (*header) {
3530                 case _SD_BUS_MESSAGE_HEADER_INVALID:
3531                         return -EBADMSG;
3532
3533                 case SD_BUS_MESSAGE_HEADER_PATH:
3534
3535                         if (m->path)
3536                                 return -EBADMSG;
3537
3538                         if (!streq(signature, "o"))
3539                                 return -EBADMSG;
3540
3541                         r = message_peek_field_string(m, object_path_is_valid, &ri, &m->path);
3542                         break;
3543
3544                 case SD_BUS_MESSAGE_HEADER_INTERFACE:
3545
3546                         if (m->interface)
3547                                 return -EBADMSG;
3548
3549                         if (!streq(signature, "s"))
3550                                 return -EBADMSG;
3551
3552                         r = message_peek_field_string(m, interface_name_is_valid, &ri, &m->interface);
3553                         break;
3554
3555                 case SD_BUS_MESSAGE_HEADER_MEMBER:
3556
3557                         if (m->member)
3558                                 return -EBADMSG;
3559
3560                         if (!streq(signature, "s"))
3561                                 return -EBADMSG;
3562
3563                         r = message_peek_field_string(m, member_name_is_valid, &ri, &m->member);
3564                         break;
3565
3566                 case SD_BUS_MESSAGE_HEADER_ERROR_NAME:
3567
3568                         if (m->error.name)
3569                                 return -EBADMSG;
3570
3571                         if (!streq(signature, "s"))
3572                                 return -EBADMSG;
3573
3574                         r = message_peek_field_string(m, error_name_is_valid, &ri, &m->error.name);
3575                         break;
3576
3577                 case SD_BUS_MESSAGE_HEADER_DESTINATION:
3578
3579                         if (m->destination)
3580                                 return -EBADMSG;
3581
3582                         if (!streq(signature, "s"))
3583                                 return -EBADMSG;
3584
3585                         r = message_peek_field_string(m, service_name_is_valid, &ri, &m->destination);
3586                         break;
3587
3588                 case SD_BUS_MESSAGE_HEADER_SENDER:
3589
3590                         if (m->sender)
3591                                 return -EBADMSG;
3592
3593                         if (!streq(signature, "s"))
3594                                 return -EBADMSG;
3595
3596                         r = message_peek_field_string(m, service_name_is_valid, &ri, &m->sender);
3597                         break;
3598
3599
3600                 case SD_BUS_MESSAGE_HEADER_SIGNATURE: {
3601                         const char *s;
3602                         char *c;
3603
3604                         if (m->root_container.signature)
3605                                 return -EBADMSG;
3606
3607                         if (!streq(signature, "g"))
3608                                 return -EBADMSG;
3609
3610                         r = message_peek_field_signature(m, &ri, &s);
3611                         if (r < 0)
3612                                 return r;
3613
3614                         c = strdup(s);
3615                         if (!c)
3616                                 return -ENOMEM;
3617
3618                         free(m->root_container.signature);
3619                         m->root_container.signature = c;
3620                         break;
3621                 }
3622
3623                 case SD_BUS_MESSAGE_HEADER_REPLY_SERIAL:
3624                         if (m->reply_serial != 0)
3625                                 return -EBADMSG;
3626
3627                         if (!streq(signature, "u"))
3628                                 return -EBADMSG;
3629
3630                         r = message_peek_field_uint32(m, &ri, &m->reply_serial);
3631                         if (r < 0)
3632                                 return r;
3633
3634                         if (m->reply_serial == 0)
3635                                 return -EBADMSG;
3636
3637                         break;
3638
3639                 case SD_BUS_MESSAGE_HEADER_UNIX_FDS:
3640                         if (unix_fds != 0)
3641                                 return -EBADMSG;
3642
3643                         if (!streq(signature, "u"))
3644                                 return -EBADMSG;
3645
3646                         r = message_peek_field_uint32(m, &ri, &unix_fds);
3647                         if (r < 0)
3648                                 return -EBADMSG;
3649
3650                         if (unix_fds == 0)
3651                                 return -EBADMSG;
3652
3653                         break;
3654
3655                 default:
3656                         r = message_skip_fields(m, &ri, (uint32_t) -1, (const char **) &signature);
3657                 }
3658
3659                 if (r < 0)
3660                         return r;
3661         }
3662
3663         if (m->n_fds != unix_fds)
3664                 return -EBADMSG;
3665
3666         if (isempty(m->root_container.signature) != (BUS_MESSAGE_BODY_SIZE(m) == 0))
3667                 return -EBADMSG;
3668
3669         switch (m->header->type) {
3670
3671         case SD_BUS_MESSAGE_TYPE_SIGNAL:
3672                 if (!m->path || !m->interface || !m->member)
3673                         return -EBADMSG;
3674                 break;
3675
3676         case SD_BUS_MESSAGE_TYPE_METHOD_CALL:
3677
3678                 if (!m->path || !m->member)
3679                         return -EBADMSG;
3680
3681                 break;
3682
3683         case SD_BUS_MESSAGE_TYPE_METHOD_RETURN:
3684
3685                 if (m->reply_serial == 0)
3686                         return -EBADMSG;
3687                 break;
3688
3689         case SD_BUS_MESSAGE_TYPE_METHOD_ERROR:
3690
3691                 if (m->reply_serial == 0 || !m->error.name)
3692                         return -EBADMSG;
3693                 break;
3694         }
3695
3696         /* Try to read the error message, but if we can't it's a non-issue */
3697         if (m->header->type == SD_BUS_MESSAGE_TYPE_METHOD_ERROR)
3698                 sd_bus_message_read(m, "s", &m->error.message);
3699
3700         return 0;
3701 }
3702
3703 int bus_message_seal(sd_bus_message *m, uint64_t serial) {
3704         struct bus_body_part *part;
3705         size_t l, a;
3706         unsigned i;
3707         int r;
3708
3709         assert(m);
3710
3711         if (m->sealed)
3712                 return -EPERM;
3713
3714         if (m->n_containers > 0)
3715                 return -EBADMSG;
3716
3717         if (m->poisoned)
3718                 return -ESTALE;
3719
3720         /* If there's a non-trivial signature set, then add it in here */
3721         if (!isempty(m->root_container.signature)) {
3722                 r = message_append_field_signature(m, SD_BUS_MESSAGE_HEADER_SIGNATURE, m->root_container.signature, NULL);
3723                 if (r < 0)
3724                         return r;
3725         }
3726
3727         if (m->n_fds > 0) {
3728                 r = message_append_field_uint32(m, SD_BUS_MESSAGE_HEADER_UNIX_FDS, m->n_fds);
3729                 if (r < 0)
3730                         return r;
3731         }
3732
3733         /* Add padding at the end, since we know the body
3734          * needs to start at an 8 byte alignment. */
3735
3736         l = BUS_MESSAGE_FIELDS_SIZE(m);
3737         a = ALIGN8(l) - l;
3738         if (a > 0)
3739                 memset((uint8_t*) BUS_MESSAGE_FIELDS(m) + l, 0, a);
3740
3741         MESSAGE_FOREACH_PART(part, i, m)
3742                 if (part->memfd >= 0 && !part->sealed) {
3743                         bus_body_part_unmap(part);
3744
3745                         if (ioctl(part->memfd, KDBUS_CMD_MEMFD_SEAL_SET, 1) >= 0)
3746                                 part->sealed = true;
3747                 }
3748
3749         m->header->serial = serial;
3750         m->sealed = true;
3751
3752         return 0;
3753 }
3754
3755 int sd_bus_message_set_destination(sd_bus_message *m, const char *destination) {
3756         if (!m)
3757                 return -EINVAL;
3758         if (!destination)
3759                 return -EINVAL;
3760         if (m->sealed)
3761                 return -EPERM;
3762         if (m->destination)
3763                 return -EEXIST;
3764
3765         return message_append_field_string(m, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &m->destination);
3766 }
3767
3768 int bus_message_dump(sd_bus_message *m) {
3769         const char *u = NULL, *uu = NULL, *s = NULL;
3770         char **cmdline = NULL;
3771         unsigned level = 1;
3772         int r;
3773         uid_t owner, audit_loginuid;
3774         uint32_t audit_sessionid;
3775
3776         assert(m);
3777
3778         printf("Message %p\n"
3779                "\tn_ref=%u\n"
3780                "\tendian=%c\n"
3781                "\ttype=%i\n"
3782                "\tflags=%u\n"
3783                "\tversion=%u\n"
3784                "\tserial=%u\n"
3785                "\tfields_size=%u\n"
3786                "\tbody_size=%u\n"
3787                "\tpath=%s\n"
3788                "\tinterface=%s\n"
3789                "\tmember=%s\n"
3790                "\tdestination=%s\n"
3791                "\tsender=%s\n"
3792                "\tsignature=%s\n"
3793                "\treply_serial=%u\n"
3794                "\terror.name=%s\n"
3795                "\terror.message=%s\n"
3796                "\tsealed=%s\n"
3797                "\tn_body_parts=%u\n",
3798                m,
3799                m->n_ref,
3800                m->header->endian,
3801                m->header->type,
3802                m->header->flags,
3803                m->header->version,
3804                BUS_MESSAGE_SERIAL(m),
3805                BUS_MESSAGE_FIELDS_SIZE(m),
3806                BUS_MESSAGE_BODY_SIZE(m),
3807                strna(m->path),
3808                strna(m->interface),
3809                strna(m->member),
3810                strna(m->destination),
3811                strna(m->sender),
3812                strna(m->root_container.signature),
3813                m->reply_serial,
3814                strna(m->error.name),
3815                strna(m->error.message),
3816                yes_no(m->sealed),
3817                m->n_body_parts);
3818
3819         if (m->pid != 0)
3820                 printf("\tpid=%lu\n", (unsigned long) m->pid);
3821         if (m->tid != 0)
3822                 printf("\ttid=%lu\n", (unsigned long) m->tid);
3823         if (m->uid_valid)
3824                 printf("\tuid=%lu\n", (unsigned long) m->uid);
3825         if (m->gid_valid)
3826                 printf("\tgid=%lu\n", (unsigned long) m->gid);
3827         if (m->pid_starttime != 0)
3828                 printf("\tpid_starttime=%llu\n", (unsigned long long) m->pid_starttime);
3829         if (m->monotonic != 0)
3830                 printf("\tmonotonic=%llu\n", (unsigned long long) m->monotonic);
3831         if (m->realtime != 0)
3832                 printf("\trealtime=%llu\n", (unsigned long long) m->realtime);
3833         if (m->exe)
3834                 printf("\texe=[%s]\n", m->exe);
3835         if (m->comm)
3836                 printf("\tcomm=[%s]\n", m->comm);
3837         if (m->tid_comm)
3838                 printf("\ttid_comm=[%s]\n", m->tid_comm);
3839         if (m->label)
3840                 printf("\tlabel=[%s]\n", m->label);
3841         if (m->cgroup)
3842                 printf("\tcgroup=[%s]\n", m->cgroup);
3843
3844         sd_bus_message_get_unit(m, &u);
3845         if (u)
3846                 printf("\tunit=[%s]\n", u);
3847         sd_bus_message_get_user_unit(m, &uu);
3848         if (uu)
3849                 printf("\tuser_unit=[%s]\n", uu);
3850         sd_bus_message_get_session(m, &s);
3851         if (s)
3852                 printf("\tsession=[%s]\n", s);
3853         if (sd_bus_message_get_owner_uid(m, &owner) >= 0)
3854                 printf("\towner_uid=%lu\n", (unsigned long) owner);
3855         if (sd_bus_message_get_audit_loginuid(m, &audit_loginuid) >= 0)
3856                 printf("\taudit_loginuid=%lu\n", (unsigned long) audit_loginuid);
3857         if (sd_bus_message_get_audit_sessionid(m, &audit_sessionid) >= 0)
3858                 printf("\taudit_sessionid=%lu\n", (unsigned long) audit_sessionid);
3859
3860         printf("\tCAP_KILL=%i\n", sd_bus_message_has_effective_cap(m, 5));
3861
3862         if (sd_bus_message_get_cmdline(m, &cmdline) >= 0) {
3863                 char **c;
3864
3865                 fputs("\tcmdline=[", stdout);
3866                 STRV_FOREACH(c, cmdline) {
3867                         if (c != cmdline)
3868                                 putchar(' ');
3869
3870                         fputs(*c, stdout);
3871                 }
3872
3873                 fputs("]\n", stdout);
3874         }
3875
3876         r = sd_bus_message_rewind(m, true);
3877         if (r < 0) {
3878                 log_error("Failed to rewind: %s", strerror(-r));
3879                 return r;
3880         }
3881
3882         printf("BEGIN_MESSAGE \"%s\" {\n", strempty(m->root_container.signature));
3883
3884         for(;;) {
3885                 _cleanup_free_ char *prefix = NULL;
3886                 const char *contents = NULL;
3887                 char type;
3888                 union {
3889                         uint8_t u8;
3890                         uint16_t u16;
3891                         int16_t s16;
3892                         uint32_t u32;
3893                         int32_t s32;
3894                         uint64_t u64;
3895                         int64_t s64;
3896                         double d64;
3897                         const char *string;
3898                         int i;
3899                 } basic;
3900
3901                 r = sd_bus_message_peek_type(m, &type, &contents);
3902                 if (r < 0) {
3903                         log_error("Failed to peek type: %s", strerror(-r));
3904                         return r;
3905                 }
3906                 if (r == 0) {
3907                         if (level <= 1)
3908                                 break;
3909
3910                         r = sd_bus_message_exit_container(m);
3911                         if (r < 0) {
3912                                 log_error("Failed to exit container: %s", strerror(-r));
3913                                 return r;
3914                         }
3915
3916                         level--;
3917
3918                         prefix = strrep("\t", level);
3919                         if (!prefix)
3920                                 return log_oom();
3921
3922                         if (type == SD_BUS_TYPE_ARRAY)
3923                                 printf("%s} END_ARRAY \n", prefix);
3924                         else if (type == SD_BUS_TYPE_VARIANT)
3925                                 printf("%s} END_VARIANT\n", prefix);
3926                         else if (type == SD_BUS_TYPE_STRUCT)
3927                                 printf("%s} END_STRUCT\n", prefix);
3928                         else if (type == SD_BUS_TYPE_DICT_ENTRY)
3929                                 printf("%s} END_DICT_ENTRY\n", prefix);
3930
3931                         continue;
3932                 }
3933
3934                 prefix = strrep("\t", level);
3935                 if (!prefix)
3936                         return log_oom();
3937
3938                 if (bus_type_is_container(type) > 0) {
3939                         r = sd_bus_message_enter_container(m, type, contents);
3940                         if (r < 0) {
3941                                 log_error("Failed to enter container: %s", strerror(-r));
3942                                 return r;
3943                         }
3944
3945                         if (type == SD_BUS_TYPE_ARRAY)
3946                                 printf("%sBEGIN_ARRAY \"%s\" {\n", prefix, contents);
3947                         else if (type == SD_BUS_TYPE_VARIANT)
3948                                 printf("%sBEGIN_VARIANT \"%s\" {\n", prefix, contents);
3949                         else if (type == SD_BUS_TYPE_STRUCT)
3950                                 printf("%sBEGIN_STRUCT \"%s\" {\n", prefix, contents);
3951                         else if (type == SD_BUS_TYPE_DICT_ENTRY)
3952                                 printf("%sBEGIN_DICT_ENTRY \"%s\" {\n", prefix, contents);
3953
3954                         level ++;
3955
3956                         continue;
3957                 }
3958
3959                 r = sd_bus_message_read_basic(m, type, &basic);
3960                 if (r < 0) {
3961                         log_error("Failed to get basic: %s", strerror(-r));
3962                         return r;
3963                 }
3964
3965                 switch (type) {
3966
3967                 case SD_BUS_TYPE_BYTE:
3968                         printf("%sBYTE: %u\n", prefix, basic.u8);
3969                         break;
3970
3971                 case SD_BUS_TYPE_BOOLEAN:
3972                         printf("%sBOOLEAN: %s\n", prefix, yes_no(basic.i));
3973                         break;
3974
3975                 case SD_BUS_TYPE_INT16:
3976                         printf("%sINT16: %i\n", prefix, basic.s16);
3977                         break;
3978
3979                 case SD_BUS_TYPE_UINT16:
3980                         printf("%sUINT16: %u\n", prefix, basic.u16);
3981                         break;
3982
3983                 case SD_BUS_TYPE_INT32:
3984                         printf("%sINT32: %i\n", prefix, basic.s32);
3985                         break;
3986
3987                 case SD_BUS_TYPE_UINT32:
3988                         printf("%sUINT32: %u\n", prefix, basic.u32);
3989                         break;
3990
3991                 case SD_BUS_TYPE_INT64:
3992                         printf("%sINT64: %lli\n", prefix, (long long) basic.s64);
3993                         break;
3994
3995                 case SD_BUS_TYPE_UINT64:
3996                         printf("%sUINT64: %llu\n", prefix, (unsigned long long) basic.u64);
3997                         break;
3998
3999                 case SD_BUS_TYPE_DOUBLE:
4000                         printf("%sDOUBLE: %g\n", prefix, basic.d64);
4001                         break;
4002
4003                 case SD_BUS_TYPE_STRING:
4004                         printf("%sSTRING: \"%s\"\n", prefix, basic.string);
4005                         break;
4006
4007                 case SD_BUS_TYPE_OBJECT_PATH:
4008                         printf("%sOBJECT_PATH: \"%s\"\n", prefix, basic.string);
4009                         break;
4010
4011                 case SD_BUS_TYPE_SIGNATURE:
4012                         printf("%sSIGNATURE: \"%s\"\n", prefix, basic.string);
4013                         break;
4014
4015                 case SD_BUS_TYPE_UNIX_FD:
4016                         printf("%sUNIX_FD: %i\n", prefix, basic.i);
4017                         break;
4018
4019                 default:
4020                         assert_not_reached("Unknown basic type.");
4021                 }
4022         }
4023
4024         printf("} END_MESSAGE\n");
4025         return 0;
4026 }
4027
4028 int bus_message_get_blob(sd_bus_message *m, void **buffer, size_t *sz) {
4029         size_t total;
4030         void *p, *e;
4031         unsigned i;
4032         struct bus_body_part *part;
4033
4034         assert(m);
4035         assert(buffer);
4036         assert(sz);
4037
4038         total = BUS_MESSAGE_SIZE(m);
4039
4040         p = malloc(total);
4041         if (!p)
4042                 return -ENOMEM;
4043
4044         e = mempcpy(p, m->header, BUS_MESSAGE_BODY_BEGIN(m));
4045         MESSAGE_FOREACH_PART(part, i, m)
4046                 e = mempcpy(e, part->data, part->size);
4047
4048         assert(total == (size_t) ((uint8_t*) e - (uint8_t*) p));
4049
4050         *buffer = p;
4051         *sz = total;
4052
4053         return 0;
4054 }
4055
4056 int bus_message_read_strv_extend(sd_bus_message *m, char ***l) {
4057         int r;
4058
4059         assert(m);
4060         assert(l);
4061
4062         r = sd_bus_message_enter_container(m, 'a', "s");
4063         if (r < 0)
4064                 return r;
4065
4066         for (;;) {
4067                 const char *s;
4068
4069                 r = sd_bus_message_read_basic(m, 's', &s);
4070                 if (r < 0)
4071                         return r;
4072                 if (r == 0)
4073                         break;
4074
4075                 r = strv_extend(l, s);
4076                 if (r < 0)
4077                         return r;
4078         }
4079
4080         r = sd_bus_message_exit_container(m);
4081         if (r < 0)
4082                 return r;
4083
4084         return 0;
4085 }
4086
4087 const char* bus_message_get_arg(sd_bus_message *m, unsigned i) {
4088         int r;
4089         const char *t = NULL;
4090         unsigned j;
4091
4092         assert(m);
4093
4094         r = sd_bus_message_rewind(m, true);
4095         if (r < 0)
4096                 return NULL;
4097
4098         for (j = 0; j <= i; j++) {
4099                 char type;
4100
4101                 r = sd_bus_message_peek_type(m, &type, NULL);
4102                 if (r < 0)
4103                         return NULL;
4104
4105                 if (type != SD_BUS_TYPE_STRING &&
4106                     type != SD_BUS_TYPE_OBJECT_PATH &&
4107                     type != SD_BUS_TYPE_SIGNATURE)
4108                         return NULL;
4109
4110                 r = sd_bus_message_read_basic(m, type, &t);
4111                 if (r < 0)
4112                         return NULL;
4113         }
4114
4115         return t;
4116 }
4117
4118 bool bus_header_is_complete(struct bus_header *h, size_t size) {
4119         size_t full;
4120
4121         assert(h);
4122         assert(size);
4123
4124         if (size < sizeof(struct bus_header))
4125                 return false;
4126
4127         full = sizeof(struct bus_header) +
4128                 (h->endian == SD_BUS_NATIVE_ENDIAN ? h->fields_size : bswap_32(h->fields_size));
4129
4130         return size >= full;
4131 }
4132
4133 int bus_header_message_size(struct bus_header *h, size_t *sum) {
4134         size_t fs, bs;
4135
4136         assert(h);
4137         assert(sum);
4138
4139         if (h->endian == SD_BUS_NATIVE_ENDIAN) {
4140                 fs = h->fields_size;
4141                 bs = h->body_size;
4142         } else if (h->endian == SD_BUS_REVERSE_ENDIAN) {
4143                 fs = bswap_32(h->fields_size);
4144                 bs = bswap_32(h->body_size);
4145         } else
4146                 return -EBADMSG;
4147
4148         *sum = sizeof(struct bus_header) + ALIGN8(fs) + bs;
4149         return 0;
4150 }