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"
37 #include "bus-gvariant.h"
39 static int message_append_basic(sd_bus_message *m, char type, const void *p, const void **stored);
41 static void *adjust_pointer(const void *p, void *old_base, size_t sz, void *new_base) {
46 if (old_base == new_base)
49 if ((uint8_t*) p < (uint8_t*) old_base)
52 if ((uint8_t*) p >= (uint8_t*) old_base + sz)
55 return (uint8_t*) new_base + ((uint8_t*) p - (uint8_t*) old_base);
58 static void message_free_part(sd_bus_message *m, struct bus_body_part *part) {
62 if (part->memfd >= 0) {
63 /* If we can reuse the memfd, try that. For that it
64 * can't be sealed yet. */
67 bus_kernel_push_memfd(m->bus, part->memfd, part->data, part->mapped);
70 assert_se(munmap(part->data, part->mapped) == 0);
72 close_nointr_nofail(part->memfd);
75 } else if (part->munmap_this)
76 munmap(part->data, part->mapped);
77 else if (part->free_this)
84 static void message_reset_parts(sd_bus_message *m) {
85 struct bus_body_part *part;
90 while (m->n_body_parts > 0) {
91 struct bus_body_part *next = part->next;
92 message_free_part(m, part);
99 m->cached_rindex_part = NULL;
100 m->cached_rindex_part_begin = 0;
103 static void message_reset_containers(sd_bus_message *m) {
108 for (i = 0; i < m->n_containers; i++)
109 free(m->containers[i].signature);
112 m->containers = NULL;
115 m->root_container.index = 0;
118 static void message_free(sd_bus_message *m) {
124 message_reset_parts(m);
129 if (m->release_kdbus) {
132 off = (uint8_t *)m->kdbus - (uint8_t *)m->bus->kdbus_buffer;
133 ioctl(m->bus->input_fd, KDBUS_CMD_FREE, &off);
137 sd_bus_unref(m->bus);
140 close_many(m->fds, m->n_fds);
144 if (m->iovec != m->iovec_fixed)
147 message_reset_containers(m);
148 free(m->root_container.signature);
150 free(m->peeked_signature);
152 bus_creds_done(&m->creds);
156 static void *message_extend_fields(sd_bus_message *m, size_t align, size_t sz, bool add_offset) {
158 size_t old_size, new_size, start;
165 old_size = sizeof(struct bus_header) + m->header->fields_size;
166 start = ALIGN_TO(old_size, align);
167 new_size = start + sz;
169 if (old_size == new_size)
170 return (uint8_t*) m->header + old_size;
172 if (new_size > (size_t) ((uint32_t) -1))
175 if (m->free_header) {
176 np = realloc(m->header, ALIGN8(new_size));
180 /* Initially, the header is allocated as part of of
181 * the sd_bus_message itself, let's replace it by
184 np = malloc(ALIGN8(new_size));
188 memcpy(np, m->header, sizeof(struct bus_header));
191 /* Zero out padding */
192 if (start > old_size)
193 memset((uint8_t*) np + old_size, 0, start - old_size);
197 m->header->fields_size = new_size - sizeof(struct bus_header);
199 /* Adjust quick access pointers */
200 m->path = adjust_pointer(m->path, op, old_size, m->header);
201 m->interface = adjust_pointer(m->interface, op, old_size, m->header);
202 m->member = adjust_pointer(m->member, op, old_size, m->header);
203 m->destination = adjust_pointer(m->destination, op, old_size, m->header);
204 m->sender = adjust_pointer(m->sender, op, old_size, m->header);
205 m->error.name = adjust_pointer(m->error.name, op, old_size, m->header);
207 m->free_header = true;
210 if (m->n_header_offsets >= ELEMENTSOF(m->header_offsets))
213 m->header_offsets[m->n_header_offsets++] = new_size - sizeof(struct bus_header);
216 return (uint8_t*) np + start;
223 static int message_append_field_string(
235 /* dbus1 doesn't allow strings over 32bit, let's enforce this
236 * globally, to not risk convertability */
238 if (l > (size_t) (uint32_t) -1)
241 /* Signature "(yv)" where the variant contains "s" */
243 if (m->is_gvariant) {
245 /* (field id byte + 7x padding, ((string + NUL) + NUL + signature string 's') */
246 p = message_extend_fields(m, 8, 1 + 7 + l + 1 + 1 + 1, true);
258 *ret = (char*) p + 1;
261 /* (field id byte + (signature length + signature 's' + NUL) + (string length + string + NUL)) */
262 p = message_extend_fields(m, 8, 4 + 4 + l + 1, false);
271 ((uint32_t*) p)[1] = l;
272 memcpy(p + 8, s, l + 1);
275 *ret = (char*) p + 8;
281 static int message_append_field_signature(
292 /* dbus1 doesn't allow signatures over 32bit, let's enforce
293 * this globally, to not risk convertability */
298 /* Signature "(yv)" where the variant contains "g" */
301 /* For gvariant the serialization is the same as for normal strings */
302 return message_append_field_string(m, h, 'g', s, ret);
304 /* (field id byte + (signature length + signature 'g' + NUL) + (string length + string + NUL)) */
305 p = message_extend_fields(m, 8, 4 + 1 + l + 1, false);
311 p[2] = SD_BUS_TYPE_SIGNATURE;
314 memcpy(p + 5, s, l + 1);
317 *ret = (const char*) p + 5;
323 static int message_append_field_uint32(sd_bus_message *m, uint8_t h, uint32_t x) {
328 if (m->is_gvariant) {
329 /* (field id byte + 7x padding + ((value + NUL + signature string 'u') */
331 p = message_extend_fields(m, 8, 1 + 7 + 4 + 1 + 1, true);
337 *((uint32_t*) (p + 8)) = x;
341 /* (field id byte + (signature length + signature 'u' + NUL) + value) */
342 p = message_extend_fields(m, 8, 4 + 4, false);
348 p[2] = SD_BUS_TYPE_UINT32;
351 ((uint32_t*) p)[1] = x;
357 int bus_message_from_header(
363 const struct ucred *ucred,
366 sd_bus_message **ret) {
369 struct bus_header *h;
372 assert(buffer || length <= 0);
373 assert(fds || n_fds <= 0);
376 if (length < sizeof(struct bus_header))
386 if (h->type == _SD_BUS_MESSAGE_TYPE_INVALID)
389 if (h->endian != BUS_LITTLE_ENDIAN &&
390 h->endian != BUS_BIG_ENDIAN)
393 a = ALIGN(sizeof(sd_bus_message)) + ALIGN(extra);
396 label_sz = strlen(label);
411 m->creds.uid = ucred->uid;
412 m->creds.pid = ucred->pid;
413 m->creds.gid = ucred->gid;
414 m->creds.mask |= SD_BUS_CREDS_UID | SD_BUS_CREDS_PID | SD_BUS_CREDS_GID;
418 m->creds.label = (char*) m + ALIGN(sizeof(sd_bus_message)) + ALIGN(extra);
419 memcpy(m->creds.label, label, label_sz + 1);
421 m->creds.mask |= SD_BUS_CREDS_SELINUX_CONTEXT;
425 m->bus = sd_bus_ref(bus);
431 int bus_message_from_malloc(
437 const struct ucred *ucred,
439 sd_bus_message **ret) {
445 r = bus_message_from_header(bus, buffer, length, fds, n_fds, ucred, label, 0, &m);
449 if (length != BUS_MESSAGE_SIZE(m)) {
454 sz = length - sizeof(struct bus_header) - ALIGN8(BUS_MESSAGE_FIELDS_SIZE(m));
457 m->body.data = (uint8_t*) buffer + sizeof(struct bus_header) + ALIGN8(BUS_MESSAGE_FIELDS_SIZE(m));
459 m->body.sealed = true;
464 m->iovec = m->iovec_fixed;
465 m->iovec[0].iov_base = buffer;
466 m->iovec[0].iov_len = length;
468 r = bus_message_parse_fields(m);
472 /* We take possession of the memory and fds now */
473 m->free_header = true;
484 static sd_bus_message *message_new(sd_bus *bus, uint8_t type) {
487 m = malloc0(ALIGN(sizeof(sd_bus_message)) + sizeof(struct bus_header));
492 m->header = (struct bus_header*) ((uint8_t*) m + ALIGN(sizeof(struct sd_bus_message)));
493 m->header->endian = BUS_NATIVE_ENDIAN;
494 m->header->type = type;
495 m->header->version = bus ? bus->message_version : 1;
496 m->allow_fds = !bus || bus->can_fds || (bus->state != BUS_HELLO && bus->state != BUS_RUNNING);
497 m->root_container.need_offsets = m->is_gvariant = bus ? bus->use_gvariant : false;
500 m->bus = sd_bus_ref(bus);
505 _public_ int sd_bus_message_new_signal(
508 const char *interface,
510 sd_bus_message **m) {
515 assert_return(!bus || bus->state != BUS_UNSET, -ENOTCONN);
516 assert_return(object_path_is_valid(path), -EINVAL);
517 assert_return(interface_name_is_valid(interface), -EINVAL);
518 assert_return(member_name_is_valid(member), -EINVAL);
519 assert_return(m, -EINVAL);
521 t = message_new(bus, SD_BUS_MESSAGE_SIGNAL);
525 t->header->flags |= BUS_MESSAGE_NO_REPLY_EXPECTED;
527 r = message_append_field_string(t, BUS_MESSAGE_HEADER_PATH, SD_BUS_TYPE_OBJECT_PATH, path, &t->path);
530 r = message_append_field_string(t, BUS_MESSAGE_HEADER_INTERFACE, SD_BUS_TYPE_STRING, interface, &t->interface);
533 r = message_append_field_string(t, BUS_MESSAGE_HEADER_MEMBER, SD_BUS_TYPE_STRING, member, &t->member);
541 sd_bus_message_unref(t);
545 _public_ int sd_bus_message_new_method_call(
547 const char *destination,
549 const char *interface,
551 sd_bus_message **m) {
556 assert_return(!bus || bus->state != BUS_UNSET, -ENOTCONN);
557 assert_return(!destination || service_name_is_valid(destination), -EINVAL);
558 assert_return(object_path_is_valid(path), -EINVAL);
559 assert_return(!interface || interface_name_is_valid(interface), -EINVAL);
560 assert_return(member_name_is_valid(member), -EINVAL);
561 assert_return(m, -EINVAL);
563 t = message_new(bus, SD_BUS_MESSAGE_METHOD_CALL);
567 r = message_append_field_string(t, BUS_MESSAGE_HEADER_PATH, SD_BUS_TYPE_OBJECT_PATH, path, &t->path);
570 r = message_append_field_string(t, BUS_MESSAGE_HEADER_MEMBER, SD_BUS_TYPE_STRING, member, &t->member);
575 r = message_append_field_string(t, BUS_MESSAGE_HEADER_INTERFACE, SD_BUS_TYPE_STRING, interface, &t->interface);
581 r = message_append_field_string(t, BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &t->destination);
594 static int message_new_reply(
595 sd_bus_message *call,
597 sd_bus_message **m) {
602 assert_return(call, -EINVAL);
603 assert_return(call->sealed, -EPERM);
604 assert_return(call->header->type == SD_BUS_MESSAGE_METHOD_CALL, -EINVAL);
605 assert_return(!call->bus || call->bus->state != BUS_UNSET, -ENOTCONN);
606 assert_return(m, -EINVAL);
608 t = message_new(call->bus, type);
612 t->header->flags |= BUS_MESSAGE_NO_REPLY_EXPECTED;
613 t->reply_serial = BUS_MESSAGE_SERIAL(call);
615 r = message_append_field_uint32(t, BUS_MESSAGE_HEADER_REPLY_SERIAL, t->reply_serial);
620 r = message_append_field_string(t, BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, call->sender, &t->destination);
625 t->dont_send = !!(call->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED);
626 t->enforced_reply_signature = call->enforced_reply_signature;
636 _public_ int sd_bus_message_new_method_return(
637 sd_bus_message *call,
638 sd_bus_message **m) {
640 return message_new_reply(call, SD_BUS_MESSAGE_METHOD_RETURN, m);
643 _public_ int sd_bus_message_new_method_error(
644 sd_bus_message *call,
645 const sd_bus_error *e,
646 sd_bus_message **m) {
651 assert_return(sd_bus_error_is_set(e), -EINVAL);
652 assert_return(m, -EINVAL);
654 r = message_new_reply(call, SD_BUS_MESSAGE_METHOD_ERROR, &t);
658 r = message_append_field_string(t, BUS_MESSAGE_HEADER_ERROR_NAME, SD_BUS_TYPE_STRING, e->name, &t->error.name);
663 r = message_append_basic(t, SD_BUS_TYPE_STRING, e->message, (const void**) &t->error.message);
668 t->error._need_free = -1;
678 _public_ int sd_bus_message_new_method_errorf(
679 sd_bus_message *call,
685 _cleanup_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
688 assert_return(name, -EINVAL);
689 assert_return(m, -EINVAL);
691 va_start(ap, format);
692 bus_error_setfv(&error, name, format, ap);
695 return sd_bus_message_new_method_error(call, &error, m);
698 _public_ int sd_bus_message_new_method_errno(
699 sd_bus_message *call,
701 const sd_bus_error *p,
702 sd_bus_message **m) {
704 _cleanup_free_ sd_bus_error berror = SD_BUS_ERROR_NULL;
706 if (sd_bus_error_is_set(p))
707 return sd_bus_message_new_method_error(call, p, m);
709 sd_bus_error_set_errno(&berror, error);
711 return sd_bus_message_new_method_error(call, &berror, m);
714 _public_ int sd_bus_message_new_method_errnof(
715 sd_bus_message *call,
721 _cleanup_free_ sd_bus_error berror = SD_BUS_ERROR_NULL;
724 va_start(ap, format);
725 bus_error_set_errnofv(&berror, error, format, ap);
728 return sd_bus_message_new_method_error(call, &berror, m);
731 int bus_message_new_synthetic_error(
734 const sd_bus_error *e,
735 sd_bus_message **m) {
740 assert(sd_bus_error_is_set(e));
743 t = message_new(bus, SD_BUS_MESSAGE_METHOD_ERROR);
747 t->header->flags |= BUS_MESSAGE_NO_REPLY_EXPECTED;
748 t->reply_serial = serial;
750 r = message_append_field_uint32(t, BUS_MESSAGE_HEADER_REPLY_SERIAL, t->reply_serial);
754 if (bus && bus->unique_name) {
755 r = message_append_field_string(t, BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, bus->unique_name, &t->destination);
760 r = message_append_field_string(t, BUS_MESSAGE_HEADER_ERROR_NAME, SD_BUS_TYPE_STRING, e->name, &t->error.name);
765 r = message_append_basic(t, SD_BUS_TYPE_STRING, e->message, (const void**) &t->error.message);
770 t->error._need_free = -1;
780 _public_ sd_bus_message* sd_bus_message_ref(sd_bus_message *m) {
781 assert_return(m, NULL);
783 assert(m->n_ref > 0);
789 _public_ sd_bus_message* sd_bus_message_unref(sd_bus_message *m) {
790 assert_return(m, NULL);
792 assert(m->n_ref > 0);
801 _public_ int sd_bus_message_get_type(sd_bus_message *m, uint8_t *type) {
802 assert_return(m, -EINVAL);
803 assert_return(type, -EINVAL);
805 *type = m->header->type;
809 _public_ int sd_bus_message_get_serial(sd_bus_message *m, uint64_t *serial) {
810 assert_return(m, -EINVAL);
811 assert_return(serial, -EINVAL);
812 assert_return(m->header->serial != 0, -ENOENT);
814 *serial = BUS_MESSAGE_SERIAL(m);
818 _public_ int sd_bus_message_get_reply_serial(sd_bus_message *m, uint64_t *serial) {
819 assert_return(m, -EINVAL);
820 assert_return(serial, -EINVAL);
821 assert_return(m->reply_serial != 0, -ENOENT);
823 *serial = m->reply_serial;
827 _public_ int sd_bus_message_get_no_reply(sd_bus_message *m) {
828 assert_return(m, -EINVAL);
830 return m->header->type == SD_BUS_MESSAGE_METHOD_CALL ? !!(m->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED) : 0;
833 _public_ int sd_bus_message_get_no_auto_start(sd_bus_message *m) {
834 assert_return(m, -EINVAL);
836 return !!(m->header->flags & BUS_MESSAGE_NO_AUTO_START);
839 _public_ const char *sd_bus_message_get_path(sd_bus_message *m) {
840 assert_return(m, NULL);
845 _public_ const char *sd_bus_message_get_interface(sd_bus_message *m) {
846 assert_return(m, NULL);
851 _public_ const char *sd_bus_message_get_member(sd_bus_message *m) {
852 assert_return(m, NULL);
857 _public_ const char *sd_bus_message_get_destination(sd_bus_message *m) {
858 assert_return(m, NULL);
860 return m->destination;
863 _public_ const char *sd_bus_message_get_sender(sd_bus_message *m) {
864 assert_return(m, NULL);
869 _public_ const sd_bus_error *sd_bus_message_get_error(sd_bus_message *m) {
870 assert_return(m, NULL);
871 assert_return(sd_bus_error_is_set(&m->error), NULL);
876 _public_ int sd_bus_message_get_monotonic_timestamp(sd_bus_message *m, uint64_t *usec) {
877 assert_return(m, -EINVAL);
878 assert_return(usec, -EINVAL);
879 assert_return(m->monotonic > 0, -ENODATA);
881 *usec = m->monotonic;
885 _public_ int sd_bus_message_get_realtime_timestamp(sd_bus_message *m, uint64_t *usec) {
886 assert_return(m, -EINVAL);
887 assert_return(usec, -EINVAL);
888 assert_return(m->realtime > 0, -ENODATA);
894 _public_ sd_bus_creds *sd_bus_message_get_creds(sd_bus_message *m) {
895 assert_return(m, NULL);
897 if (m->creds.mask == 0)
903 _public_ int sd_bus_message_is_signal(sd_bus_message *m,
904 const char *interface,
905 const char *member) {
906 assert_return(m, -EINVAL);
908 if (m->header->type != SD_BUS_MESSAGE_SIGNAL)
911 if (interface && (!m->interface || !streq(m->interface, interface)))
914 if (member && (!m->member || !streq(m->member, member)))
920 _public_ int sd_bus_message_is_method_call(sd_bus_message *m,
921 const char *interface,
922 const char *member) {
923 assert_return(m, -EINVAL);
925 if (m->header->type != SD_BUS_MESSAGE_METHOD_CALL)
928 if (interface && (!m->interface || !streq(m->interface, interface)))
931 if (member && (!m->member || !streq(m->member, member)))
937 _public_ int sd_bus_message_is_method_error(sd_bus_message *m, const char *name) {
938 assert_return(m, -EINVAL);
940 if (m->header->type != SD_BUS_MESSAGE_METHOD_ERROR)
943 if (name && (!m->error.name || !streq(m->error.name, name)))
949 _public_ int sd_bus_message_set_no_reply(sd_bus_message *m, int b) {
950 assert_return(m, -EINVAL);
951 assert_return(!m->sealed, -EPERM);
952 assert_return(m->header->type == SD_BUS_MESSAGE_METHOD_CALL, -EPERM);
955 m->header->flags |= BUS_MESSAGE_NO_REPLY_EXPECTED;
957 m->header->flags &= ~BUS_MESSAGE_NO_REPLY_EXPECTED;
962 _public_ int sd_bus_message_set_no_auto_start(sd_bus_message *m, int b) {
963 assert_return(m, -EINVAL);
964 assert_return(!m->sealed, -EPERM);
967 m->header->flags |= BUS_MESSAGE_NO_AUTO_START;
969 m->header->flags &= ~BUS_MESSAGE_NO_AUTO_START;
974 static struct bus_container *message_get_container(sd_bus_message *m) {
977 if (m->n_containers == 0)
978 return &m->root_container;
980 assert(m->containers);
981 return m->containers + m->n_containers - 1;
984 struct bus_body_part *message_append_part(sd_bus_message *m) {
985 struct bus_body_part *part;
992 if (m->n_body_parts <= 0) {
998 part = new0(struct bus_body_part, 1);
1004 m->body_end->next = part;
1014 static void part_zero(struct bus_body_part *part, size_t sz) {
1019 /* All other fields can be left in their defaults */
1020 assert(!part->data);
1021 assert(part->memfd < 0);
1024 part->is_zero = true;
1025 part->sealed = true;
1028 static int part_make_space(
1029 struct sd_bus_message *m,
1030 struct bus_body_part *part,
1039 assert(!part->sealed);
1044 if (!part->data && part->memfd < 0)
1045 part->memfd = bus_kernel_pop_memfd(m->bus, &part->data, &part->mapped);
1047 if (part->memfd >= 0) {
1050 r = ioctl(part->memfd, KDBUS_CMD_MEMFD_SIZE_SET, &u);
1056 if (!part->data || sz > part->mapped) {
1057 size_t psz = PAGE_ALIGN(sz > 0 ? sz : 1);
1059 if (part->mapped <= 0)
1060 n = mmap(NULL, psz, PROT_READ|PROT_WRITE, MAP_SHARED, part->memfd, 0);
1062 n = mremap(part->data, part->mapped, psz, MREMAP_MAYMOVE);
1064 if (n == MAP_FAILED) {
1073 part->munmap_this = true;
1075 n = realloc(part->data, MAX(sz, 1u));
1082 part->free_this = true;
1086 *q = part->data ? (uint8_t*) part->data + part->size : NULL;
1092 static int message_add_offset(sd_bus_message *m, size_t offset) {
1093 struct bus_container *c;
1096 assert(m->is_gvariant);
1098 /* Add offset to current container, unless this is the first
1099 * item in it, which will have the 0 offset, which we can
1101 c = message_get_container(m);
1103 if (!c->need_offsets)
1106 if (!GREEDY_REALLOC(c->offsets, c->n_allocated, c->n_offsets + 1))
1109 c->offsets[c->n_offsets++] = offset;
1113 static void message_extend_containers(sd_bus_message *m, size_t expand) {
1114 struct bus_container *c;
1121 /* Update counters */
1122 for (c = m->containers; c < m->containers + m->n_containers; c++) {
1125 *c->array_size += expand;
1129 static void *message_extend_body(sd_bus_message *m, size_t align, size_t sz, bool add_offset) {
1130 struct bus_body_part *part = NULL;
1131 size_t start_body, end_body, padding, start_part, end_part, added;
1143 start_body = ALIGN_TO((size_t) m->header->body_size, align);
1144 end_body = start_body + sz;
1146 padding = start_body - m->header->body_size;
1147 added = padding + sz;
1149 /* Check for 32bit overflows */
1150 if (end_body > (size_t) ((uint32_t) -1)) {
1156 m->n_body_parts <= 0 ||
1157 m->body_end->sealed ||
1158 padding != ALIGN_TO(m->body_end->size, align) - m->body_end->size;
1162 part = message_append_part(m);
1166 part_zero(part, padding);
1169 part = message_append_part(m);
1173 r = part_make_space(m, part, sz, &p);
1177 struct bus_container *c;
1185 start_part = ALIGN_TO(part->size, align);
1186 end_part = start_part + sz;
1188 r = part_make_space(m, part, end_part, &p);
1193 memset(p, 0, padding);
1194 p = (uint8_t*) p + padding;
1197 /* Readjust pointers */
1198 for (c = m->containers; c < m->containers + m->n_containers; c++)
1199 c->array_size = adjust_pointer(c->array_size, op, os, part->data);
1201 m->error.message = (const char*) adjust_pointer(m->error.message, op, os, part->data);
1204 m->header->body_size = end_body;
1205 message_extend_containers(m, added);
1208 r = message_add_offset(m, end_body);
1218 static int message_push_fd(sd_bus_message *m, int fd) {
1229 copy = fcntl(fd, F_DUPFD_CLOEXEC, 3);
1233 f = realloc(m->fds, sizeof(int) * (m->n_fds + 1));
1236 close_nointr_nofail(copy);
1241 m->fds[m->n_fds] = copy;
1247 int message_append_basic(sd_bus_message *m, char type, const void *p, const void **stored) {
1248 _cleanup_close_ int fd = -1;
1249 struct bus_container *c;
1253 assert_return(m, -EINVAL);
1254 assert_return(!m->sealed, -EPERM);
1255 assert_return(bus_type_is_basic(type), -EINVAL);
1256 assert_return(!m->poisoned, -ESTALE);
1258 c = message_get_container(m);
1260 if (c->signature && c->signature[c->index]) {
1261 /* Container signature is already set */
1263 if (c->signature[c->index] != type)
1268 /* Maybe we can append to the signature? But only if this is the top-level container*/
1269 if (c->enclosing != 0)
1272 e = strextend(&c->signature, CHAR_TO_STR(type), NULL);
1279 if (m->is_gvariant) {
1285 case SD_BUS_TYPE_SIGNATURE:
1286 case SD_BUS_TYPE_STRING:
1289 /* Fall through... */
1290 case SD_BUS_TYPE_OBJECT_PATH:
1298 case SD_BUS_TYPE_BOOLEAN:
1300 u8 = p && *(int*) p;
1306 case SD_BUS_TYPE_UNIX_FD:
1311 fd = message_push_fd(m, *(int*) p);
1322 align = bus_gvariant_get_alignment(CHAR_TO_STR(type));
1323 sz = bus_gvariant_get_size(type);
1330 a = message_extend_body(m, align, sz, true);
1337 *stored = (const uint8_t*) a;
1344 case SD_BUS_TYPE_STRING:
1345 /* To make things easy we'll serialize a NULL string
1346 * into the empty string */
1349 /* Fall through... */
1350 case SD_BUS_TYPE_OBJECT_PATH:
1356 sz = 4 + strlen(p) + 1;
1359 case SD_BUS_TYPE_SIGNATURE:
1364 sz = 1 + strlen(p) + 1;
1367 case SD_BUS_TYPE_BOOLEAN:
1369 u32 = p && *(int*) p;
1373 case SD_BUS_TYPE_UNIX_FD:
1378 fd = message_push_fd(m, *(int*) p);
1389 align = bus_type_get_alignment(type);
1390 sz = bus_type_get_size(type);
1397 a = message_extend_body(m, align, sz, false);
1401 if (type == SD_BUS_TYPE_STRING || type == SD_BUS_TYPE_OBJECT_PATH) {
1402 *(uint32_t*) a = sz - 5;
1403 memcpy((uint8_t*) a + 4, p, sz - 4);
1406 *stored = (const uint8_t*) a + 4;
1408 } else if (type == SD_BUS_TYPE_SIGNATURE) {
1409 *(uint8_t*) a = sz - 1;
1410 memcpy((uint8_t*) a + 1, p, sz - 1);
1413 *stored = (const uint8_t*) a + 1;
1422 if (type == SD_BUS_TYPE_UNIX_FD)
1425 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1432 _public_ int sd_bus_message_append_basic(sd_bus_message *m, char type, const void *p) {
1433 return message_append_basic(m, type, p, NULL);
1436 _public_ int sd_bus_message_append_string_space(
1441 struct bus_container *c;
1444 assert_return(m, -EINVAL);
1445 assert_return(s, -EINVAL);
1446 assert_return(!m->sealed, -EPERM);
1447 assert_return(!m->poisoned, -ESTALE);
1449 c = message_get_container(m);
1451 if (c->signature && c->signature[c->index]) {
1452 /* Container signature is already set */
1454 if (c->signature[c->index] != SD_BUS_TYPE_STRING)
1459 /* Maybe we can append to the signature? But only if this is the top-level container*/
1460 if (c->enclosing != 0)
1463 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRING), NULL);
1470 if (m->is_gvariant) {
1471 a = message_extend_body(m, 1, size + 1, true);
1477 a = message_extend_body(m, 4, 4 + size + 1, false);
1481 *(uint32_t*) a = size;
1487 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1493 _public_ int sd_bus_message_append_string_iovec(
1495 const struct iovec *iov,
1503 assert_return(m, -EINVAL);
1504 assert_return(!m->sealed, -EPERM);
1505 assert_return(iov || n == 0, -EINVAL);
1506 assert_return(!m->poisoned, -ESTALE);
1508 size = IOVEC_TOTAL_SIZE(iov, n);
1510 r = sd_bus_message_append_string_space(m, size, &p);
1514 for (i = 0; i < n; i++) {
1516 if (iov[i].iov_base)
1517 memcpy(p, iov[i].iov_base, iov[i].iov_len);
1519 memset(p, ' ', iov[i].iov_len);
1521 p += iov[i].iov_len;
1527 static int bus_message_open_array(
1529 struct bus_container *c,
1530 const char *contents,
1531 uint32_t **array_size,
1533 bool *need_offsets) {
1543 assert(need_offsets);
1545 if (!signature_is_single(contents, true))
1548 if (c->signature && c->signature[c->index]) {
1550 /* Verify the existing signature */
1552 if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
1555 if (!startswith(c->signature + c->index + 1, contents))
1558 nindex = c->index + 1 + strlen(contents);
1562 if (c->enclosing != 0)
1565 /* Extend the existing signature */
1567 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_ARRAY), contents, NULL);
1573 nindex = e - c->signature;
1576 if (m->is_gvariant) {
1577 alignment = bus_gvariant_get_alignment(contents);
1581 /* Add alignment padding and add to offset list */
1582 if (!message_extend_body(m, alignment, 0, false))
1585 r = bus_gvariant_is_fixed_size(contents);
1589 *begin = m->header->body_size;
1590 *need_offsets = r == 0;
1594 struct bus_body_part *o;
1596 alignment = bus_type_get_alignment(contents[0]);
1600 a = message_extend_body(m, 4, 4, false);
1605 op = m->body_end->data;
1606 os = m->body_end->size;
1608 /* Add alignment between size and first element */
1609 if (!message_extend_body(m, alignment, 0, false))
1612 /* location of array size might have changed so let's readjust a */
1613 if (o == m->body_end)
1614 a = adjust_pointer(a, op, os, m->body_end->data);
1620 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1626 static int bus_message_open_variant(
1628 struct bus_container *c,
1629 const char *contents) {
1635 if (!signature_is_single(contents, false))
1638 if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
1641 if (c->signature && c->signature[c->index]) {
1643 if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
1649 if (c->enclosing != 0)
1652 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_VARIANT), NULL);
1659 if (m->is_gvariant) {
1660 /* Variants are always aligned to 8 */
1662 if (!message_extend_body(m, 8, 0, false))
1669 l = strlen(contents);
1670 a = message_extend_body(m, 1, 1 + l + 1, false);
1675 memcpy((uint8_t*) a + 1, contents, l + 1);
1678 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1684 static int bus_message_open_struct(
1686 struct bus_container *c,
1687 const char *contents,
1689 bool *need_offsets) {
1698 assert(need_offsets);
1700 if (!signature_is_valid(contents, false))
1703 if (c->signature && c->signature[c->index]) {
1706 l = strlen(contents);
1708 if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
1709 !startswith(c->signature + c->index + 1, contents) ||
1710 c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
1713 nindex = c->index + 1 + l + 1;
1717 if (c->enclosing != 0)
1720 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_BEGIN), contents, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_END), NULL);
1726 nindex = e - c->signature;
1729 if (m->is_gvariant) {
1732 alignment = bus_gvariant_get_alignment(contents);
1736 if (!message_extend_body(m, alignment, 0, false))
1739 r = bus_gvariant_is_fixed_size(contents);
1743 *begin = m->header->body_size;
1744 *need_offsets = r == 0;
1746 /* Align contents to 8 byte boundary */
1747 if (!message_extend_body(m, 8, 0, false))
1751 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1757 static int bus_message_open_dict_entry(
1759 struct bus_container *c,
1760 const char *contents,
1762 bool *need_offsets) {
1770 assert(need_offsets);
1772 if (!signature_is_pair(contents))
1775 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1778 if (c->signature && c->signature[c->index]) {
1781 l = strlen(contents);
1783 if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
1784 !startswith(c->signature + c->index + 1, contents) ||
1785 c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
1790 if (m->is_gvariant) {
1793 alignment = bus_gvariant_get_alignment(contents);
1797 if (!message_extend_body(m, alignment, 0, false))
1800 r = bus_gvariant_is_fixed_size(contents);
1804 *begin = m->header->body_size;
1805 *need_offsets = r == 0;
1807 /* Align contents to 8 byte boundary */
1808 if (!message_extend_body(m, 8, 0, false))
1815 _public_ int sd_bus_message_open_container(
1818 const char *contents) {
1820 struct bus_container *c, *w;
1821 uint32_t *array_size = NULL;
1823 size_t before, begin;
1824 bool need_offsets = false;
1827 assert_return(m, -EINVAL);
1828 assert_return(!m->sealed, -EPERM);
1829 assert_return(contents, -EINVAL);
1830 assert_return(!m->poisoned, -ESTALE);
1832 /* Make sure we have space for one more container */
1833 w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
1841 c = message_get_container(m);
1843 signature = strdup(contents);
1849 /* Save old index in the parent container, in case we have to
1850 * abort this container */
1851 c->saved_index = c->index;
1852 before = m->header->body_size;
1854 if (type == SD_BUS_TYPE_ARRAY)
1855 r = bus_message_open_array(m, c, contents, &array_size, &begin, &need_offsets);
1856 else if (type == SD_BUS_TYPE_VARIANT)
1857 r = bus_message_open_variant(m, c, contents);
1858 else if (type == SD_BUS_TYPE_STRUCT)
1859 r = bus_message_open_struct(m, c, contents, &begin, &need_offsets);
1860 else if (type == SD_BUS_TYPE_DICT_ENTRY)
1861 r = bus_message_open_dict_entry(m, c, contents, &begin, &need_offsets);
1870 /* OK, let's fill it in */
1871 w += m->n_containers++;
1872 w->enclosing = type;
1873 w->signature = signature;
1875 w->array_size = array_size;
1878 w->n_offsets = w->n_allocated = 0;
1880 w->need_offsets = need_offsets;
1885 static int bus_message_close_array(sd_bus_message *m, struct bus_container *c) {
1890 if (!m->is_gvariant)
1893 if (c->need_offsets) {
1898 /* Variable-width arrays */
1900 sz = c->n_offsets > 0 ? c->offsets[c->n_offsets-1] - c->begin : 0;
1901 if (sz + c->n_offsets <= 0xFF) {
1902 a = message_extend_body(m, 1, c->n_offsets, true);
1906 for (i = 0; i < c->n_offsets; i++)
1907 a[i] = (uint8_t) (c->offsets[i] - c->begin);
1909 } else if (sz + c->n_offsets*2 <= 0xFFFF) {
1910 a = message_extend_body(m, 1, c->n_offsets * 2, true);
1914 for (i = 0; i < c->n_offsets; i++) {
1915 uint16_t x = htole16((uint16_t) (c->offsets[i] - c->begin));
1916 memcpy(a + (i*2), &x, 2);
1919 } else if (sz + c->n_offsets*4 <= 0xFFFFFFFF) {
1920 a = message_extend_body(m, 1, c->n_offsets * 4, true);
1924 for (i = 0; i < c->n_offsets; i++) {
1925 uint32_t x = htole32((uint32_t) (c->offsets[i] - c->begin));
1926 memcpy(a + (i*4), &x, 4);
1929 a = message_extend_body(m, 1, c->n_offsets * 8, true);
1933 for (i = 0; i < c->n_offsets; i++) {
1934 uint64_t x = htole64((uint64_t) (c->offsets[i] - c->begin));
1935 memcpy(a + (i*8), &x, 8);
1942 /* Fixed-width or empty arrays */
1944 a = message_extend_body(m, 1, 0, true); /* let's add offset to parent */
1952 static int bus_message_close_variant(sd_bus_message *m, struct bus_container *c) {
1959 if (!m->is_gvariant)
1962 l = strlen(c->signature);
1964 a = message_extend_body(m, 1, 1 + l, true);
1969 memcpy(a+1, c->signature, l);
1974 static int bus_message_close_struct(sd_bus_message *m, struct bus_container *c, bool add_offset) {
1975 size_t n_variable = 0;
1984 if (!m->is_gvariant)
1991 r = signature_element_length(p, &n);
2000 r = bus_gvariant_is_fixed_size(t);
2005 assert(i <= c->n_offsets);
2007 /* We need to add an offset for each item that has a
2008 * variable size and that is not the last one in the
2010 if (r == 0 && p[n] != 0)
2013 c->offsets[i] = (size_t) -1;
2019 if (n_variable <= 0) {
2020 a = message_extend_body(m, 1, 0, true);
2027 assert(c->offsets[c->n_offsets-1] == m->header->body_size ||
2028 c->offsets[c->n_offsets-1] == (size_t) -1);
2030 sz = m->header->body_size - c->begin;
2031 if (sz + n_variable <= 0xFF)
2033 else if (sz + (n_variable)*2 <= 0xFFFF)
2035 else if (sz + (n_variable)*4 <= 0xFFFFFFFF)
2040 a = message_extend_body(m, 1, z * n_variable, add_offset);
2044 for (i = 0, j = 0; i < c->n_offsets; i++) {
2048 if (c->offsets[i] == (size_t) -1)
2051 v = c->offsets[i] - c->begin;
2052 k = n_variable - 1 - j;
2055 ((uint8_t*) a)[k] = (uint8_t) v;
2057 uint16_t x = htole16((uint16_t) v);
2058 memcpy(a + k * 2, &x, 2);
2059 } else if (z == 4) {
2060 uint32_t x = htole32((uint32_t) v);
2061 memcpy(a + k * 4, &x, 4);
2062 } else if (z == 8) {
2063 uint64_t x = htole64((uint64_t) v);
2064 memcpy(a + k * 8, &x, 8);
2066 assert_not_reached("Wrong offset width");
2075 _public_ int sd_bus_message_close_container(sd_bus_message *m) {
2076 struct bus_container *c;
2079 assert_return(m, -EINVAL);
2080 assert_return(!m->sealed, -EPERM);
2081 assert_return(m->n_containers > 0, -EINVAL);
2082 assert_return(!m->poisoned, -ESTALE);
2084 c = message_get_container(m);
2086 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2087 if (c->signature && c->signature[c->index] != 0)
2092 if (c->enclosing == SD_BUS_TYPE_ARRAY)
2093 r = bus_message_close_array(m, c);
2094 else if (c->enclosing == SD_BUS_TYPE_VARIANT)
2095 r = bus_message_close_variant(m, c);
2096 else if (c->enclosing == SD_BUS_TYPE_STRUCT || c->enclosing == SD_BUS_TYPE_DICT_ENTRY)
2097 r = bus_message_close_struct(m, c, true);
2099 assert_not_reached("Unknown container type");
2111 static int type_stack_push(TypeStack *stack, unsigned max, unsigned *i, const char *types, unsigned n_struct, unsigned n_array) {
2118 stack[*i].types = types;
2119 stack[*i].n_struct = n_struct;
2120 stack[*i].n_array = n_array;
2126 static int type_stack_pop(TypeStack *stack, unsigned max, unsigned *i, const char **types, unsigned *n_struct, unsigned *n_array) {
2137 *types = stack[*i].types;
2138 *n_struct = stack[*i].n_struct;
2139 *n_array = stack[*i].n_array;
2144 int bus_message_append_ap(
2149 unsigned n_array, n_struct;
2150 TypeStack stack[BUS_CONTAINER_DEPTH];
2151 unsigned stack_ptr = 0;
2159 n_array = (unsigned) -1;
2160 n_struct = strlen(types);
2165 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
2166 r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
2172 r = sd_bus_message_close_container(m);
2180 if (n_array != (unsigned) -1)
2189 case SD_BUS_TYPE_BYTE: {
2192 x = (uint8_t) va_arg(ap, int);
2193 r = sd_bus_message_append_basic(m, *t, &x);
2197 case SD_BUS_TYPE_BOOLEAN:
2198 case SD_BUS_TYPE_INT32:
2199 case SD_BUS_TYPE_UINT32:
2200 case SD_BUS_TYPE_UNIX_FD: {
2203 /* We assume a boolean is the same as int32_t */
2204 assert_cc(sizeof(int32_t) == sizeof(int));
2206 x = va_arg(ap, uint32_t);
2207 r = sd_bus_message_append_basic(m, *t, &x);
2211 case SD_BUS_TYPE_INT16:
2212 case SD_BUS_TYPE_UINT16: {
2215 x = (uint16_t) va_arg(ap, int);
2216 r = sd_bus_message_append_basic(m, *t, &x);
2220 case SD_BUS_TYPE_INT64:
2221 case SD_BUS_TYPE_UINT64:
2222 case SD_BUS_TYPE_DOUBLE: {
2225 x = va_arg(ap, uint64_t);
2226 r = sd_bus_message_append_basic(m, *t, &x);
2230 case SD_BUS_TYPE_STRING:
2231 case SD_BUS_TYPE_OBJECT_PATH:
2232 case SD_BUS_TYPE_SIGNATURE: {
2235 x = va_arg(ap, const char*);
2236 r = sd_bus_message_append_basic(m, *t, x);
2240 case SD_BUS_TYPE_ARRAY: {
2243 r = signature_element_length(t + 1, &k);
2249 memcpy(s, t + 1, k);
2252 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, s);
2257 if (n_array == (unsigned) -1) {
2262 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2268 n_array = va_arg(ap, unsigned);
2273 case SD_BUS_TYPE_VARIANT: {
2276 s = va_arg(ap, const char*);
2280 r = sd_bus_message_open_container(m, SD_BUS_TYPE_VARIANT, s);
2284 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2289 n_struct = strlen(s);
2290 n_array = (unsigned) -1;
2295 case SD_BUS_TYPE_STRUCT_BEGIN:
2296 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
2299 r = signature_element_length(t, &k);
2306 memcpy(s, t + 1, k - 2);
2309 r = sd_bus_message_open_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
2314 if (n_array == (unsigned) -1) {
2319 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2325 n_array = (unsigned) -1;
2341 _public_ int sd_bus_message_append(sd_bus_message *m, const char *types, ...) {
2345 assert_return(m, -EINVAL);
2346 assert_return(types, -EINVAL);
2347 assert_return(!m->sealed, -EPERM);
2348 assert_return(!m->poisoned, -ESTALE);
2350 va_start(ap, types);
2351 r = bus_message_append_ap(m, types, ap);
2357 _public_ int sd_bus_message_append_array_space(
2367 assert_return(m, -EINVAL);
2368 assert_return(!m->sealed, -EPERM);
2369 assert_return(bus_type_is_trivial(type), -EINVAL);
2370 assert_return(ptr || size == 0, -EINVAL);
2371 assert_return(!m->poisoned, -ESTALE);
2373 align = bus_type_get_alignment(type);
2374 sz = bus_type_get_size(type);
2376 assert_se(align > 0);
2382 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
2386 a = message_extend_body(m, align, size, false);
2390 r = sd_bus_message_close_container(m);
2398 _public_ int sd_bus_message_append_array(sd_bus_message *m,
2405 assert_return(m, -EINVAL);
2406 assert_return(!m->sealed, -EPERM);
2407 assert_return(bus_type_is_trivial(type), -EINVAL);
2408 assert_return(ptr || size == 0, -EINVAL);
2409 assert_return(!m->poisoned, -ESTALE);
2411 r = sd_bus_message_append_array_space(m, type, size, &p);
2416 memcpy(p, ptr, size);
2421 _public_ int sd_bus_message_append_array_iovec(
2424 const struct iovec *iov,
2432 assert_return(m, -EINVAL);
2433 assert_return(!m->sealed, -EPERM);
2434 assert_return(bus_type_is_trivial(type), -EINVAL);
2435 assert_return(iov || n == 0, -EINVAL);
2436 assert_return(!m->poisoned, -ESTALE);
2438 size = IOVEC_TOTAL_SIZE(iov, n);
2440 r = sd_bus_message_append_array_space(m, type, size, &p);
2444 for (i = 0; i < n; i++) {
2446 if (iov[i].iov_base)
2447 memcpy(p, iov[i].iov_base, iov[i].iov_len);
2449 memset(p, 0, iov[i].iov_len);
2451 p = (uint8_t*) p + iov[i].iov_len;
2457 _public_ int sd_bus_message_append_array_memfd(sd_bus_message *m,
2460 _cleanup_close_ int copy_fd = -1;
2461 struct bus_body_part *part;
2473 if (!bus_type_is_trivial(type))
2478 r = sd_memfd_set_sealed(memfd, true);
2482 copy_fd = sd_memfd_dup_fd(memfd);
2486 r = sd_memfd_get_size(memfd, &size);
2490 align = bus_type_get_alignment(type);
2491 sz = bus_type_get_size(type);
2493 assert_se(align > 0);
2499 if (size > (uint64_t) (uint32_t) -1)
2502 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
2506 a = message_extend_body(m, align, 0, false);
2510 part = message_append_part(m);
2514 part->memfd = copy_fd;
2515 part->sealed = true;
2519 message_extend_containers(m, size);
2520 m->header->body_size += size;
2522 return sd_bus_message_close_container(m);
2525 _public_ int sd_bus_message_append_string_memfd(sd_bus_message *m, sd_memfd *memfd) {
2526 _cleanup_close_ int copy_fd = -1;
2527 struct bus_body_part *part;
2528 struct bus_container *c;
2533 assert_return(m, -EINVAL);
2534 assert_return(memfd, -EINVAL);
2535 assert_return(!m->sealed, -EPERM);
2536 assert_return(!m->poisoned, -ESTALE);
2538 r = sd_memfd_set_sealed(memfd, true);
2542 copy_fd = sd_memfd_dup_fd(memfd);
2546 r = sd_memfd_get_size(memfd, &size);
2550 /* We require this to be NUL terminated */
2554 if (size > (uint64_t) (uint32_t) -1)
2557 c = message_get_container(m);
2558 if (c->signature && c->signature[c->index]) {
2559 /* Container signature is already set */
2561 if (c->signature[c->index] != SD_BUS_TYPE_STRING)
2566 /* Maybe we can append to the signature? But only if this is the top-level container*/
2567 if (c->enclosing != 0)
2570 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRING), NULL);
2577 if (!m->is_gvariant) {
2578 a = message_extend_body(m, 4, 4, false);
2582 *(uint32_t*) a = size - 1;
2585 part = message_append_part(m);
2589 part->memfd = copy_fd;
2590 part->sealed = true;
2594 m->header->body_size += size;
2595 message_extend_containers(m, size);
2597 if (m->is_gvariant) {
2598 r = message_add_offset(m, m->header->body_size);
2605 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2611 _public_ int sd_bus_message_append_strv(sd_bus_message *m, char **l) {
2615 assert_return(m, -EINVAL);
2616 assert_return(!m->sealed, -EPERM);
2617 assert_return(!m->poisoned, -ESTALE);
2619 r = sd_bus_message_open_container(m, 'a', "s");
2623 STRV_FOREACH(i, l) {
2624 r = sd_bus_message_append_basic(m, 's', *i);
2629 return sd_bus_message_close_container(m);
2632 int bus_body_part_map(struct bus_body_part *part) {
2641 if (part->size <= 0)
2644 /* For smaller zero parts (as used for padding) we don't need to map anything... */
2645 if (part->memfd < 0 && part->is_zero && part->size < 8) {
2646 static const uint8_t zeroes[7] = { };
2647 part->data = (void*) zeroes;
2651 psz = PAGE_ALIGN(part->size);
2653 if (part->memfd >= 0)
2654 p = mmap(NULL, psz, PROT_READ, MAP_SHARED, part->memfd, 0);
2655 else if (part->is_zero)
2656 p = mmap(NULL, psz, PROT_READ, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
2660 if (p == MAP_FAILED)
2665 part->munmap_this = true;
2670 void bus_body_part_unmap(struct bus_body_part *part) {
2674 if (part->memfd < 0)
2680 if (!part->munmap_this)
2683 assert_se(munmap(part->data, part->mapped) == 0);
2687 part->munmap_this = false;
2692 static int buffer_peek(const void *p, uint32_t sz, size_t *rindex, size_t align, size_t nbytes, void **r) {
2693 size_t k, start, end;
2698 start = ALIGN_TO((size_t) *rindex, align);
2699 end = start + nbytes;
2704 /* Verify that padding is 0 */
2705 for (k = *rindex; k < start; k++)
2706 if (((const uint8_t*) p)[k] != 0)
2710 *r = (uint8_t*) p + start;
2717 static bool message_end_of_signature(sd_bus_message *m) {
2718 struct bus_container *c;
2722 c = message_get_container(m);
2723 return !c->signature || c->signature[c->index] == 0;
2726 static bool message_end_of_array(sd_bus_message *m, size_t index) {
2727 struct bus_container *c;
2731 c = message_get_container(m);
2735 return index >= c->begin + BUS_MESSAGE_BSWAP32(m, *c->array_size);
2738 _public_ int sd_bus_message_at_end(sd_bus_message *m, int complete) {
2739 assert_return(m, -EINVAL);
2740 assert_return(m->sealed, -EPERM);
2742 if (complete && m->n_containers > 0)
2745 if (message_end_of_signature(m))
2748 if (message_end_of_array(m, m->rindex))
2754 static struct bus_body_part* find_part(sd_bus_message *m, size_t index, size_t sz, void **p) {
2755 struct bus_body_part *part;
2761 if (m->cached_rindex_part && index >= m->cached_rindex_part_begin) {
2762 part = m->cached_rindex_part;
2763 begin = m->cached_rindex_part_begin;
2773 if (index + sz <= begin + part->size) {
2775 r = bus_body_part_map(part);
2780 *p = (uint8_t*) part->data + index - begin;
2782 m->cached_rindex_part = part;
2783 m->cached_rindex_part_begin = begin;
2788 begin += part->size;
2795 static int message_peek_body(
2802 size_t k, start, end, padding;
2803 struct bus_body_part *part;
2810 if (message_end_of_array(m, *rindex))
2813 start = ALIGN_TO((size_t) *rindex, align);
2814 padding = start - *rindex;
2815 end = start + nbytes;
2817 if (end > BUS_MESSAGE_BODY_SIZE(m))
2820 part = find_part(m, *rindex, padding, (void**) &q);
2825 /* Verify padding */
2826 for (k = 0; k < padding; k++)
2831 part = find_part(m, start, nbytes, (void**) &q);
2843 static bool validate_nul(const char *s, size_t l) {
2845 /* Check for NUL chars in the string */
2846 if (memchr(s, 0, l))
2849 /* Check for NUL termination */
2856 static bool validate_string(const char *s, size_t l) {
2858 if (!validate_nul(s, l))
2861 /* Check if valid UTF8 */
2862 if (!utf8_is_valid(s))
2868 static bool validate_signature(const char *s, size_t l) {
2870 if (!validate_nul(s, l))
2873 /* Check if valid signature */
2874 if (!signature_is_valid(s, true))
2880 static bool validate_object_path(const char *s, size_t l) {
2882 if (!validate_nul(s, l))
2885 if (!object_path_is_valid(s))
2891 _public_ int sd_bus_message_read_basic(sd_bus_message *m, char type, void *p) {
2892 struct bus_container *c;
2896 assert_return(m, -EINVAL);
2897 assert_return(m->sealed, -EPERM);
2898 assert_return(bus_type_is_basic(type), -EINVAL);
2900 if (message_end_of_signature(m))
2903 if (message_end_of_array(m, m->rindex))
2906 c = message_get_container(m);
2907 if (c->signature[c->index] != type)
2912 case SD_BUS_TYPE_STRING:
2913 case SD_BUS_TYPE_OBJECT_PATH: {
2918 r = message_peek_body(m, &rindex, 4, 4, &q);
2922 l = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2923 r = message_peek_body(m, &rindex, 1, l+1, &q);
2929 if (type == SD_BUS_TYPE_OBJECT_PATH) {
2930 if (!validate_object_path(q, l))
2933 if (!validate_string(q, l))
2939 *(const char**) p = q;
2944 case SD_BUS_TYPE_SIGNATURE: {
2949 r = message_peek_body(m, &rindex, 1, 1, &q);
2954 r = message_peek_body(m, &rindex, 1, l+1, &q);
2960 if (!validate_signature(q, l))
2966 *(const char**) p = q;
2974 align = bus_type_get_alignment(type);
2975 sz = bus_type_get_size(type);
2976 assert(align > 0 && sz > 0);
2979 r = message_peek_body(m, &rindex, align, sz, &q);
2985 case SD_BUS_TYPE_BYTE:
2987 *(uint8_t*) p = *(uint8_t*) q;
2990 case SD_BUS_TYPE_BOOLEAN:
2992 *(int*) p = !!*(uint32_t*) q;
2995 case SD_BUS_TYPE_INT16:
2996 case SD_BUS_TYPE_UINT16:
2998 *(uint16_t*) p = BUS_MESSAGE_BSWAP16(m, *(uint16_t*) q);
3001 case SD_BUS_TYPE_INT32:
3002 case SD_BUS_TYPE_UINT32:
3004 *(uint32_t*) p = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
3007 case SD_BUS_TYPE_INT64:
3008 case SD_BUS_TYPE_UINT64:
3009 case SD_BUS_TYPE_DOUBLE:
3011 *(uint64_t*) p = BUS_MESSAGE_BSWAP64(m, *(uint64_t*) q);
3014 case SD_BUS_TYPE_UNIX_FD: {
3017 j = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
3022 *(int*) p = m->fds[j];
3027 assert_not_reached("Unknown basic type...");
3036 if (c->enclosing != SD_BUS_TYPE_ARRAY)
3042 static int bus_message_enter_array(
3044 struct bus_container *c,
3045 const char *contents,
3046 uint32_t **array_size) {
3057 if (!signature_is_single(contents, true))
3060 alignment = bus_type_get_alignment(contents[0]);
3064 if (!c->signature || c->signature[c->index] == 0)
3067 if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
3070 if (!startswith(c->signature + c->index + 1, contents))
3074 r = message_peek_body(m, &rindex, 4, 4, &q);
3078 if (BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q) > BUS_ARRAY_MAX_SIZE)
3081 r = message_peek_body(m, &rindex, alignment, 0, NULL);
3087 if (c->enclosing != SD_BUS_TYPE_ARRAY)
3088 c->index += 1 + strlen(contents);
3092 *array_size = (uint32_t*) q;
3097 static int bus_message_enter_variant(
3099 struct bus_container *c,
3100 const char *contents) {
3111 if (!signature_is_single(contents, false))
3114 if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
3117 if (!c->signature || c->signature[c->index] == 0)
3120 if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
3124 r = message_peek_body(m, &rindex, 1, 1, &q);
3129 r = message_peek_body(m, &rindex, 1, l+1, &q);
3135 if (!validate_signature(q, l))
3138 if (!streq(q, contents))
3141 if (c->enclosing != SD_BUS_TYPE_ARRAY)
3149 static int bus_message_enter_struct(
3151 struct bus_container *c,
3152 const char *contents) {
3161 if (!signature_is_valid(contents, false))
3164 if (!c->signature || c->signature[c->index] == 0)
3167 l = strlen(contents);
3169 if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
3170 !startswith(c->signature + c->index + 1, contents) ||
3171 c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
3174 r = message_peek_body(m, &m->rindex, 8, 0, NULL);
3178 if (c->enclosing != SD_BUS_TYPE_ARRAY)
3179 c->index += 1 + l + 1;
3184 static int bus_message_enter_dict_entry(
3186 struct bus_container *c,
3187 const char *contents) {
3196 if (!signature_is_pair(contents))
3199 if (c->enclosing != SD_BUS_TYPE_ARRAY)
3202 if (!c->signature || c->signature[c->index] == 0)
3205 l = strlen(contents);
3207 if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
3208 !startswith(c->signature + c->index + 1, contents) ||
3209 c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
3212 r = message_peek_body(m, &m->rindex, 8, 0, NULL);
3216 if (c->enclosing != SD_BUS_TYPE_ARRAY)
3217 c->index += 1 + l + 1;
3222 _public_ int sd_bus_message_enter_container(sd_bus_message *m,
3224 const char *contents) {
3225 struct bus_container *c, *w;
3226 uint32_t *array_size = NULL;
3231 assert_return(m, -EINVAL);
3232 assert_return(m->sealed, -EPERM);
3233 assert_return(type != 0 || !contents, -EINVAL);
3235 if (type == 0 || !contents) {
3239 /* Allow entering into anonymous containers */
3240 r = sd_bus_message_peek_type(m, &tt, &cc);
3244 if (type != 0 && type != tt)
3247 if (contents && !streq(contents, cc))
3255 * We enforce a global limit on container depth, that is much
3256 * higher than the 32 structs and 32 arrays the specification
3257 * mandates. This is simpler to implement for us, and we need
3258 * this only to ensure our container array doesn't grow
3259 * without bounds. We are happy to return any data from a
3260 * message as long as the data itself is valid, even if the
3261 * overall message might be not.
3263 * Note that the message signature is validated when
3264 * parsing the headers, and that validation does check the
3267 * Note that the specification defines no limits on the depth
3268 * of stacked variants, but we do.
3270 if (m->n_containers >= BUS_CONTAINER_DEPTH)
3273 w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
3278 if (message_end_of_signature(m))
3281 if (message_end_of_array(m, m->rindex))
3284 c = message_get_container(m);
3286 signature = strdup(contents);
3290 c->saved_index = c->index;
3293 if (type == SD_BUS_TYPE_ARRAY)
3294 r = bus_message_enter_array(m, c, contents, &array_size);
3295 else if (type == SD_BUS_TYPE_VARIANT)
3296 r = bus_message_enter_variant(m, c, contents);
3297 else if (type == SD_BUS_TYPE_STRUCT)
3298 r = bus_message_enter_struct(m, c, contents);
3299 else if (type == SD_BUS_TYPE_DICT_ENTRY)
3300 r = bus_message_enter_dict_entry(m, c, contents);
3309 /* OK, let's fill it in */
3310 w += m->n_containers++;
3311 w->enclosing = type;
3312 w->signature = signature;
3314 w->array_size = array_size;
3316 w->begin = m->rindex;
3321 _public_ int sd_bus_message_exit_container(sd_bus_message *m) {
3322 struct bus_container *c;
3324 assert_return(m, -EINVAL);
3325 assert_return(m->sealed, -EPERM);
3326 assert_return(m->n_containers > 0, -ENXIO);
3328 c = message_get_container(m);
3329 if (c->enclosing == SD_BUS_TYPE_ARRAY) {
3332 l = BUS_MESSAGE_BSWAP32(m, *c->array_size);
3333 if (c->begin + l != m->rindex)
3337 if (c->signature && c->signature[c->index] != 0)
3347 static void message_quit_container(sd_bus_message *m) {
3348 struct bus_container *c;
3352 assert(m->n_containers > 0);
3354 c = message_get_container(m);
3357 assert(m->rindex >= c->before);
3358 m->rindex = c->before;
3360 /* Free container */
3364 /* Correct index of new top-level container */
3365 c = message_get_container(m);
3366 c->index = c->saved_index;
3369 _public_ int sd_bus_message_peek_type(sd_bus_message *m, char *type, const char **contents) {
3370 struct bus_container *c;
3373 assert_return(m, -EINVAL);
3374 assert_return(m->sealed, -EPERM);
3376 if (message_end_of_signature(m))
3379 if (message_end_of_array(m, m->rindex))
3382 c = message_get_container(m);
3384 if (bus_type_is_basic(c->signature[c->index])) {
3388 *type = c->signature[c->index];
3392 if (c->signature[c->index] == SD_BUS_TYPE_ARRAY) {
3398 r = signature_element_length(c->signature+c->index+1, &l);
3404 sig = strndup(c->signature + c->index + 1, l);
3408 free(m->peeked_signature);
3409 m->peeked_signature = sig;
3415 *type = SD_BUS_TYPE_ARRAY;
3420 if (c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ||
3421 c->signature[c->index] == SD_BUS_TYPE_DICT_ENTRY_BEGIN) {
3427 r = signature_element_length(c->signature+c->index, &l);
3432 sig = strndup(c->signature + c->index + 1, l - 2);
3436 free(m->peeked_signature);
3437 m->peeked_signature = sig;
3443 *type = c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY;
3448 if (c->signature[c->index] == SD_BUS_TYPE_VARIANT) {
3454 r = message_peek_body(m, &rindex, 1, 1, &q);
3461 r = message_peek_body(m, &rindex, 1, l+1, &q);
3467 if (!validate_signature(q, l))
3474 *type = SD_BUS_TYPE_VARIANT;
3489 _public_ int sd_bus_message_rewind(sd_bus_message *m, int complete) {
3490 struct bus_container *c;
3492 assert_return(m, -EINVAL);
3493 assert_return(m->sealed, -EPERM);
3496 message_reset_containers(m);
3498 m->root_container.index = 0;
3500 c = message_get_container(m);
3502 c = message_get_container(m);
3505 m->rindex = c->begin;
3508 return !isempty(c->signature);
3511 static int message_read_ap(
3516 unsigned n_array, n_struct;
3517 TypeStack stack[BUS_CONTAINER_DEPTH];
3518 unsigned stack_ptr = 0;
3519 unsigned n_loop = 0;
3527 /* Ideally, we'd just call ourselves recursively on every
3528 * complex type. However, the state of a va_list that is
3529 * passed to a function is undefined after that function
3530 * returns. This means we need to docode the va_list linearly
3531 * in a single stackframe. We hence implement our own
3532 * home-grown stack in an array. */
3534 n_array = (unsigned) -1; /* lenght of current array entries */
3535 n_struct = strlen(types); /* length of current struct contents signature */
3542 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
3543 r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
3549 r = sd_bus_message_exit_container(m);
3557 if (n_array != (unsigned) -1)
3566 case SD_BUS_TYPE_BYTE:
3567 case SD_BUS_TYPE_BOOLEAN:
3568 case SD_BUS_TYPE_INT16:
3569 case SD_BUS_TYPE_UINT16:
3570 case SD_BUS_TYPE_INT32:
3571 case SD_BUS_TYPE_UINT32:
3572 case SD_BUS_TYPE_INT64:
3573 case SD_BUS_TYPE_UINT64:
3574 case SD_BUS_TYPE_DOUBLE:
3575 case SD_BUS_TYPE_STRING:
3576 case SD_BUS_TYPE_OBJECT_PATH:
3577 case SD_BUS_TYPE_SIGNATURE:
3578 case SD_BUS_TYPE_UNIX_FD: {
3581 p = va_arg(ap, void*);
3582 r = sd_bus_message_read_basic(m, *t, p);
3595 case SD_BUS_TYPE_ARRAY: {
3598 r = signature_element_length(t + 1, &k);
3604 memcpy(s, t + 1, k);
3607 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, s);
3618 if (n_array == (unsigned) -1) {
3623 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
3629 n_array = va_arg(ap, unsigned);
3634 case SD_BUS_TYPE_VARIANT: {
3637 s = va_arg(ap, const char *);
3641 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, s);
3651 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
3656 n_struct = strlen(s);
3657 n_array = (unsigned) -1;
3662 case SD_BUS_TYPE_STRUCT_BEGIN:
3663 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
3666 r = signature_element_length(t, &k);
3672 memcpy(s, t + 1, k - 2);
3675 r = sd_bus_message_enter_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
3685 if (n_array == (unsigned) -1) {
3690 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
3696 n_array = (unsigned) -1;
3709 _public_ int sd_bus_message_read(sd_bus_message *m, const char *types, ...) {
3713 assert_return(m, -EINVAL);
3714 assert_return(m->sealed, -EPERM);
3715 assert_return(types, -EINVAL);
3717 va_start(ap, types);
3718 r = message_read_ap(m, types, ap);
3724 _public_ int sd_bus_message_skip(sd_bus_message *m, const char *types) {
3727 assert_return(m, -EINVAL);
3728 assert_return(m->sealed, -EPERM);
3729 assert_return(types, -EINVAL);
3736 case SD_BUS_TYPE_BYTE:
3737 case SD_BUS_TYPE_BOOLEAN:
3738 case SD_BUS_TYPE_INT16:
3739 case SD_BUS_TYPE_UINT16:
3740 case SD_BUS_TYPE_INT32:
3741 case SD_BUS_TYPE_UINT32:
3742 case SD_BUS_TYPE_INT64:
3743 case SD_BUS_TYPE_UINT64:
3744 case SD_BUS_TYPE_DOUBLE:
3745 case SD_BUS_TYPE_STRING:
3746 case SD_BUS_TYPE_OBJECT_PATH:
3747 case SD_BUS_TYPE_SIGNATURE:
3748 case SD_BUS_TYPE_UNIX_FD:
3750 r = sd_bus_message_read_basic(m, *types, NULL);
3754 r = sd_bus_message_skip(m, types + 1);
3760 case SD_BUS_TYPE_ARRAY: {
3763 r = signature_element_length(types + 1, &k);
3769 memcpy(s, types+1, k);
3772 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, s);
3777 r = sd_bus_message_skip(m, s);
3784 r = sd_bus_message_exit_container(m);
3789 r = sd_bus_message_skip(m, types + 1 + k);
3796 case SD_BUS_TYPE_VARIANT: {
3797 const char *contents;
3800 r = sd_bus_message_peek_type(m, &x, &contents);
3804 if (x != SD_BUS_TYPE_VARIANT)
3807 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, contents);
3811 r = sd_bus_message_skip(m, contents);
3816 r = sd_bus_message_exit_container(m);
3820 r = sd_bus_message_skip(m, types + 1);
3827 case SD_BUS_TYPE_STRUCT_BEGIN:
3828 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
3831 r = signature_element_length(types, &k);
3837 memcpy(s, types+1, k-2);
3840 r = sd_bus_message_enter_container(m, *types == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
3844 r = sd_bus_message_skip(m, s);
3849 r = sd_bus_message_exit_container(m);
3854 r = sd_bus_message_skip(m, types + k);
3866 _public_ int sd_bus_message_read_array(sd_bus_message *m,
3870 struct bus_container *c;
3876 assert_return(m, -EINVAL);
3877 assert_return(m->sealed, -EPERM);
3878 assert_return(bus_type_is_trivial(type), -EINVAL);
3879 assert_return(ptr, -EINVAL);
3880 assert_return(size, -EINVAL);
3881 assert_return(!BUS_MESSAGE_NEED_BSWAP(m), -ENOTSUP);
3883 align = bus_type_get_alignment(type);
3887 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
3891 c = message_get_container(m);
3892 sz = BUS_MESSAGE_BSWAP32(m, *c->array_size);
3895 /* Zero length array, let's return some aligned
3896 * pointer that is not NULL */
3897 p = (uint8_t*) NULL + align;
3899 r = message_peek_body(m, &m->rindex, align, sz, &p);
3908 r = sd_bus_message_exit_container(m);
3912 *ptr = (const void*) p;
3918 message_quit_container(m);
3922 static int message_peek_fields(
3933 return buffer_peek(BUS_MESSAGE_FIELDS(m), BUS_MESSAGE_FIELDS_SIZE(m), rindex, align, nbytes, ret);
3936 static int message_peek_field_uint32(
3947 r = message_peek_fields(m, ri, 4, 4, &q);
3952 *ret = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
3957 static int message_peek_field_string(
3959 bool (*validate)(const char *p),
3970 r = message_peek_field_uint32(m, ri, &l);
3974 r = message_peek_fields(m, ri, 1, l+1, &q);
3979 if (!validate_nul(q, l))
3985 if (!validate_string(q, l))
3995 static int message_peek_field_signature(
4007 r = message_peek_fields(m, ri, 1, 1, &q);
4012 r = message_peek_fields(m, ri, 1, l+1, &q);
4016 if (!validate_signature(q, l))
4025 static int message_skip_fields(
4028 uint32_t array_size,
4029 const char **signature) {
4031 size_t original_index;
4038 original_index = *ri;
4044 if (array_size != (uint32_t) -1 &&
4045 array_size <= *ri - original_index)
4052 if (t == SD_BUS_TYPE_STRING) {
4054 r = message_peek_field_string(m, NULL, ri, NULL);
4060 } else if (t == SD_BUS_TYPE_OBJECT_PATH) {
4062 r = message_peek_field_string(m, object_path_is_valid, ri, NULL);
4068 } else if (t == SD_BUS_TYPE_SIGNATURE) {
4070 r = message_peek_field_signature(m, ri, NULL);
4076 } else if (bus_type_is_basic(t)) {
4079 align = bus_type_get_alignment(t);
4080 k = bus_type_get_size(t);
4081 assert(align > 0 && k > 0);
4083 r = message_peek_fields(m, ri, align, k, NULL);
4089 } else if (t == SD_BUS_TYPE_ARRAY) {
4091 r = signature_element_length(*signature+1, &l);
4101 strncpy(sig, *signature + 1, l-1);
4104 alignment = bus_type_get_alignment(sig[0]);
4108 r = message_peek_field_uint32(m, ri, &nas);
4111 if (nas > BUS_ARRAY_MAX_SIZE)
4114 r = message_peek_fields(m, ri, alignment, 0, NULL);
4118 r = message_skip_fields(m, ri, nas, (const char**) &s);
4123 (*signature) += 1 + l;
4125 } else if (t == SD_BUS_TYPE_VARIANT) {
4128 r = message_peek_field_signature(m, ri, &s);
4132 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
4138 } else if (t == SD_BUS_TYPE_STRUCT ||
4139 t == SD_BUS_TYPE_DICT_ENTRY) {
4141 r = signature_element_length(*signature, &l);
4148 strncpy(sig, *signature + 1, l-1);
4151 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
4162 int bus_message_parse_fields(sd_bus_message *m) {
4165 uint32_t unix_fds = 0;
4169 for (ri = 0; ri < BUS_MESSAGE_FIELDS_SIZE(m); ) {
4170 const char *signature;
4173 r = message_peek_fields(m, &ri, 8, 1, (void**) &header);
4177 r = message_peek_field_signature(m, &ri, &signature);
4182 case _BUS_MESSAGE_HEADER_INVALID:
4185 case BUS_MESSAGE_HEADER_PATH:
4190 if (!streq(signature, "o"))
4193 r = message_peek_field_string(m, object_path_is_valid, &ri, &m->path);
4196 case BUS_MESSAGE_HEADER_INTERFACE:
4201 if (!streq(signature, "s"))
4204 r = message_peek_field_string(m, interface_name_is_valid, &ri, &m->interface);
4207 case BUS_MESSAGE_HEADER_MEMBER:
4212 if (!streq(signature, "s"))
4215 r = message_peek_field_string(m, member_name_is_valid, &ri, &m->member);
4218 case BUS_MESSAGE_HEADER_ERROR_NAME:
4223 if (!streq(signature, "s"))
4226 r = message_peek_field_string(m, error_name_is_valid, &ri, &m->error.name);
4228 m->error._need_free = -1;
4232 case BUS_MESSAGE_HEADER_DESTINATION:
4237 if (!streq(signature, "s"))
4240 r = message_peek_field_string(m, service_name_is_valid, &ri, &m->destination);
4243 case BUS_MESSAGE_HEADER_SENDER:
4248 if (!streq(signature, "s"))
4251 r = message_peek_field_string(m, service_name_is_valid, &ri, &m->sender);
4253 if (r >= 0 && m->sender[0] == ':' && m->bus && m->bus->bus_client && !m->bus->is_kernel) {
4254 m->creds.unique_name = (char*) m->sender;
4255 m->creds.mask |= SD_BUS_CREDS_UNIQUE_NAME & m->bus->creds_mask;
4261 case BUS_MESSAGE_HEADER_SIGNATURE: {
4265 if (m->root_container.signature)
4268 if (!streq(signature, "g"))
4271 r = message_peek_field_signature(m, &ri, &s);
4279 free(m->root_container.signature);
4280 m->root_container.signature = c;
4284 case BUS_MESSAGE_HEADER_REPLY_SERIAL:
4285 if (m->reply_serial != 0)
4288 if (!streq(signature, "u"))
4291 r = message_peek_field_uint32(m, &ri, &m->reply_serial);
4295 if (m->reply_serial == 0)
4300 case BUS_MESSAGE_HEADER_UNIX_FDS:
4304 if (!streq(signature, "u"))
4307 r = message_peek_field_uint32(m, &ri, &unix_fds);
4317 r = message_skip_fields(m, &ri, (uint32_t) -1, (const char **) &signature);
4324 if (m->n_fds != unix_fds)
4327 if (isempty(m->root_container.signature) != (BUS_MESSAGE_BODY_SIZE(m) == 0))
4330 switch (m->header->type) {
4332 case SD_BUS_MESSAGE_SIGNAL:
4333 if (!m->path || !m->interface || !m->member)
4337 case SD_BUS_MESSAGE_METHOD_CALL:
4339 if (!m->path || !m->member)
4344 case SD_BUS_MESSAGE_METHOD_RETURN:
4346 if (m->reply_serial == 0)
4350 case SD_BUS_MESSAGE_METHOD_ERROR:
4352 if (m->reply_serial == 0 || !m->error.name)
4357 /* Try to read the error message, but if we can't it's a non-issue */
4358 if (m->header->type == SD_BUS_MESSAGE_METHOD_ERROR)
4359 sd_bus_message_read(m, "s", &m->error.message);
4364 static int bus_message_close_header(sd_bus_message *m) {
4370 if (!m->is_gvariant)
4373 if (m->n_header_offsets <= 1)
4376 assert(m->header->fields_size == m->header_offsets[m->n_header_offsets-1]);
4378 if (m->header->fields_size + m->n_header_offsets <= 0xFF)
4380 else if (m->header->fields_size + 2*m->n_header_offsets <= 0xFFFF)
4382 else if (m->header->fields_size + 4*m->n_header_offsets <= 0xFFFFFFFF)
4387 a = message_extend_fields(m, 1, z * m->n_header_offsets, false);
4391 for (i = 0; i < m->n_header_offsets; i++) {
4393 ((uint8_t*) a)[i] = (uint8_t) m->header_offsets[i];
4395 uint16_t x = htole16((uint16_t) m->header_offsets[i]);
4396 memcpy(a + 2*i, &x, 2);
4397 } else if (z == 4) {
4398 uint32_t x = htole32((uint32_t) m->header_offsets[i]);
4399 memcpy(a + 4*i, &x, 4);
4400 } else if (z == 8) {
4401 uint64_t x = htole64((uint64_t) m->header_offsets[i]);
4402 memcpy(a + 8*i, &x, 8);
4404 assert_not_reached("unknown type");
4410 int bus_message_seal(sd_bus_message *m, uint64_t serial) {
4411 struct bus_body_part *part;
4421 if (m->n_containers > 0)
4427 /* In vtables the return signature of method calls is listed,
4428 * let's check if they match if this is a response */
4429 if (m->header->type == SD_BUS_MESSAGE_METHOD_RETURN &&
4430 m->enforced_reply_signature &&
4431 !streq(strempty(m->root_container.signature), m->enforced_reply_signature))
4434 /* If gvariant marshalling is used we need to close the body structure */
4435 r = bus_message_close_struct(m, &m->root_container, false);
4439 /* If there's a non-trivial signature set, then add it in here */
4440 if (!isempty(m->root_container.signature)) {
4441 r = message_append_field_signature(m, BUS_MESSAGE_HEADER_SIGNATURE, m->root_container.signature, NULL);
4447 r = message_append_field_uint32(m, BUS_MESSAGE_HEADER_UNIX_FDS, m->n_fds);
4452 r = bus_message_close_header(m);
4456 /* Add padding at the end of the fields part, since we know
4457 * the body needs to start at an 8 byte alignment. We made
4458 * sure we allocated enough space for this, so all we need to
4459 * do here is to zero it out. */
4460 l = BUS_MESSAGE_FIELDS_SIZE(m);
4463 memset((uint8_t*) BUS_MESSAGE_FIELDS(m) + l, 0, a);
4465 /* If this is something we can send as memfd, then let's seal
4466 the memfd now. Note that we can send memfds as payload only
4467 for directed messages, and not for broadcasts. */
4468 if (m->destination && m->bus && m->bus->use_memfd) {
4469 MESSAGE_FOREACH_PART(part, i, m)
4470 if (part->memfd >= 0 && !part->sealed && (part->size > MEMFD_MIN_SIZE || m->bus->use_memfd < 0)) {
4471 bus_body_part_unmap(part);
4473 if (ioctl(part->memfd, KDBUS_CMD_MEMFD_SEAL_SET, 1) >= 0)
4474 part->sealed = true;
4478 m->header->serial = serial;
4484 _public_ int sd_bus_message_set_destination(sd_bus_message *m, const char *destination) {
4485 assert_return(m, -EINVAL);
4486 assert_return(destination, -EINVAL);
4487 assert_return(!m->sealed, -EPERM);
4488 assert_return(!m->destination, -EEXIST);
4490 return message_append_field_string(m, BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &m->destination);
4493 int bus_message_get_blob(sd_bus_message *m, void **buffer, size_t *sz) {
4497 struct bus_body_part *part;
4503 total = BUS_MESSAGE_SIZE(m);
4509 e = mempcpy(p, m->header, BUS_MESSAGE_BODY_BEGIN(m));
4510 MESSAGE_FOREACH_PART(part, i, m)
4511 e = mempcpy(e, part->data, part->size);
4513 assert(total == (size_t) ((uint8_t*) e - (uint8_t*) p));
4521 int bus_message_read_strv_extend(sd_bus_message *m, char ***l) {
4527 r = sd_bus_message_enter_container(m, 'a', "s");
4534 r = sd_bus_message_read_basic(m, 's', &s);
4540 r = strv_extend(l, s);
4545 r = sd_bus_message_exit_container(m);
4552 _public_ int sd_bus_message_read_strv(sd_bus_message *m, char ***l) {
4556 assert_return(m, -EINVAL);
4557 assert_return(m->sealed, -EPERM);
4558 assert_return(l, -EINVAL);
4560 r = bus_message_read_strv_extend(m, &strv);
4570 const char* bus_message_get_arg(sd_bus_message *m, unsigned i) {
4572 const char *t = NULL;
4577 r = sd_bus_message_rewind(m, true);
4581 for (j = 0; j <= i; j++) {
4584 r = sd_bus_message_peek_type(m, &type, NULL);
4588 if (type != SD_BUS_TYPE_STRING &&
4589 type != SD_BUS_TYPE_OBJECT_PATH &&
4590 type != SD_BUS_TYPE_SIGNATURE)
4593 r = sd_bus_message_read_basic(m, type, &t);
4601 bool bus_header_is_complete(struct bus_header *h, size_t size) {
4607 if (size < sizeof(struct bus_header))
4610 full = sizeof(struct bus_header) +
4611 (h->endian == BUS_NATIVE_ENDIAN ? h->fields_size : bswap_32(h->fields_size));
4613 return size >= full;
4616 int bus_header_message_size(struct bus_header *h, size_t *sum) {
4622 if (h->endian == BUS_NATIVE_ENDIAN) {
4623 fs = h->fields_size;
4625 } else if (h->endian == BUS_REVERSE_ENDIAN) {
4626 fs = bswap_32(h->fields_size);
4627 bs = bswap_32(h->body_size);
4631 *sum = sizeof(struct bus_header) + ALIGN8(fs) + bs;
4635 _public_ int sd_bus_message_get_errno(sd_bus_message *m) {
4636 assert_return(m, -EINVAL);
4638 if (m->header->type != SD_BUS_MESSAGE_METHOD_ERROR)
4641 return sd_bus_error_get_errno(&m->error);
4644 _public_ const char* sd_bus_message_get_signature(sd_bus_message *m, int complete) {
4645 struct bus_container *c;
4647 assert_return(m, NULL);
4649 c = complete ? &m->root_container : message_get_container(m);
4650 return c->signature ?: "";
4653 _public_ int sd_bus_message_copy(sd_bus_message *m, sd_bus_message *source, int all) {
4654 bool done_something = false;
4657 assert_return(m, -EINVAL);
4658 assert_return(source, -EINVAL);
4659 assert_return(!m->sealed, -EPERM);
4660 assert_return(source->sealed, -EPERM);
4663 const char *contents;
4678 r = sd_bus_message_peek_type(source, &type, &contents);
4684 done_something = true;
4686 if (bus_type_is_container(type) > 0) {
4688 r = sd_bus_message_enter_container(source, type, contents);
4692 r = sd_bus_message_open_container(m, type, contents);
4696 r = sd_bus_message_copy(m, source, true);
4700 r = sd_bus_message_close_container(m);
4704 r = sd_bus_message_exit_container(source);
4711 r = sd_bus_message_read_basic(source, type, &basic);
4717 if (type == SD_BUS_TYPE_OBJECT_PATH ||
4718 type == SD_BUS_TYPE_SIGNATURE ||
4719 type == SD_BUS_TYPE_STRING)
4720 r = sd_bus_message_append_basic(m, type, basic.string);
4722 r = sd_bus_message_append_basic(m, type, &basic);
4729 return done_something;
4732 _public_ int sd_bus_message_verify_type(sd_bus_message *m, char type, const char *contents) {
4737 assert_return(m, -EINVAL);
4738 assert_return(m->sealed, -EPERM);
4739 assert_return(!type || bus_type_is_valid(type), -EINVAL);
4740 assert_return(!contents || signature_is_valid(contents, true), -EINVAL);
4741 assert_return(type || contents, -EINVAL);
4742 assert_return(!contents || !type || bus_type_is_container(type), -EINVAL);
4744 r = sd_bus_message_peek_type(m, &t, &c);
4748 if (type != 0 && type != t)
4751 if (contents && !streq_ptr(contents, c))
4757 _public_ sd_bus *sd_bus_message_get_bus(sd_bus_message *m) {
4758 assert_return(m, NULL);