1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2013 Lennart Poettering
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.
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.
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/>.
29 #include "time-util.h"
30 #include "cgroup-util.h"
33 #include "bus-message.h"
34 #include "bus-internal.h"
36 #include "bus-signature.h"
38 static int message_append_basic(sd_bus_message *m, char type, const void *p, const void **stored);
40 static void *adjust_pointer(const void *p, void *old_base, size_t sz, void *new_base) {
45 if (old_base == new_base)
48 if ((uint8_t*) p < (uint8_t*) old_base)
51 if ((uint8_t*) p >= (uint8_t*) old_base + sz)
54 return (uint8_t*) new_base + ((uint8_t*) p - (uint8_t*) old_base);
57 static void message_free_part(sd_bus_message *m, struct bus_body_part *part) {
61 if (part->memfd >= 0) {
62 /* If we can reuse the memfd, try that. For that it
63 * can't be sealed yet. */
66 bus_kernel_push_memfd(m->bus, part->memfd, part->data, part->mapped);
69 assert_se(munmap(part->data, part->mapped) == 0);
71 close_nointr_nofail(part->memfd);
74 } else if (part->munmap_this)
75 munmap(part->data, part->mapped);
76 else if (part->free_this)
83 static void message_reset_parts(sd_bus_message *m) {
84 struct bus_body_part *part;
89 while (m->n_body_parts > 0) {
90 struct bus_body_part *next = part->next;
91 message_free_part(m, part);
98 m->cached_rindex_part = NULL;
99 m->cached_rindex_part_begin = 0;
102 static void message_reset_containers(sd_bus_message *m) {
107 for (i = 0; i < m->n_containers; i++)
108 free(m->containers[i].signature);
111 m->containers = NULL;
114 m->root_container.index = 0;
117 static void message_free(sd_bus_message *m) {
123 message_reset_parts(m);
128 if (m->release_kdbus) {
131 off = (uint8_t *)m->kdbus - (uint8_t *)m->bus->kdbus_buffer;
132 ioctl(m->bus->input_fd, KDBUS_CMD_FREE, &off);
136 sd_bus_unref(m->bus);
139 close_many(m->fds, m->n_fds);
143 if (m->iovec != m->iovec_fixed)
146 message_reset_containers(m);
147 free(m->root_container.signature);
149 free(m->peeked_signature);
151 bus_creds_done(&m->creds);
155 static void *message_extend_fields(sd_bus_message *m, size_t align, size_t sz) {
157 size_t old_size, new_size, start;
164 old_size = sizeof(struct bus_header) + m->header->fields_size;
165 start = ALIGN_TO(old_size, align);
166 new_size = start + sz;
168 if (old_size == new_size)
169 return (uint8_t*) m->header + old_size;
171 if (new_size > (size_t) ((uint32_t) -1))
174 if (m->free_header) {
175 np = realloc(m->header, ALIGN8(new_size));
179 /* Initially, the header is allocated as part of of
180 * the sd_bus_message itself, let's replace it by
183 np = malloc(ALIGN8(new_size));
187 memcpy(np, m->header, sizeof(struct bus_header));
190 /* Zero out padding */
191 if (start > old_size)
192 memset((uint8_t*) np + old_size, 0, start - old_size);
196 m->header->fields_size = new_size - sizeof(struct bus_header);
198 /* Adjust quick access pointers */
199 m->path = adjust_pointer(m->path, op, old_size, m->header);
200 m->interface = adjust_pointer(m->interface, op, old_size, m->header);
201 m->member = adjust_pointer(m->member, op, old_size, m->header);
202 m->destination = adjust_pointer(m->destination, op, old_size, m->header);
203 m->sender = adjust_pointer(m->sender, op, old_size, m->header);
204 m->error.name = adjust_pointer(m->error.name, op, old_size, m->header);
206 m->free_header = true;
208 return (uint8_t*) np + start;
215 static int message_append_field_string(
228 if (l > (size_t) (uint32_t) -1)
231 /* field id byte + signature length + signature 's' + NUL + string length + string + NUL */
232 p = message_extend_fields(m, 8, 4 + 4 + l + 1);
241 ((uint32_t*) p)[1] = l;
242 memcpy(p + 8, s, l + 1);
245 *ret = (char*) p + 8;
250 static int message_append_field_signature(
265 /* field id byte + signature length + signature 'g' + NUL + string length + string + NUL */
266 p = message_extend_fields(m, 8, 4 + 1 + l + 1);
272 p[2] = SD_BUS_TYPE_SIGNATURE;
275 memcpy(p + 5, s, l + 1);
278 *ret = (const char*) p + 5;
283 static int message_append_field_uint32(sd_bus_message *m, uint8_t h, uint32_t x) {
288 /* field id byte + signature length + signature 'u' + NUL + value */
289 p = message_extend_fields(m, 8, 4 + 4);
295 p[2] = SD_BUS_TYPE_UINT32;
298 ((uint32_t*) p)[1] = x;
303 int bus_message_from_header(
309 const struct ucred *ucred,
312 sd_bus_message **ret) {
315 struct bus_header *h;
318 assert(buffer || length <= 0);
319 assert(fds || n_fds <= 0);
322 if (length < sizeof(struct bus_header))
332 if (h->type == _SD_BUS_MESSAGE_TYPE_INVALID)
335 if (h->endian != SD_BUS_LITTLE_ENDIAN &&
336 h->endian != SD_BUS_BIG_ENDIAN)
339 a = ALIGN(sizeof(sd_bus_message)) + ALIGN(extra);
342 label_sz = strlen(label);
357 m->creds.uid = ucred->uid;
358 m->creds.pid = ucred->pid;
359 m->creds.gid = ucred->gid;
360 m->creds.mask |= SD_BUS_CREDS_UID | SD_BUS_CREDS_PID | SD_BUS_CREDS_GID;
364 m->creds.label = (char*) m + ALIGN(sizeof(sd_bus_message)) + ALIGN(extra);
365 memcpy(m->creds.label, label, label_sz + 1);
367 m->creds.mask |= SD_BUS_CREDS_SELINUX_CONTEXT;
371 m->bus = sd_bus_ref(bus);
377 int bus_message_from_malloc(
383 const struct ucred *ucred,
385 sd_bus_message **ret) {
391 r = bus_message_from_header(bus, buffer, length, fds, n_fds, ucred, label, 0, &m);
395 if (length != BUS_MESSAGE_SIZE(m)) {
400 sz = length - sizeof(struct bus_header) - ALIGN8(BUS_MESSAGE_FIELDS_SIZE(m));
403 m->body.data = (uint8_t*) buffer + sizeof(struct bus_header) + ALIGN8(BUS_MESSAGE_FIELDS_SIZE(m));
405 m->body.sealed = true;
410 m->iovec = m->iovec_fixed;
411 m->iovec[0].iov_base = buffer;
412 m->iovec[0].iov_len = length;
414 r = bus_message_parse_fields(m);
418 /* We take possession of the memory and fds now */
419 m->free_header = true;
430 static sd_bus_message *message_new(sd_bus *bus, uint8_t type) {
433 m = malloc0(ALIGN(sizeof(sd_bus_message)) + sizeof(struct bus_header));
438 m->header = (struct bus_header*) ((uint8_t*) m + ALIGN(sizeof(struct sd_bus_message)));
439 m->header->endian = SD_BUS_NATIVE_ENDIAN;
440 m->header->type = type;
441 m->header->version = bus ? bus->message_version : 1;
442 m->allow_fds = !bus || bus->can_fds || (bus->state != BUS_HELLO && bus->state != BUS_RUNNING);
445 m->bus = sd_bus_ref(bus);
450 _public_ int sd_bus_message_new_signal(
453 const char *interface,
455 sd_bus_message **m) {
460 assert_return(!bus || bus->state != BUS_UNSET, -ENOTCONN);
461 assert_return(object_path_is_valid(path), -EINVAL);
462 assert_return(interface_name_is_valid(interface), -EINVAL);
463 assert_return(member_name_is_valid(member), -EINVAL);
464 assert_return(m, -EINVAL);
466 t = message_new(bus, SD_BUS_MESSAGE_SIGNAL);
470 t->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
472 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_PATH, SD_BUS_TYPE_OBJECT_PATH, path, &t->path);
475 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_INTERFACE, SD_BUS_TYPE_STRING, interface, &t->interface);
478 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_MEMBER, SD_BUS_TYPE_STRING, member, &t->member);
486 sd_bus_message_unref(t);
490 _public_ int sd_bus_message_new_method_call(
492 const char *destination,
494 const char *interface,
496 sd_bus_message **m) {
501 assert_return(!bus || bus->state != BUS_UNSET, -ENOTCONN);
502 assert_return(!destination || service_name_is_valid(destination), -EINVAL);
503 assert_return(object_path_is_valid(path), -EINVAL);
504 assert_return(!interface || interface_name_is_valid(interface), -EINVAL);
505 assert_return(member_name_is_valid(member), -EINVAL);
506 assert_return(m, -EINVAL);
508 t = message_new(bus, SD_BUS_MESSAGE_METHOD_CALL);
512 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_PATH, SD_BUS_TYPE_OBJECT_PATH, path, &t->path);
515 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_MEMBER, SD_BUS_TYPE_STRING, member, &t->member);
520 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_INTERFACE, SD_BUS_TYPE_STRING, interface, &t->interface);
526 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &t->destination);
539 static int message_new_reply(
540 sd_bus_message *call,
542 sd_bus_message **m) {
547 assert_return(call, -EINVAL);
548 assert_return(call->sealed, -EPERM);
549 assert_return(call->header->type == SD_BUS_MESSAGE_METHOD_CALL, -EINVAL);
550 assert_return(!call->bus || call->bus->state != BUS_UNSET, -ENOTCONN);
551 assert_return(m, -EINVAL);
553 t = message_new(call->bus, type);
557 t->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
558 t->reply_serial = BUS_MESSAGE_SERIAL(call);
560 r = message_append_field_uint32(t, SD_BUS_MESSAGE_HEADER_REPLY_SERIAL, t->reply_serial);
565 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, call->sender, &t->destination);
570 t->dont_send = !!(call->header->flags & SD_BUS_MESSAGE_NO_REPLY_EXPECTED);
571 t->enforced_reply_signature = call->enforced_reply_signature;
581 _public_ int sd_bus_message_new_method_return(
582 sd_bus_message *call,
583 sd_bus_message **m) {
585 return message_new_reply(call, SD_BUS_MESSAGE_METHOD_RETURN, m);
588 _public_ int sd_bus_message_new_method_error(
589 sd_bus_message *call,
590 const sd_bus_error *e,
591 sd_bus_message **m) {
596 assert_return(sd_bus_error_is_set(e), -EINVAL);
597 assert_return(m, -EINVAL);
599 r = message_new_reply(call, SD_BUS_MESSAGE_METHOD_ERROR, &t);
603 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_ERROR_NAME, SD_BUS_TYPE_STRING, e->name, &t->error.name);
608 r = message_append_basic(t, SD_BUS_TYPE_STRING, e->message, (const void**) &t->error.message);
613 t->error._need_free = -1;
623 _public_ int sd_bus_message_new_method_errorf(
624 sd_bus_message *call,
630 _cleanup_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
633 assert_return(name, -EINVAL);
634 assert_return(m, -EINVAL);
636 va_start(ap, format);
637 bus_error_setfv(&error, name, format, ap);
640 return sd_bus_message_new_method_error(call, &error, m);
643 _public_ int sd_bus_message_new_method_errno(
644 sd_bus_message *call,
646 const sd_bus_error *p,
647 sd_bus_message **m) {
649 _cleanup_free_ sd_bus_error berror = SD_BUS_ERROR_NULL;
651 if (sd_bus_error_is_set(p))
652 return sd_bus_message_new_method_error(call, p, m);
654 sd_bus_error_set_errno(&berror, error);
656 return sd_bus_message_new_method_error(call, &berror, m);
659 _public_ int sd_bus_message_new_method_errnof(
660 sd_bus_message *call,
666 _cleanup_free_ sd_bus_error berror = SD_BUS_ERROR_NULL;
669 va_start(ap, format);
670 bus_error_set_errnofv(&berror, error, format, ap);
673 return sd_bus_message_new_method_error(call, &berror, m);
676 int bus_message_new_synthetic_error(
679 const sd_bus_error *e,
680 sd_bus_message **m) {
685 assert(sd_bus_error_is_set(e));
688 t = message_new(bus, SD_BUS_MESSAGE_METHOD_ERROR);
692 t->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
693 t->reply_serial = serial;
695 r = message_append_field_uint32(t, SD_BUS_MESSAGE_HEADER_REPLY_SERIAL, t->reply_serial);
699 if (bus && bus->unique_name) {
700 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, bus->unique_name, &t->destination);
705 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_ERROR_NAME, SD_BUS_TYPE_STRING, e->name, &t->error.name);
710 r = message_append_basic(t, SD_BUS_TYPE_STRING, e->message, (const void**) &t->error.message);
715 t->error._need_free = -1;
725 _public_ sd_bus_message* sd_bus_message_ref(sd_bus_message *m) {
726 assert_return(m, NULL);
728 assert(m->n_ref > 0);
734 _public_ sd_bus_message* sd_bus_message_unref(sd_bus_message *m) {
735 assert_return(m, NULL);
737 assert(m->n_ref > 0);
746 _public_ int sd_bus_message_get_type(sd_bus_message *m, uint8_t *type) {
747 assert_return(m, -EINVAL);
748 assert_return(type, -EINVAL);
750 *type = m->header->type;
754 _public_ int sd_bus_message_get_serial(sd_bus_message *m, uint64_t *serial) {
755 assert_return(m, -EINVAL);
756 assert_return(serial, -EINVAL);
757 assert_return(m->header->serial != 0, -ENOENT);
759 *serial = BUS_MESSAGE_SERIAL(m);
763 _public_ int sd_bus_message_get_reply_serial(sd_bus_message *m, uint64_t *serial) {
764 assert_return(m, -EINVAL);
765 assert_return(serial, -EINVAL);
766 assert_return(m->reply_serial != 0, -ENOENT);
768 *serial = m->reply_serial;
772 _public_ int sd_bus_message_get_no_reply(sd_bus_message *m) {
773 assert_return(m, -EINVAL);
775 return m->header->type == SD_BUS_MESSAGE_METHOD_CALL ? !!(m->header->flags & SD_BUS_MESSAGE_NO_REPLY_EXPECTED) : 0;
778 _public_ int sd_bus_message_get_no_auto_start(sd_bus_message *m) {
779 assert_return(m, -EINVAL);
781 return !!(m->header->flags & SD_BUS_MESSAGE_NO_AUTO_START);
784 _public_ const char *sd_bus_message_get_path(sd_bus_message *m) {
785 assert_return(m, NULL);
790 _public_ const char *sd_bus_message_get_interface(sd_bus_message *m) {
791 assert_return(m, NULL);
796 _public_ const char *sd_bus_message_get_member(sd_bus_message *m) {
797 assert_return(m, NULL);
802 _public_ const char *sd_bus_message_get_destination(sd_bus_message *m) {
803 assert_return(m, NULL);
805 return m->destination;
808 _public_ const char *sd_bus_message_get_sender(sd_bus_message *m) {
809 assert_return(m, NULL);
814 _public_ const sd_bus_error *sd_bus_message_get_error(sd_bus_message *m) {
815 assert_return(m, NULL);
816 assert_return(sd_bus_error_is_set(&m->error), NULL);
821 _public_ int sd_bus_message_get_monotonic_timestamp(sd_bus_message *m, uint64_t *usec) {
822 assert_return(m, -EINVAL);
823 assert_return(usec, -EINVAL);
824 assert_return(m->monotonic > 0, -ENODATA);
826 *usec = m->monotonic;
830 _public_ int sd_bus_message_get_realtime_timestamp(sd_bus_message *m, uint64_t *usec) {
831 assert_return(m, -EINVAL);
832 assert_return(usec, -EINVAL);
833 assert_return(m->realtime > 0, -ENODATA);
839 _public_ sd_bus_creds *sd_bus_message_get_creds(sd_bus_message *m) {
840 assert_return(m, NULL);
842 if (m->creds.mask == 0)
848 _public_ int sd_bus_message_is_signal(sd_bus_message *m,
849 const char *interface,
850 const char *member) {
851 assert_return(m, -EINVAL);
853 if (m->header->type != SD_BUS_MESSAGE_SIGNAL)
856 if (interface && (!m->interface || !streq(m->interface, interface)))
859 if (member && (!m->member || !streq(m->member, member)))
865 _public_ int sd_bus_message_is_method_call(sd_bus_message *m,
866 const char *interface,
867 const char *member) {
868 assert_return(m, -EINVAL);
870 if (m->header->type != SD_BUS_MESSAGE_METHOD_CALL)
873 if (interface && (!m->interface || !streq(m->interface, interface)))
876 if (member && (!m->member || !streq(m->member, member)))
882 _public_ int sd_bus_message_is_method_error(sd_bus_message *m, const char *name) {
883 assert_return(m, -EINVAL);
885 if (m->header->type != SD_BUS_MESSAGE_METHOD_ERROR)
888 if (name && (!m->error.name || !streq(m->error.name, name)))
894 _public_ int sd_bus_message_set_no_reply(sd_bus_message *m, int b) {
895 assert_return(m, -EINVAL);
896 assert_return(!m->sealed, -EPERM);
897 assert_return(m->header->type == SD_BUS_MESSAGE_METHOD_CALL, -EPERM);
900 m->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
902 m->header->flags &= ~SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
907 _public_ int sd_bus_message_set_no_auto_start(sd_bus_message *m, int b) {
908 assert_return(m, -EINVAL);
909 assert_return(!m->sealed, -EPERM);
912 m->header->flags |= SD_BUS_MESSAGE_NO_AUTO_START;
914 m->header->flags &= ~SD_BUS_MESSAGE_NO_AUTO_START;
919 static struct bus_container *message_get_container(sd_bus_message *m) {
922 if (m->n_containers == 0)
923 return &m->root_container;
925 assert(m->containers);
926 return m->containers + m->n_containers - 1;
929 struct bus_body_part *message_append_part(sd_bus_message *m) {
930 struct bus_body_part *part;
937 if (m->n_body_parts <= 0) {
943 part = new0(struct bus_body_part, 1);
949 m->body_end->next = part;
959 static void part_zero(struct bus_body_part *part, size_t sz) {
964 /* All other fields can be left in their defaults */
966 assert(part->memfd < 0);
969 part->is_zero = true;
973 static int part_make_space(
974 struct sd_bus_message *m,
975 struct bus_body_part *part,
984 assert(!part->sealed);
989 if (!part->data && part->memfd < 0)
990 part->memfd = bus_kernel_pop_memfd(m->bus, &part->data, &part->mapped);
992 if (part->memfd >= 0) {
995 r = ioctl(part->memfd, KDBUS_CMD_MEMFD_SIZE_SET, &u);
1001 if (!part->data || sz > part->mapped) {
1002 size_t psz = PAGE_ALIGN(sz > 0 ? sz : 1);
1004 if (part->mapped <= 0)
1005 n = mmap(NULL, psz, PROT_READ|PROT_WRITE, MAP_SHARED, part->memfd, 0);
1007 n = mremap(part->data, part->mapped, psz, MREMAP_MAYMOVE);
1009 if (n == MAP_FAILED) {
1018 part->munmap_this = true;
1020 n = realloc(part->data, MAX(sz, 1u));
1027 part->free_this = true;
1031 *q = part->data ? (uint8_t*) part->data + part->size : NULL;
1037 static void message_extend_containers(sd_bus_message *m, size_t expand) {
1038 struct bus_container *c;
1045 /* Update counters */
1046 for (c = m->containers; c < m->containers + m->n_containers; c++)
1048 *c->array_size += expand;
1051 static void *message_extend_body(sd_bus_message *m, size_t align, size_t sz) {
1052 struct bus_body_part *part = NULL;
1053 size_t start_body, end_body, padding, start_part, end_part, added;
1065 start_body = ALIGN_TO((size_t) m->header->body_size, align);
1066 end_body = start_body + sz;
1068 padding = start_body - m->header->body_size;
1069 added = padding + sz;
1071 /* Check for 32bit overflows */
1072 if (end_body > (size_t) ((uint32_t) -1)) {
1078 m->n_body_parts <= 0 ||
1079 m->body_end->sealed ||
1080 padding != ALIGN_TO(m->body_end->size, align) - m->body_end->size;
1084 part = message_append_part(m);
1088 part_zero(part, padding);
1091 part = message_append_part(m);
1095 r = part_make_space(m, part, sz, &p);
1099 struct bus_container *c;
1107 start_part = ALIGN_TO(part->size, align);
1108 end_part = start_part + sz;
1110 r = part_make_space(m, part, end_part, &p);
1115 memset(p, 0, padding);
1116 p = (uint8_t*) p + padding;
1119 /* Readjust pointers */
1120 for (c = m->containers; c < m->containers + m->n_containers; c++)
1121 c->array_size = adjust_pointer(c->array_size, op, os, part->data);
1123 m->error.message = (const char*) adjust_pointer(m->error.message, op, os, part->data);
1126 m->header->body_size = end_body;
1127 message_extend_containers(m, added);
1132 int message_append_basic(sd_bus_message *m, char type, const void *p, const void **stored) {
1133 struct bus_container *c;
1141 assert_return(m, -EINVAL);
1142 assert_return(!m->sealed, -EPERM);
1143 assert_return(bus_type_is_basic(type), -EINVAL);
1144 assert_return(!m->poisoned, -ESTALE);
1146 c = message_get_container(m);
1148 if (c->signature && c->signature[c->index]) {
1149 /* Container signature is already set */
1151 if (c->signature[c->index] != type)
1156 /* Maybe we can append to the signature? But only if this is the top-level container*/
1157 if (c->enclosing != 0)
1160 e = strextend(&c->signature, CHAR_TO_STR(type), NULL);
1169 case SD_BUS_TYPE_STRING:
1170 /* To make things easy we'll serialize a NULL string
1171 * into the empty string */
1174 /* Fall through... */
1175 case SD_BUS_TYPE_OBJECT_PATH:
1183 sz = 4 + strlen(p) + 1;
1186 case SD_BUS_TYPE_SIGNATURE:
1194 sz = 1 + strlen(p) + 1;
1197 case SD_BUS_TYPE_BOOLEAN:
1206 assert_cc(sizeof(int) == sizeof(uint32_t));
1212 case SD_BUS_TYPE_UNIX_FD: {
1220 if (!m->allow_fds) {
1233 fd = fcntl(z, F_DUPFD_CLOEXEC, 3);
1239 f = realloc(m->fds, sizeof(int) * (m->n_fds + 1));
1259 align = bus_type_get_alignment(type);
1260 sz = bus_type_get_size(type);
1267 a = message_extend_body(m, align, sz);
1273 if (type == SD_BUS_TYPE_STRING || type == SD_BUS_TYPE_OBJECT_PATH) {
1274 *(uint32_t*) a = sz - 5;
1275 memcpy((uint8_t*) a + 4, p, sz - 4);
1278 *stored = (const uint8_t*) a + 4;
1280 } else if (type == SD_BUS_TYPE_SIGNATURE) {
1281 *(uint8_t*) a = sz - 1;
1282 memcpy((uint8_t*) a + 1, p, sz - 1);
1285 *stored = (const uint8_t*) a + 1;
1286 } else if (type == SD_BUS_TYPE_UNIX_FD) {
1287 *(uint32_t*) a = fdi;
1301 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1308 close_nointr_nofail(fd);
1313 _public_ int sd_bus_message_append_basic(sd_bus_message *m, char type, const void *p) {
1314 return message_append_basic(m, type, p, NULL);
1317 _public_ int sd_bus_message_append_string_space(
1322 struct bus_container *c;
1325 assert_return(m, -EINVAL);
1326 assert_return(s, -EINVAL);
1327 assert_return(!m->sealed, -EPERM);
1328 assert_return(!m->poisoned, -ESTALE);
1330 c = message_get_container(m);
1332 if (c->signature && c->signature[c->index]) {
1333 /* Container signature is already set */
1335 if (c->signature[c->index] != SD_BUS_TYPE_STRING)
1340 /* Maybe we can append to the signature? But only if this is the top-level container*/
1341 if (c->enclosing != 0)
1344 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRING), NULL);
1351 a = message_extend_body(m, 4, 4 + size + 1);
1355 *(uint32_t*) a = size;
1360 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1366 _public_ int sd_bus_message_append_string_iovec(
1368 const struct iovec *iov,
1376 assert_return(m, -EINVAL);
1377 assert_return(!m->sealed, -EPERM);
1378 assert_return(iov || n == 0, -EINVAL);
1379 assert_return(!m->poisoned, -ESTALE);
1381 size = IOVEC_TOTAL_SIZE(iov, n);
1383 r = sd_bus_message_append_string_space(m, size, &p);
1387 for (i = 0; i < n; i++) {
1389 if (iov[i].iov_base)
1390 memcpy(p, iov[i].iov_base, iov[i].iov_len);
1392 memset(p, ' ', iov[i].iov_len);
1394 p += iov[i].iov_len;
1400 static int bus_message_open_array(
1402 struct bus_container *c,
1403 const char *contents,
1404 uint32_t **array_size) {
1410 struct bus_body_part *o;
1417 if (!signature_is_single(contents, true))
1420 alignment = bus_type_get_alignment(contents[0]);
1424 if (c->signature && c->signature[c->index]) {
1426 /* Verify the existing signature */
1428 if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
1431 if (!startswith(c->signature + c->index + 1, contents))
1434 nindex = c->index + 1 + strlen(contents);
1438 if (c->enclosing != 0)
1441 /* Extend the existing signature */
1443 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_ARRAY), contents, NULL);
1449 nindex = e - c->signature;
1452 a = message_extend_body(m, 4, 4);
1457 op = m->body_end->data;
1458 os = m->body_end->size;
1460 /* Add alignment between size and first element */
1461 if (!message_extend_body(m, alignment, 0))
1464 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1467 /* location of array size might have changed so let's readjust a */
1468 if (o == m->body_end)
1469 a = adjust_pointer(a, op, os, m->body_end->data);
1476 static int bus_message_open_variant(
1478 struct bus_container *c,
1479 const char *contents) {
1488 if (!signature_is_single(contents, false))
1491 if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
1494 if (c->signature && c->signature[c->index]) {
1496 if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
1502 if (c->enclosing != 0)
1505 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_VARIANT), NULL);
1512 l = strlen(contents);
1513 a = message_extend_body(m, 1, 1 + l + 1);
1518 memcpy((uint8_t*) a + 1, contents, l + 1);
1520 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1526 static int bus_message_open_struct(
1528 struct bus_container *c,
1529 const char *contents) {
1537 if (!signature_is_valid(contents, false))
1540 if (c->signature && c->signature[c->index]) {
1543 l = strlen(contents);
1545 if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
1546 !startswith(c->signature + c->index + 1, contents) ||
1547 c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
1550 nindex = c->index + 1 + l + 1;
1554 if (c->enclosing != 0)
1557 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_BEGIN), contents, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_END), NULL);
1563 nindex = e - c->signature;
1566 /* Align contents to 8 byte boundary */
1567 if (!message_extend_body(m, 8, 0))
1570 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1576 static int bus_message_open_dict_entry(
1578 struct bus_container *c,
1579 const char *contents) {
1587 if (!signature_is_pair(contents))
1590 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1593 if (c->signature && c->signature[c->index]) {
1596 l = strlen(contents);
1598 if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
1599 !startswith(c->signature + c->index + 1, contents) ||
1600 c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
1603 nindex = c->index + 1 + l + 1;
1607 /* Align contents to 8 byte boundary */
1608 if (!message_extend_body(m, 8, 0))
1611 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1617 _public_ int sd_bus_message_open_container(
1620 const char *contents) {
1622 struct bus_container *c, *w;
1623 uint32_t *array_size = NULL;
1628 assert_return(m, -EINVAL);
1629 assert_return(!m->sealed, -EPERM);
1630 assert_return(contents, -EINVAL);
1631 assert_return(!m->poisoned, -ESTALE);
1633 /* Make sure we have space for one more container */
1634 w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
1642 c = message_get_container(m);
1644 signature = strdup(contents);
1650 /* Save old index in the parent container, in case we have to
1651 * abort this container */
1652 c->saved_index = c->index;
1653 before = m->header->body_size;
1655 if (type == SD_BUS_TYPE_ARRAY)
1656 r = bus_message_open_array(m, c, contents, &array_size);
1657 else if (type == SD_BUS_TYPE_VARIANT)
1658 r = bus_message_open_variant(m, c, contents);
1659 else if (type == SD_BUS_TYPE_STRUCT)
1660 r = bus_message_open_struct(m, c, contents);
1661 else if (type == SD_BUS_TYPE_DICT_ENTRY)
1662 r = bus_message_open_dict_entry(m, c, contents);
1671 /* OK, let's fill it in */
1672 w += m->n_containers++;
1673 w->enclosing = type;
1674 w->signature = signature;
1676 w->array_size = array_size;
1678 w->begin = m->rindex;
1683 _public_ int sd_bus_message_close_container(sd_bus_message *m) {
1684 struct bus_container *c;
1686 assert_return(m, -EINVAL);
1687 assert_return(!m->sealed, -EPERM);
1688 assert_return(m->n_containers > 0, -EINVAL);
1689 assert_return(!m->poisoned, -ESTALE);
1691 c = message_get_container(m);
1692 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1693 if (c->signature && c->signature[c->index] != 0)
1708 static int type_stack_push(TypeStack *stack, unsigned max, unsigned *i, const char *types, unsigned n_struct, unsigned n_array) {
1715 stack[*i].types = types;
1716 stack[*i].n_struct = n_struct;
1717 stack[*i].n_array = n_array;
1723 static int type_stack_pop(TypeStack *stack, unsigned max, unsigned *i, const char **types, unsigned *n_struct, unsigned *n_array) {
1734 *types = stack[*i].types;
1735 *n_struct = stack[*i].n_struct;
1736 *n_array = stack[*i].n_array;
1741 int bus_message_append_ap(
1746 unsigned n_array, n_struct;
1747 TypeStack stack[BUS_CONTAINER_DEPTH];
1748 unsigned stack_ptr = 0;
1756 n_array = (unsigned) -1;
1757 n_struct = strlen(types);
1762 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
1763 r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
1769 r = sd_bus_message_close_container(m);
1777 if (n_array != (unsigned) -1)
1786 case SD_BUS_TYPE_BYTE: {
1789 x = (uint8_t) va_arg(ap, int);
1790 r = sd_bus_message_append_basic(m, *t, &x);
1794 case SD_BUS_TYPE_BOOLEAN:
1795 case SD_BUS_TYPE_INT32:
1796 case SD_BUS_TYPE_UINT32:
1797 case SD_BUS_TYPE_UNIX_FD: {
1800 /* We assume a boolean is the same as int32_t */
1801 assert_cc(sizeof(int32_t) == sizeof(int));
1803 x = va_arg(ap, uint32_t);
1804 r = sd_bus_message_append_basic(m, *t, &x);
1808 case SD_BUS_TYPE_INT16:
1809 case SD_BUS_TYPE_UINT16: {
1812 x = (uint16_t) va_arg(ap, int);
1813 r = sd_bus_message_append_basic(m, *t, &x);
1817 case SD_BUS_TYPE_INT64:
1818 case SD_BUS_TYPE_UINT64:
1819 case SD_BUS_TYPE_DOUBLE: {
1822 x = va_arg(ap, uint64_t);
1823 r = sd_bus_message_append_basic(m, *t, &x);
1827 case SD_BUS_TYPE_STRING:
1828 case SD_BUS_TYPE_OBJECT_PATH:
1829 case SD_BUS_TYPE_SIGNATURE: {
1832 x = va_arg(ap, const char*);
1833 r = sd_bus_message_append_basic(m, *t, x);
1837 case SD_BUS_TYPE_ARRAY: {
1840 r = signature_element_length(t + 1, &k);
1846 memcpy(s, t + 1, k);
1849 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, s);
1854 if (n_array == (unsigned) -1) {
1859 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
1865 n_array = va_arg(ap, unsigned);
1870 case SD_BUS_TYPE_VARIANT: {
1873 s = va_arg(ap, const char*);
1877 r = sd_bus_message_open_container(m, SD_BUS_TYPE_VARIANT, s);
1881 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
1886 n_struct = strlen(s);
1887 n_array = (unsigned) -1;
1892 case SD_BUS_TYPE_STRUCT_BEGIN:
1893 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
1896 r = signature_element_length(t, &k);
1903 memcpy(s, t + 1, k - 2);
1906 r = sd_bus_message_open_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
1911 if (n_array == (unsigned) -1) {
1916 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
1922 n_array = (unsigned) -1;
1938 _public_ int sd_bus_message_append(sd_bus_message *m, const char *types, ...) {
1942 assert_return(m, -EINVAL);
1943 assert_return(types, -EINVAL);
1944 assert_return(!m->sealed, -EPERM);
1945 assert_return(!m->poisoned, -ESTALE);
1947 va_start(ap, types);
1948 r = bus_message_append_ap(m, types, ap);
1954 _public_ int sd_bus_message_append_array_space(sd_bus_message *m,
1962 assert_return(m, -EINVAL);
1963 assert_return(!m->sealed, -EPERM);
1964 assert_return(bus_type_is_trivial(type), -EINVAL);
1965 assert_return(ptr || size == 0, -EINVAL);
1966 assert_return(!m->poisoned, -ESTALE);
1968 align = bus_type_get_alignment(type);
1969 sz = bus_type_get_size(type);
1971 assert_se(align > 0);
1977 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
1981 a = message_extend_body(m, align, size);
1985 r = sd_bus_message_close_container(m);
1993 _public_ int sd_bus_message_append_array(sd_bus_message *m,
2000 assert_return(m, -EINVAL);
2001 assert_return(!m->sealed, -EPERM);
2002 assert_return(bus_type_is_trivial(type), -EINVAL);
2003 assert_return(ptr || size == 0, -EINVAL);
2004 assert_return(!m->poisoned, -ESTALE);
2006 r = sd_bus_message_append_array_space(m, type, size, &p);
2011 memcpy(p, ptr, size);
2016 _public_ int sd_bus_message_append_array_iovec(
2019 const struct iovec *iov,
2027 assert_return(m, -EINVAL);
2028 assert_return(!m->sealed, -EPERM);
2029 assert_return(bus_type_is_trivial(type), -EINVAL);
2030 assert_return(iov || n == 0, -EINVAL);
2031 assert_return(!m->poisoned, -ESTALE);
2033 size = IOVEC_TOTAL_SIZE(iov, n);
2035 r = sd_bus_message_append_array_space(m, type, size, &p);
2039 for (i = 0; i < n; i++) {
2041 if (iov[i].iov_base)
2042 memcpy(p, iov[i].iov_base, iov[i].iov_len);
2044 memset(p, 0, iov[i].iov_len);
2046 p = (uint8_t*) p + iov[i].iov_len;
2052 _public_ int sd_bus_message_append_array_memfd(sd_bus_message *m,
2055 _cleanup_close_ int copy_fd = -1;
2056 struct bus_body_part *part;
2068 if (!bus_type_is_trivial(type))
2073 r = sd_memfd_set_sealed(memfd, true);
2077 copy_fd = sd_memfd_dup_fd(memfd);
2081 r = sd_memfd_get_size(memfd, &size);
2085 align = bus_type_get_alignment(type);
2086 sz = bus_type_get_size(type);
2088 assert_se(align > 0);
2094 if (size > (uint64_t) (uint32_t) -1)
2097 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
2101 a = message_extend_body(m, align, 0);
2105 part = message_append_part(m);
2109 part->memfd = copy_fd;
2110 part->sealed = true;
2114 message_extend_containers(m, size);
2115 m->header->body_size += size;
2117 return sd_bus_message_close_container(m);
2120 _public_ int sd_bus_message_append_string_memfd(sd_bus_message *m, sd_memfd *memfd) {
2121 _cleanup_close_ int copy_fd = -1;
2122 struct bus_body_part *part;
2123 struct bus_container *c;
2128 assert_return(m, -EINVAL);
2129 assert_return(memfd, -EINVAL);
2130 assert_return(!m->sealed, -EPERM);
2131 assert_return(!m->poisoned, -ESTALE);
2133 r = sd_memfd_set_sealed(memfd, true);
2137 copy_fd = sd_memfd_dup_fd(memfd);
2141 r = sd_memfd_get_size(memfd, &size);
2145 /* We require this to be NUL terminated */
2149 if (size > (uint64_t) (uint32_t) -1)
2152 c = message_get_container(m);
2153 if (c->signature && c->signature[c->index]) {
2154 /* Container signature is already set */
2156 if (c->signature[c->index] != SD_BUS_TYPE_STRING)
2161 /* Maybe we can append to the signature? But only if this is the top-level container*/
2162 if (c->enclosing != 0)
2165 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRING), NULL);
2172 a = message_extend_body(m, 4, 4);
2176 *(uint32_t*) a = size - 1;
2178 part = message_append_part(m);
2182 part->memfd = copy_fd;
2183 part->sealed = true;
2187 message_extend_containers(m, size);
2188 m->header->body_size += size;
2190 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2196 _public_ int sd_bus_message_append_strv(sd_bus_message *m, char **l) {
2200 assert_return(m, -EINVAL);
2201 assert_return(!m->sealed, -EPERM);
2202 assert_return(!m->poisoned, -ESTALE);
2204 r = sd_bus_message_open_container(m, 'a', "s");
2208 STRV_FOREACH(i, l) {
2209 r = sd_bus_message_append_basic(m, 's', *i);
2214 return sd_bus_message_close_container(m);
2217 int bus_body_part_map(struct bus_body_part *part) {
2226 if (part->size <= 0)
2229 /* For smaller zero parts (as used for padding) we don't need to map anything... */
2230 if (part->memfd < 0 && part->is_zero && part->size < 8) {
2231 static const uint8_t zeroes[7] = { };
2232 part->data = (void*) zeroes;
2236 psz = PAGE_ALIGN(part->size);
2238 if (part->memfd >= 0)
2239 p = mmap(NULL, psz, PROT_READ, MAP_SHARED, part->memfd, 0);
2240 else if (part->is_zero)
2241 p = mmap(NULL, psz, PROT_READ, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
2245 if (p == MAP_FAILED)
2250 part->munmap_this = true;
2255 void bus_body_part_unmap(struct bus_body_part *part) {
2259 if (part->memfd < 0)
2265 if (!part->munmap_this)
2268 assert_se(munmap(part->data, part->mapped) == 0);
2272 part->munmap_this = false;
2277 static int buffer_peek(const void *p, uint32_t sz, size_t *rindex, size_t align, size_t nbytes, void **r) {
2278 size_t k, start, end;
2283 start = ALIGN_TO((size_t) *rindex, align);
2284 end = start + nbytes;
2289 /* Verify that padding is 0 */
2290 for (k = *rindex; k < start; k++)
2291 if (((const uint8_t*) p)[k] != 0)
2295 *r = (uint8_t*) p + start;
2302 static bool message_end_of_signature(sd_bus_message *m) {
2303 struct bus_container *c;
2307 c = message_get_container(m);
2308 return !c->signature || c->signature[c->index] == 0;
2311 static bool message_end_of_array(sd_bus_message *m, size_t index) {
2312 struct bus_container *c;
2316 c = message_get_container(m);
2320 return index >= c->begin + BUS_MESSAGE_BSWAP32(m, *c->array_size);
2323 _public_ int sd_bus_message_at_end(sd_bus_message *m, int complete) {
2324 assert_return(m, -EINVAL);
2325 assert_return(m->sealed, -EPERM);
2327 if (complete && m->n_containers > 0)
2330 if (message_end_of_signature(m))
2333 if (message_end_of_array(m, m->rindex))
2339 static struct bus_body_part* find_part(sd_bus_message *m, size_t index, size_t sz, void **p) {
2340 struct bus_body_part *part;
2346 if (m->cached_rindex_part && index >= m->cached_rindex_part_begin) {
2347 part = m->cached_rindex_part;
2348 begin = m->cached_rindex_part_begin;
2358 if (index + sz <= begin + part->size) {
2360 r = bus_body_part_map(part);
2365 *p = (uint8_t*) part->data + index - begin;
2367 m->cached_rindex_part = part;
2368 m->cached_rindex_part_begin = begin;
2373 begin += part->size;
2380 static int message_peek_body(
2387 size_t k, start, end, padding;
2388 struct bus_body_part *part;
2395 if (message_end_of_array(m, *rindex))
2398 start = ALIGN_TO((size_t) *rindex, align);
2399 padding = start - *rindex;
2400 end = start + nbytes;
2402 if (end > BUS_MESSAGE_BODY_SIZE(m))
2405 part = find_part(m, *rindex, padding, (void**) &q);
2410 /* Verify padding */
2411 for (k = 0; k < padding; k++)
2416 part = find_part(m, start, nbytes, (void**) &q);
2428 static bool validate_nul(const char *s, size_t l) {
2430 /* Check for NUL chars in the string */
2431 if (memchr(s, 0, l))
2434 /* Check for NUL termination */
2441 static bool validate_string(const char *s, size_t l) {
2443 if (!validate_nul(s, l))
2446 /* Check if valid UTF8 */
2447 if (!utf8_is_valid(s))
2453 static bool validate_signature(const char *s, size_t l) {
2455 if (!validate_nul(s, l))
2458 /* Check if valid signature */
2459 if (!signature_is_valid(s, true))
2465 static bool validate_object_path(const char *s, size_t l) {
2467 if (!validate_nul(s, l))
2470 if (!object_path_is_valid(s))
2476 _public_ int sd_bus_message_read_basic(sd_bus_message *m, char type, void *p) {
2477 struct bus_container *c;
2481 assert_return(m, -EINVAL);
2482 assert_return(m->sealed, -EPERM);
2483 assert_return(bus_type_is_basic(type), -EINVAL);
2485 if (message_end_of_signature(m))
2488 if (message_end_of_array(m, m->rindex))
2491 c = message_get_container(m);
2492 if (c->signature[c->index] != type)
2497 case SD_BUS_TYPE_STRING:
2498 case SD_BUS_TYPE_OBJECT_PATH: {
2503 r = message_peek_body(m, &rindex, 4, 4, &q);
2507 l = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2508 r = message_peek_body(m, &rindex, 1, l+1, &q);
2514 if (type == SD_BUS_TYPE_OBJECT_PATH) {
2515 if (!validate_object_path(q, l))
2518 if (!validate_string(q, l))
2524 *(const char**) p = q;
2529 case SD_BUS_TYPE_SIGNATURE: {
2534 r = message_peek_body(m, &rindex, 1, 1, &q);
2539 r = message_peek_body(m, &rindex, 1, l+1, &q);
2545 if (!validate_signature(q, l))
2551 *(const char**) p = q;
2559 align = bus_type_get_alignment(type);
2560 sz = bus_type_get_size(type);
2561 assert(align > 0 && sz > 0);
2564 r = message_peek_body(m, &rindex, align, sz, &q);
2570 case SD_BUS_TYPE_BYTE:
2572 *(uint8_t*) p = *(uint8_t*) q;
2575 case SD_BUS_TYPE_BOOLEAN:
2577 *(int*) p = !!*(uint32_t*) q;
2580 case SD_BUS_TYPE_INT16:
2581 case SD_BUS_TYPE_UINT16:
2583 *(uint16_t*) p = BUS_MESSAGE_BSWAP16(m, *(uint16_t*) q);
2586 case SD_BUS_TYPE_INT32:
2587 case SD_BUS_TYPE_UINT32:
2589 *(uint32_t*) p = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2592 case SD_BUS_TYPE_INT64:
2593 case SD_BUS_TYPE_UINT64:
2594 case SD_BUS_TYPE_DOUBLE:
2596 *(uint64_t*) p = BUS_MESSAGE_BSWAP64(m, *(uint64_t*) q);
2599 case SD_BUS_TYPE_UNIX_FD: {
2602 j = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2607 *(int*) p = m->fds[j];
2612 assert_not_reached("Unknown basic type...");
2621 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2627 static int bus_message_enter_array(
2629 struct bus_container *c,
2630 const char *contents,
2631 uint32_t **array_size) {
2642 if (!signature_is_single(contents, true))
2645 alignment = bus_type_get_alignment(contents[0]);
2649 if (!c->signature || c->signature[c->index] == 0)
2652 if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
2655 if (!startswith(c->signature + c->index + 1, contents))
2659 r = message_peek_body(m, &rindex, 4, 4, &q);
2663 if (BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q) > BUS_ARRAY_MAX_SIZE)
2666 r = message_peek_body(m, &rindex, alignment, 0, NULL);
2672 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2673 c->index += 1 + strlen(contents);
2677 *array_size = (uint32_t*) q;
2682 static int bus_message_enter_variant(
2684 struct bus_container *c,
2685 const char *contents) {
2696 if (!signature_is_single(contents, false))
2699 if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
2702 if (!c->signature || c->signature[c->index] == 0)
2705 if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
2709 r = message_peek_body(m, &rindex, 1, 1, &q);
2714 r = message_peek_body(m, &rindex, 1, l+1, &q);
2720 if (!validate_signature(q, l))
2723 if (!streq(q, contents))
2726 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2734 static int bus_message_enter_struct(
2736 struct bus_container *c,
2737 const char *contents) {
2746 if (!signature_is_valid(contents, false))
2749 if (!c->signature || c->signature[c->index] == 0)
2752 l = strlen(contents);
2754 if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
2755 !startswith(c->signature + c->index + 1, contents) ||
2756 c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
2759 r = message_peek_body(m, &m->rindex, 8, 0, NULL);
2763 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2764 c->index += 1 + l + 1;
2769 static int bus_message_enter_dict_entry(
2771 struct bus_container *c,
2772 const char *contents) {
2781 if (!signature_is_pair(contents))
2784 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2787 if (!c->signature || c->signature[c->index] == 0)
2790 l = strlen(contents);
2792 if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
2793 !startswith(c->signature + c->index + 1, contents) ||
2794 c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
2797 r = message_peek_body(m, &m->rindex, 8, 0, NULL);
2801 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2802 c->index += 1 + l + 1;
2807 _public_ int sd_bus_message_enter_container(sd_bus_message *m,
2809 const char *contents) {
2810 struct bus_container *c, *w;
2811 uint32_t *array_size = NULL;
2816 assert_return(m, -EINVAL);
2817 assert_return(m->sealed, -EPERM);
2818 assert_return(type != 0 || !contents, -EINVAL);
2820 if (type == 0 || !contents) {
2824 /* Allow entering into anonymous containers */
2825 r = sd_bus_message_peek_type(m, &tt, &cc);
2829 if (type != 0 && type != tt)
2832 if (contents && !streq(contents, cc))
2840 * We enforce a global limit on container depth, that is much
2841 * higher than the 32 structs and 32 arrays the specification
2842 * mandates. This is simpler to implement for us, and we need
2843 * this only to ensure our container array doesn't grow
2844 * without bounds. We are happy to return any data from a
2845 * message as long as the data itself is valid, even if the
2846 * overall message might be not.
2848 * Note that the message signature is validated when
2849 * parsing the headers, and that validation does check the
2852 * Note that the specification defines no limits on the depth
2853 * of stacked variants, but we do.
2855 if (m->n_containers >= BUS_CONTAINER_DEPTH)
2858 w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
2863 if (message_end_of_signature(m))
2866 if (message_end_of_array(m, m->rindex))
2869 c = message_get_container(m);
2871 signature = strdup(contents);
2875 c->saved_index = c->index;
2878 if (type == SD_BUS_TYPE_ARRAY)
2879 r = bus_message_enter_array(m, c, contents, &array_size);
2880 else if (type == SD_BUS_TYPE_VARIANT)
2881 r = bus_message_enter_variant(m, c, contents);
2882 else if (type == SD_BUS_TYPE_STRUCT)
2883 r = bus_message_enter_struct(m, c, contents);
2884 else if (type == SD_BUS_TYPE_DICT_ENTRY)
2885 r = bus_message_enter_dict_entry(m, c, contents);
2894 /* OK, let's fill it in */
2895 w += m->n_containers++;
2896 w->enclosing = type;
2897 w->signature = signature;
2899 w->array_size = array_size;
2901 w->begin = m->rindex;
2906 _public_ int sd_bus_message_exit_container(sd_bus_message *m) {
2907 struct bus_container *c;
2909 assert_return(m, -EINVAL);
2910 assert_return(m->sealed, -EPERM);
2911 assert_return(m->n_containers > 0, -ENXIO);
2913 c = message_get_container(m);
2914 if (c->enclosing == SD_BUS_TYPE_ARRAY) {
2917 l = BUS_MESSAGE_BSWAP32(m, *c->array_size);
2918 if (c->begin + l != m->rindex)
2922 if (c->signature && c->signature[c->index] != 0)
2932 static void message_quit_container(sd_bus_message *m) {
2933 struct bus_container *c;
2937 assert(m->n_containers > 0);
2939 c = message_get_container(m);
2942 assert(m->rindex >= c->before);
2943 m->rindex = c->before;
2945 /* Free container */
2949 /* Correct index of new top-level container */
2950 c = message_get_container(m);
2951 c->index = c->saved_index;
2954 _public_ int sd_bus_message_peek_type(sd_bus_message *m, char *type, const char **contents) {
2955 struct bus_container *c;
2958 assert_return(m, -EINVAL);
2959 assert_return(m->sealed, -EPERM);
2961 if (message_end_of_signature(m))
2964 if (message_end_of_array(m, m->rindex))
2967 c = message_get_container(m);
2969 if (bus_type_is_basic(c->signature[c->index])) {
2973 *type = c->signature[c->index];
2977 if (c->signature[c->index] == SD_BUS_TYPE_ARRAY) {
2983 r = signature_element_length(c->signature+c->index+1, &l);
2989 sig = strndup(c->signature + c->index + 1, l);
2993 free(m->peeked_signature);
2994 m->peeked_signature = sig;
3000 *type = SD_BUS_TYPE_ARRAY;
3005 if (c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ||
3006 c->signature[c->index] == SD_BUS_TYPE_DICT_ENTRY_BEGIN) {
3012 r = signature_element_length(c->signature+c->index, &l);
3017 sig = strndup(c->signature + c->index + 1, l - 2);
3021 free(m->peeked_signature);
3022 m->peeked_signature = sig;
3028 *type = c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY;
3033 if (c->signature[c->index] == SD_BUS_TYPE_VARIANT) {
3039 r = message_peek_body(m, &rindex, 1, 1, &q);
3046 r = message_peek_body(m, &rindex, 1, l+1, &q);
3052 if (!validate_signature(q, l))
3059 *type = SD_BUS_TYPE_VARIANT;
3074 _public_ int sd_bus_message_rewind(sd_bus_message *m, int complete) {
3075 struct bus_container *c;
3077 assert_return(m, -EINVAL);
3078 assert_return(m->sealed, -EPERM);
3081 message_reset_containers(m);
3083 m->root_container.index = 0;
3085 c = message_get_container(m);
3087 c = message_get_container(m);
3090 m->rindex = c->begin;
3093 return !isempty(c->signature);
3096 static int message_read_ap(
3101 unsigned n_array, n_struct;
3102 TypeStack stack[BUS_CONTAINER_DEPTH];
3103 unsigned stack_ptr = 0;
3104 unsigned n_loop = 0;
3112 /* Ideally, we'd just call ourselves recursively on every
3113 * complex type. However, the state of a va_list that is
3114 * passed to a function is undefined after that function
3115 * returns. This means we need to docode the va_list linearly
3116 * in a single stackframe. We hence implement our own
3117 * home-grown stack in an array. */
3119 n_array = (unsigned) -1; /* lenght of current array entries */
3120 n_struct = strlen(types); /* length of current struct contents signature */
3127 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
3128 r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
3134 r = sd_bus_message_exit_container(m);
3142 if (n_array != (unsigned) -1)
3151 case SD_BUS_TYPE_BYTE:
3152 case SD_BUS_TYPE_BOOLEAN:
3153 case SD_BUS_TYPE_INT16:
3154 case SD_BUS_TYPE_UINT16:
3155 case SD_BUS_TYPE_INT32:
3156 case SD_BUS_TYPE_UINT32:
3157 case SD_BUS_TYPE_INT64:
3158 case SD_BUS_TYPE_UINT64:
3159 case SD_BUS_TYPE_DOUBLE:
3160 case SD_BUS_TYPE_STRING:
3161 case SD_BUS_TYPE_OBJECT_PATH:
3162 case SD_BUS_TYPE_SIGNATURE:
3163 case SD_BUS_TYPE_UNIX_FD: {
3166 p = va_arg(ap, void*);
3167 r = sd_bus_message_read_basic(m, *t, p);
3180 case SD_BUS_TYPE_ARRAY: {
3183 r = signature_element_length(t + 1, &k);
3189 memcpy(s, t + 1, k);
3192 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, s);
3203 if (n_array == (unsigned) -1) {
3208 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
3214 n_array = va_arg(ap, unsigned);
3219 case SD_BUS_TYPE_VARIANT: {
3222 s = va_arg(ap, const char *);
3226 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, s);
3236 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
3241 n_struct = strlen(s);
3242 n_array = (unsigned) -1;
3247 case SD_BUS_TYPE_STRUCT_BEGIN:
3248 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
3251 r = signature_element_length(t, &k);
3257 memcpy(s, t + 1, k - 2);
3260 r = sd_bus_message_enter_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
3270 if (n_array == (unsigned) -1) {
3275 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
3281 n_array = (unsigned) -1;
3294 _public_ int sd_bus_message_read(sd_bus_message *m, const char *types, ...) {
3298 assert_return(m, -EINVAL);
3299 assert_return(m->sealed, -EPERM);
3300 assert_return(types, -EINVAL);
3302 va_start(ap, types);
3303 r = message_read_ap(m, types, ap);
3309 _public_ int sd_bus_message_skip(sd_bus_message *m, const char *types) {
3312 assert_return(m, -EINVAL);
3313 assert_return(m->sealed, -EPERM);
3314 assert_return(types, -EINVAL);
3321 case SD_BUS_TYPE_BYTE:
3322 case SD_BUS_TYPE_BOOLEAN:
3323 case SD_BUS_TYPE_INT16:
3324 case SD_BUS_TYPE_UINT16:
3325 case SD_BUS_TYPE_INT32:
3326 case SD_BUS_TYPE_UINT32:
3327 case SD_BUS_TYPE_INT64:
3328 case SD_BUS_TYPE_UINT64:
3329 case SD_BUS_TYPE_DOUBLE:
3330 case SD_BUS_TYPE_STRING:
3331 case SD_BUS_TYPE_OBJECT_PATH:
3332 case SD_BUS_TYPE_SIGNATURE:
3333 case SD_BUS_TYPE_UNIX_FD:
3335 r = sd_bus_message_read_basic(m, *types, NULL);
3339 r = sd_bus_message_skip(m, types + 1);
3345 case SD_BUS_TYPE_ARRAY: {
3348 r = signature_element_length(types + 1, &k);
3354 memcpy(s, types+1, k);
3357 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, s);
3362 r = sd_bus_message_skip(m, s);
3369 r = sd_bus_message_exit_container(m);
3374 r = sd_bus_message_skip(m, types + 1 + k);
3381 case SD_BUS_TYPE_VARIANT: {
3382 const char *contents;
3385 r = sd_bus_message_peek_type(m, &x, &contents);
3389 if (x != SD_BUS_TYPE_VARIANT)
3392 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, contents);
3396 r = sd_bus_message_skip(m, contents);
3401 r = sd_bus_message_exit_container(m);
3405 r = sd_bus_message_skip(m, types + 1);
3412 case SD_BUS_TYPE_STRUCT_BEGIN:
3413 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
3416 r = signature_element_length(types, &k);
3422 memcpy(s, types+1, k-2);
3425 r = sd_bus_message_enter_container(m, *types == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
3429 r = sd_bus_message_skip(m, s);
3434 r = sd_bus_message_exit_container(m);
3439 r = sd_bus_message_skip(m, types + k);
3451 _public_ int sd_bus_message_read_array(sd_bus_message *m,
3455 struct bus_container *c;
3461 assert_return(m, -EINVAL);
3462 assert_return(m->sealed, -EPERM);
3463 assert_return(bus_type_is_trivial(type), -EINVAL);
3464 assert_return(ptr, -EINVAL);
3465 assert_return(size, -EINVAL);
3466 assert_return(!BUS_MESSAGE_NEED_BSWAP(m), -ENOTSUP);
3468 align = bus_type_get_alignment(type);
3472 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
3476 c = message_get_container(m);
3477 sz = BUS_MESSAGE_BSWAP32(m, *c->array_size);
3480 /* Zero length array, let's return some aligned
3481 * pointer that is not NULL */
3482 p = (uint8_t*) NULL + align;
3484 r = message_peek_body(m, &m->rindex, align, sz, &p);
3493 r = sd_bus_message_exit_container(m);
3497 *ptr = (const void*) p;
3503 message_quit_container(m);
3507 static int message_peek_fields(
3518 return buffer_peek(BUS_MESSAGE_FIELDS(m), BUS_MESSAGE_FIELDS_SIZE(m), rindex, align, nbytes, ret);
3521 static int message_peek_field_uint32(
3532 r = message_peek_fields(m, ri, 4, 4, &q);
3537 *ret = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
3542 static int message_peek_field_string(
3544 bool (*validate)(const char *p),
3555 r = message_peek_field_uint32(m, ri, &l);
3559 r = message_peek_fields(m, ri, 1, l+1, &q);
3564 if (!validate_nul(q, l))
3570 if (!validate_string(q, l))
3580 static int message_peek_field_signature(
3592 r = message_peek_fields(m, ri, 1, 1, &q);
3597 r = message_peek_fields(m, ri, 1, l+1, &q);
3601 if (!validate_signature(q, l))
3610 static int message_skip_fields(
3613 uint32_t array_size,
3614 const char **signature) {
3616 size_t original_index;
3623 original_index = *ri;
3629 if (array_size != (uint32_t) -1 &&
3630 array_size <= *ri - original_index)
3637 if (t == SD_BUS_TYPE_STRING) {
3639 r = message_peek_field_string(m, NULL, ri, NULL);
3645 } else if (t == SD_BUS_TYPE_OBJECT_PATH) {
3647 r = message_peek_field_string(m, object_path_is_valid, ri, NULL);
3653 } else if (t == SD_BUS_TYPE_SIGNATURE) {
3655 r = message_peek_field_signature(m, ri, NULL);
3661 } else if (bus_type_is_basic(t)) {
3664 align = bus_type_get_alignment(t);
3665 k = bus_type_get_size(t);
3666 assert(align > 0 && k > 0);
3668 r = message_peek_fields(m, ri, align, k, NULL);
3674 } else if (t == SD_BUS_TYPE_ARRAY) {
3676 r = signature_element_length(*signature+1, &l);
3686 strncpy(sig, *signature + 1, l-1);
3689 alignment = bus_type_get_alignment(sig[0]);
3693 r = message_peek_field_uint32(m, ri, &nas);
3696 if (nas > BUS_ARRAY_MAX_SIZE)
3699 r = message_peek_fields(m, ri, alignment, 0, NULL);
3703 r = message_skip_fields(m, ri, nas, (const char**) &s);
3708 (*signature) += 1 + l;
3710 } else if (t == SD_BUS_TYPE_VARIANT) {
3713 r = message_peek_field_signature(m, ri, &s);
3717 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
3723 } else if (t == SD_BUS_TYPE_STRUCT ||
3724 t == SD_BUS_TYPE_DICT_ENTRY) {
3726 r = signature_element_length(*signature, &l);
3733 strncpy(sig, *signature + 1, l-1);
3736 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
3747 int bus_message_parse_fields(sd_bus_message *m) {
3750 uint32_t unix_fds = 0;
3754 for (ri = 0; ri < BUS_MESSAGE_FIELDS_SIZE(m); ) {
3755 const char *signature;
3758 r = message_peek_fields(m, &ri, 8, 1, (void**) &header);
3762 r = message_peek_field_signature(m, &ri, &signature);
3767 case _SD_BUS_MESSAGE_HEADER_INVALID:
3770 case SD_BUS_MESSAGE_HEADER_PATH:
3775 if (!streq(signature, "o"))
3778 r = message_peek_field_string(m, object_path_is_valid, &ri, &m->path);
3781 case SD_BUS_MESSAGE_HEADER_INTERFACE:
3786 if (!streq(signature, "s"))
3789 r = message_peek_field_string(m, interface_name_is_valid, &ri, &m->interface);
3792 case SD_BUS_MESSAGE_HEADER_MEMBER:
3797 if (!streq(signature, "s"))
3800 r = message_peek_field_string(m, member_name_is_valid, &ri, &m->member);
3803 case SD_BUS_MESSAGE_HEADER_ERROR_NAME:
3808 if (!streq(signature, "s"))
3811 r = message_peek_field_string(m, error_name_is_valid, &ri, &m->error.name);
3813 m->error._need_free = -1;
3817 case SD_BUS_MESSAGE_HEADER_DESTINATION:
3822 if (!streq(signature, "s"))
3825 r = message_peek_field_string(m, service_name_is_valid, &ri, &m->destination);
3828 case SD_BUS_MESSAGE_HEADER_SENDER:
3833 if (!streq(signature, "s"))
3836 r = message_peek_field_string(m, service_name_is_valid, &ri, &m->sender);
3838 if (r >= 0 && m->sender[0] == ':' && m->bus && m->bus->bus_client && !m->bus->is_kernel) {
3839 m->creds.unique_name = (char*) m->sender;
3840 m->creds.mask |= SD_BUS_CREDS_UNIQUE_NAME & m->bus->creds_mask;
3846 case SD_BUS_MESSAGE_HEADER_SIGNATURE: {
3850 if (m->root_container.signature)
3853 if (!streq(signature, "g"))
3856 r = message_peek_field_signature(m, &ri, &s);
3864 free(m->root_container.signature);
3865 m->root_container.signature = c;
3869 case SD_BUS_MESSAGE_HEADER_REPLY_SERIAL:
3870 if (m->reply_serial != 0)
3873 if (!streq(signature, "u"))
3876 r = message_peek_field_uint32(m, &ri, &m->reply_serial);
3880 if (m->reply_serial == 0)
3885 case SD_BUS_MESSAGE_HEADER_UNIX_FDS:
3889 if (!streq(signature, "u"))
3892 r = message_peek_field_uint32(m, &ri, &unix_fds);
3902 r = message_skip_fields(m, &ri, (uint32_t) -1, (const char **) &signature);
3909 if (m->n_fds != unix_fds)
3912 if (isempty(m->root_container.signature) != (BUS_MESSAGE_BODY_SIZE(m) == 0))
3915 switch (m->header->type) {
3917 case SD_BUS_MESSAGE_SIGNAL:
3918 if (!m->path || !m->interface || !m->member)
3922 case SD_BUS_MESSAGE_METHOD_CALL:
3924 if (!m->path || !m->member)
3929 case SD_BUS_MESSAGE_METHOD_RETURN:
3931 if (m->reply_serial == 0)
3935 case SD_BUS_MESSAGE_METHOD_ERROR:
3937 if (m->reply_serial == 0 || !m->error.name)
3942 /* Try to read the error message, but if we can't it's a non-issue */
3943 if (m->header->type == SD_BUS_MESSAGE_METHOD_ERROR)
3944 sd_bus_message_read(m, "s", &m->error.message);
3949 int bus_message_seal(sd_bus_message *m, uint64_t serial) {
3950 struct bus_body_part *part;
3960 if (m->n_containers > 0)
3966 /* In vtables the return signature of method calls is listed,
3967 * let's check if they match if this is a response */
3968 if (m->header->type == SD_BUS_MESSAGE_METHOD_RETURN &&
3969 m->enforced_reply_signature &&
3970 !streq(strempty(m->root_container.signature), m->enforced_reply_signature))
3973 /* If there's a non-trivial signature set, then add it in here */
3974 if (!isempty(m->root_container.signature)) {
3975 r = message_append_field_signature(m, SD_BUS_MESSAGE_HEADER_SIGNATURE, m->root_container.signature, NULL);
3981 r = message_append_field_uint32(m, SD_BUS_MESSAGE_HEADER_UNIX_FDS, m->n_fds);
3986 /* Add padding at the end of the fields part, since we know
3987 * the body needs to start at an 8 byte alignment. We made
3988 * sure we allocated enough space for this, so all we need to
3989 * do here is to zero it out. */
3990 l = BUS_MESSAGE_FIELDS_SIZE(m);
3993 memset((uint8_t*) BUS_MESSAGE_FIELDS(m) + l, 0, a);
3995 /* If this is something we can send as memfd, then let's seal
3996 the memfd now. Note that we can send memfds as payload only
3997 for directed messages, and not for broadcasts. */
3998 if (m->destination && m->bus && m->bus->use_memfd) {
3999 MESSAGE_FOREACH_PART(part, i, m)
4000 if (part->memfd >= 0 && !part->sealed && (part->size > MEMFD_MIN_SIZE || m->bus->use_memfd < 0)) {
4001 bus_body_part_unmap(part);
4003 if (ioctl(part->memfd, KDBUS_CMD_MEMFD_SEAL_SET, 1) >= 0)
4004 part->sealed = true;
4008 m->header->serial = serial;
4014 _public_ int sd_bus_message_set_destination(sd_bus_message *m, const char *destination) {
4015 assert_return(m, -EINVAL);
4016 assert_return(destination, -EINVAL);
4017 assert_return(!m->sealed, -EPERM);
4018 assert_return(!m->destination, -EEXIST);
4020 return message_append_field_string(m, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &m->destination);
4023 int bus_message_get_blob(sd_bus_message *m, void **buffer, size_t *sz) {
4027 struct bus_body_part *part;
4033 total = BUS_MESSAGE_SIZE(m);
4039 e = mempcpy(p, m->header, BUS_MESSAGE_BODY_BEGIN(m));
4040 MESSAGE_FOREACH_PART(part, i, m)
4041 e = mempcpy(e, part->data, part->size);
4043 assert(total == (size_t) ((uint8_t*) e - (uint8_t*) p));
4051 int bus_message_read_strv_extend(sd_bus_message *m, char ***l) {
4057 r = sd_bus_message_enter_container(m, 'a', "s");
4064 r = sd_bus_message_read_basic(m, 's', &s);
4070 r = strv_extend(l, s);
4075 r = sd_bus_message_exit_container(m);
4082 _public_ int sd_bus_message_read_strv(sd_bus_message *m, char ***l) {
4086 assert_return(m, -EINVAL);
4087 assert_return(m->sealed, -EPERM);
4088 assert_return(l, -EINVAL);
4090 r = bus_message_read_strv_extend(m, &strv);
4100 const char* bus_message_get_arg(sd_bus_message *m, unsigned i) {
4102 const char *t = NULL;
4107 r = sd_bus_message_rewind(m, true);
4111 for (j = 0; j <= i; j++) {
4114 r = sd_bus_message_peek_type(m, &type, NULL);
4118 if (type != SD_BUS_TYPE_STRING &&
4119 type != SD_BUS_TYPE_OBJECT_PATH &&
4120 type != SD_BUS_TYPE_SIGNATURE)
4123 r = sd_bus_message_read_basic(m, type, &t);
4131 bool bus_header_is_complete(struct bus_header *h, size_t size) {
4137 if (size < sizeof(struct bus_header))
4140 full = sizeof(struct bus_header) +
4141 (h->endian == SD_BUS_NATIVE_ENDIAN ? h->fields_size : bswap_32(h->fields_size));
4143 return size >= full;
4146 int bus_header_message_size(struct bus_header *h, size_t *sum) {
4152 if (h->endian == SD_BUS_NATIVE_ENDIAN) {
4153 fs = h->fields_size;
4155 } else if (h->endian == SD_BUS_REVERSE_ENDIAN) {
4156 fs = bswap_32(h->fields_size);
4157 bs = bswap_32(h->body_size);
4161 *sum = sizeof(struct bus_header) + ALIGN8(fs) + bs;
4165 _public_ int sd_bus_message_get_errno(sd_bus_message *m) {
4166 assert_return(m, -EINVAL);
4168 if (m->header->type != SD_BUS_MESSAGE_METHOD_ERROR)
4171 return sd_bus_error_get_errno(&m->error);
4174 _public_ const char* sd_bus_message_get_signature(sd_bus_message *m, int complete) {
4175 struct bus_container *c;
4177 assert_return(m, NULL);
4179 c = complete ? &m->root_container : message_get_container(m);
4180 return c->signature ?: "";
4183 _public_ int sd_bus_message_copy(sd_bus_message *m, sd_bus_message *source, int all) {
4184 bool done_something = false;
4187 assert_return(m, -EINVAL);
4188 assert_return(source, -EINVAL);
4189 assert_return(!m->sealed, -EPERM);
4190 assert_return(source->sealed, -EPERM);
4193 const char *contents;
4208 r = sd_bus_message_peek_type(source, &type, &contents);
4214 done_something = true;
4216 if (bus_type_is_container(type) > 0) {
4218 r = sd_bus_message_enter_container(source, type, contents);
4222 r = sd_bus_message_open_container(m, type, contents);
4226 r = sd_bus_message_copy(m, source, true);
4230 r = sd_bus_message_close_container(m);
4234 r = sd_bus_message_exit_container(source);
4241 r = sd_bus_message_read_basic(source, type, &basic);
4247 if (type == SD_BUS_TYPE_OBJECT_PATH ||
4248 type == SD_BUS_TYPE_SIGNATURE ||
4249 type == SD_BUS_TYPE_STRING)
4250 r = sd_bus_message_append_basic(m, type, basic.string);
4252 r = sd_bus_message_append_basic(m, type, &basic);
4259 return done_something;
4262 _public_ int sd_bus_message_verify_type(sd_bus_message *m, char type, const char *contents) {
4267 assert_return(m, -EINVAL);
4268 assert_return(m->sealed, -EPERM);
4269 assert_return(!type || bus_type_is_valid(type), -EINVAL);
4270 assert_return(!contents || signature_is_valid(contents, true), -EINVAL);
4271 assert_return(type || contents, -EINVAL);
4272 assert_return(!contents || !type || bus_type_is_container(type), -EINVAL);
4274 r = sd_bus_message_peek_type(m, &t, &c);
4278 if (type != 0 && type != t)
4281 if (contents && !streq_ptr(contents, c))
4287 _public_ sd_bus *sd_bus_message_get_bus(sd_bus_message *m) {
4288 assert_return(m, NULL);