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"
40 static int message_append_basic(sd_bus_message *m, char type, const void *p, const void **stored);
42 static void *adjust_pointer(const void *p, void *old_base, size_t sz, void *new_base) {
47 if (old_base == new_base)
50 if ((uint8_t*) p < (uint8_t*) old_base)
53 if ((uint8_t*) p >= (uint8_t*) old_base + sz)
56 return (uint8_t*) new_base + ((uint8_t*) p - (uint8_t*) old_base);
59 static void message_free_part(sd_bus_message *m, struct bus_body_part *part) {
63 if (part->memfd >= 0) {
64 /* If we can reuse the memfd, try that. For that it
65 * can't be sealed yet. */
68 bus_kernel_push_memfd(m->bus, part->memfd, part->data, part->mapped);
71 assert_se(munmap(part->data, part->mapped) == 0);
73 close_nointr_nofail(part->memfd);
76 } else if (part->munmap_this)
77 munmap(part->data, part->mapped);
78 else if (part->free_this)
85 static void message_reset_parts(sd_bus_message *m) {
86 struct bus_body_part *part;
91 while (m->n_body_parts > 0) {
92 struct bus_body_part *next = part->next;
93 message_free_part(m, part);
100 m->cached_rindex_part = NULL;
101 m->cached_rindex_part_begin = 0;
104 static void message_reset_containers(sd_bus_message *m) {
109 for (i = 0; i < m->n_containers; i++) {
110 free(m->containers[i].signature);
111 free(m->containers[i].offsets);
115 m->containers = NULL;
117 m->n_containers = m->containers_allocated = 0;
118 m->root_container.index = 0;
121 static void message_free(sd_bus_message *m) {
127 message_reset_parts(m);
132 if (m->release_kdbus) {
135 off = (uint8_t *)m->kdbus - (uint8_t *)m->bus->kdbus_buffer;
136 ioctl(m->bus->input_fd, KDBUS_CMD_FREE, &off);
140 sd_bus_unref(m->bus);
143 close_many(m->fds, m->n_fds);
147 if (m->iovec != m->iovec_fixed)
150 message_reset_containers(m);
151 free(m->root_container.signature);
152 free(m->root_container.offsets);
154 free(m->peeked_signature);
156 bus_creds_done(&m->creds);
160 static void *message_extend_fields(sd_bus_message *m, size_t align, size_t sz, bool add_offset) {
162 size_t old_size, new_size, start;
169 old_size = sizeof(struct bus_header) + m->header->fields_size;
170 start = ALIGN_TO(old_size, align);
171 new_size = start + sz;
173 if (old_size == new_size)
174 return (uint8_t*) m->header + old_size;
176 if (new_size > (size_t) ((uint32_t) -1))
179 if (m->free_header) {
180 np = realloc(m->header, ALIGN8(new_size));
184 /* Initially, the header is allocated as part of of
185 * the sd_bus_message itself, let's replace it by
188 np = malloc(ALIGN8(new_size));
192 memcpy(np, m->header, sizeof(struct bus_header));
195 /* Zero out padding */
196 if (start > old_size)
197 memset((uint8_t*) np + old_size, 0, start - old_size);
201 m->header->fields_size = new_size - sizeof(struct bus_header);
203 /* Adjust quick access pointers */
204 m->path = adjust_pointer(m->path, op, old_size, m->header);
205 m->interface = adjust_pointer(m->interface, op, old_size, m->header);
206 m->member = adjust_pointer(m->member, op, old_size, m->header);
207 m->destination = adjust_pointer(m->destination, op, old_size, m->header);
208 m->sender = adjust_pointer(m->sender, op, old_size, m->header);
209 m->error.name = adjust_pointer(m->error.name, op, old_size, m->header);
211 m->free_header = true;
214 if (m->n_header_offsets >= ELEMENTSOF(m->header_offsets))
217 m->header_offsets[m->n_header_offsets++] = new_size - sizeof(struct bus_header);
220 return (uint8_t*) np + start;
227 static int message_append_field_string(
239 /* dbus1 doesn't allow strings over 32bit, let's enforce this
240 * globally, to not risk convertability */
242 if (l > (size_t) (uint32_t) -1)
245 /* Signature "(yv)" where the variant contains "s" */
247 if (BUS_MESSAGE_IS_GVARIANT(m)) {
249 /* (field id byte + 7x padding, ((string + NUL) + NUL + signature string 's') */
250 p = message_extend_fields(m, 8, 1 + 7 + l + 1 + 1 + 1, true);
262 *ret = (char*) p + 8;
265 /* (field id byte + (signature length + signature 's' + NUL) + (string length + string + NUL)) */
266 p = message_extend_fields(m, 8, 4 + 4 + l + 1, false);
275 ((uint32_t*) p)[1] = l;
276 memcpy(p + 8, s, l + 1);
279 *ret = (char*) p + 8;
285 static int message_append_field_signature(
296 /* dbus1 doesn't allow signatures over 32bit, let's enforce
297 * this globally, to not risk convertability */
302 /* Signature "(yv)" where the variant contains "g" */
304 if (BUS_MESSAGE_IS_GVARIANT(m))
305 /* For gvariant the serialization is the same as for normal strings */
306 return message_append_field_string(m, h, 'g', s, ret);
308 /* (field id byte + (signature length + signature 'g' + NUL) + (string length + string + NUL)) */
309 p = message_extend_fields(m, 8, 4 + 1 + l + 1, false);
315 p[2] = SD_BUS_TYPE_SIGNATURE;
318 memcpy(p + 5, s, l + 1);
321 *ret = (const char*) p + 5;
327 static int message_append_field_uint32(sd_bus_message *m, uint8_t h, uint32_t x) {
332 if (BUS_MESSAGE_IS_GVARIANT(m)) {
333 /* (field id byte + 7x padding + ((value + NUL + signature string 'u') */
335 p = message_extend_fields(m, 8, 1 + 7 + 4 + 1 + 1, true);
341 *((uint32_t*) (p + 8)) = x;
345 /* (field id byte + (signature length + signature 'u' + NUL) + value) */
346 p = message_extend_fields(m, 8, 4 + 4, false);
352 p[2] = SD_BUS_TYPE_UINT32;
355 ((uint32_t*) p)[1] = x;
361 int bus_message_from_header(
367 const struct ucred *ucred,
370 sd_bus_message **ret) {
373 struct bus_header *h;
376 assert(buffer || length <= 0);
377 assert(fds || n_fds <= 0);
380 if (length < sizeof(struct bus_header))
384 if (h->version != 1 &&
391 if (h->type == _SD_BUS_MESSAGE_TYPE_INVALID)
394 if (h->endian != BUS_LITTLE_ENDIAN &&
395 h->endian != BUS_BIG_ENDIAN)
398 a = ALIGN(sizeof(sd_bus_message)) + ALIGN(extra);
401 label_sz = strlen(label);
416 m->creds.uid = ucred->uid;
417 m->creds.pid = ucred->pid;
418 m->creds.gid = ucred->gid;
419 m->creds.mask |= SD_BUS_CREDS_UID | SD_BUS_CREDS_PID | SD_BUS_CREDS_GID;
423 m->creds.label = (char*) m + ALIGN(sizeof(sd_bus_message)) + ALIGN(extra);
424 memcpy(m->creds.label, label, label_sz + 1);
426 m->creds.mask |= SD_BUS_CREDS_SELINUX_CONTEXT;
430 m->bus = sd_bus_ref(bus);
436 int bus_message_from_malloc(
442 const struct ucred *ucred,
444 sd_bus_message **ret) {
450 r = bus_message_from_header(bus, buffer, length, fds, n_fds, ucred, label, 0, &m);
454 if (length != BUS_MESSAGE_SIZE(m)) {
459 sz = length - sizeof(struct bus_header) - ALIGN8(BUS_MESSAGE_FIELDS_SIZE(m));
462 m->body.data = (uint8_t*) buffer + sizeof(struct bus_header) + ALIGN8(BUS_MESSAGE_FIELDS_SIZE(m));
464 m->body.sealed = true;
469 m->iovec = m->iovec_fixed;
470 m->iovec[0].iov_base = buffer;
471 m->iovec[0].iov_len = length;
473 r = bus_message_parse_fields(m);
477 /* We take possession of the memory and fds now */
478 m->free_header = true;
489 static sd_bus_message *message_new(sd_bus *bus, uint8_t type) {
492 m = malloc0(ALIGN(sizeof(sd_bus_message)) + sizeof(struct bus_header));
497 m->header = (struct bus_header*) ((uint8_t*) m + ALIGN(sizeof(struct sd_bus_message)));
498 m->header->endian = BUS_NATIVE_ENDIAN;
499 m->header->type = type;
500 m->header->version = bus ? bus->message_version : 1;
501 m->allow_fds = !bus || bus->can_fds || (bus->state != BUS_HELLO && bus->state != BUS_RUNNING);
502 m->root_container.need_offsets = BUS_MESSAGE_IS_GVARIANT(m);
505 m->bus = sd_bus_ref(bus);
510 _public_ int sd_bus_message_new_signal(
513 const char *interface,
515 sd_bus_message **m) {
520 assert_return(!bus || bus->state != BUS_UNSET, -ENOTCONN);
521 assert_return(object_path_is_valid(path), -EINVAL);
522 assert_return(interface_name_is_valid(interface), -EINVAL);
523 assert_return(member_name_is_valid(member), -EINVAL);
524 assert_return(m, -EINVAL);
526 t = message_new(bus, SD_BUS_MESSAGE_SIGNAL);
530 t->header->flags |= BUS_MESSAGE_NO_REPLY_EXPECTED;
532 r = message_append_field_string(t, BUS_MESSAGE_HEADER_PATH, SD_BUS_TYPE_OBJECT_PATH, path, &t->path);
535 r = message_append_field_string(t, BUS_MESSAGE_HEADER_INTERFACE, SD_BUS_TYPE_STRING, interface, &t->interface);
538 r = message_append_field_string(t, BUS_MESSAGE_HEADER_MEMBER, SD_BUS_TYPE_STRING, member, &t->member);
546 sd_bus_message_unref(t);
550 _public_ int sd_bus_message_new_method_call(
552 const char *destination,
554 const char *interface,
556 sd_bus_message **m) {
561 assert_return(!bus || bus->state != BUS_UNSET, -ENOTCONN);
562 assert_return(!destination || service_name_is_valid(destination), -EINVAL);
563 assert_return(object_path_is_valid(path), -EINVAL);
564 assert_return(!interface || interface_name_is_valid(interface), -EINVAL);
565 assert_return(member_name_is_valid(member), -EINVAL);
566 assert_return(m, -EINVAL);
568 t = message_new(bus, SD_BUS_MESSAGE_METHOD_CALL);
572 r = message_append_field_string(t, BUS_MESSAGE_HEADER_PATH, SD_BUS_TYPE_OBJECT_PATH, path, &t->path);
575 r = message_append_field_string(t, BUS_MESSAGE_HEADER_MEMBER, SD_BUS_TYPE_STRING, member, &t->member);
580 r = message_append_field_string(t, BUS_MESSAGE_HEADER_INTERFACE, SD_BUS_TYPE_STRING, interface, &t->interface);
586 r = message_append_field_string(t, BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &t->destination);
599 static int message_new_reply(
600 sd_bus_message *call,
602 sd_bus_message **m) {
607 assert_return(call, -EINVAL);
608 assert_return(call->sealed, -EPERM);
609 assert_return(call->header->type == SD_BUS_MESSAGE_METHOD_CALL, -EINVAL);
610 assert_return(!call->bus || call->bus->state != BUS_UNSET, -ENOTCONN);
611 assert_return(m, -EINVAL);
613 t = message_new(call->bus, type);
617 t->header->flags |= BUS_MESSAGE_NO_REPLY_EXPECTED;
618 t->reply_serial = BUS_MESSAGE_SERIAL(call);
620 r = message_append_field_uint32(t, BUS_MESSAGE_HEADER_REPLY_SERIAL, t->reply_serial);
625 r = message_append_field_string(t, BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, call->sender, &t->destination);
630 t->dont_send = !!(call->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED);
631 t->enforced_reply_signature = call->enforced_reply_signature;
641 _public_ int sd_bus_message_new_method_return(
642 sd_bus_message *call,
643 sd_bus_message **m) {
645 return message_new_reply(call, SD_BUS_MESSAGE_METHOD_RETURN, m);
648 _public_ int sd_bus_message_new_method_error(
649 sd_bus_message *call,
650 const sd_bus_error *e,
651 sd_bus_message **m) {
656 assert_return(sd_bus_error_is_set(e), -EINVAL);
657 assert_return(m, -EINVAL);
659 r = message_new_reply(call, SD_BUS_MESSAGE_METHOD_ERROR, &t);
663 r = message_append_field_string(t, BUS_MESSAGE_HEADER_ERROR_NAME, SD_BUS_TYPE_STRING, e->name, &t->error.name);
668 r = message_append_basic(t, SD_BUS_TYPE_STRING, e->message, (const void**) &t->error.message);
673 t->error._need_free = -1;
683 _public_ int sd_bus_message_new_method_errorf(
684 sd_bus_message *call,
690 _cleanup_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
693 assert_return(name, -EINVAL);
694 assert_return(m, -EINVAL);
696 va_start(ap, format);
697 bus_error_setfv(&error, name, format, ap);
700 return sd_bus_message_new_method_error(call, &error, m);
703 _public_ int sd_bus_message_new_method_errno(
704 sd_bus_message *call,
706 const sd_bus_error *p,
707 sd_bus_message **m) {
709 _cleanup_free_ sd_bus_error berror = SD_BUS_ERROR_NULL;
711 if (sd_bus_error_is_set(p))
712 return sd_bus_message_new_method_error(call, p, m);
714 sd_bus_error_set_errno(&berror, error);
716 return sd_bus_message_new_method_error(call, &berror, m);
719 _public_ int sd_bus_message_new_method_errnof(
720 sd_bus_message *call,
726 _cleanup_free_ sd_bus_error berror = SD_BUS_ERROR_NULL;
729 va_start(ap, format);
730 bus_error_set_errnofv(&berror, error, format, ap);
733 return sd_bus_message_new_method_error(call, &berror, m);
736 int bus_message_new_synthetic_error(
739 const sd_bus_error *e,
740 sd_bus_message **m) {
745 assert(sd_bus_error_is_set(e));
748 t = message_new(bus, SD_BUS_MESSAGE_METHOD_ERROR);
752 t->header->flags |= BUS_MESSAGE_NO_REPLY_EXPECTED;
753 t->reply_serial = serial;
755 r = message_append_field_uint32(t, BUS_MESSAGE_HEADER_REPLY_SERIAL, t->reply_serial);
759 if (bus && bus->unique_name) {
760 r = message_append_field_string(t, BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, bus->unique_name, &t->destination);
765 r = message_append_field_string(t, BUS_MESSAGE_HEADER_ERROR_NAME, SD_BUS_TYPE_STRING, e->name, &t->error.name);
770 r = message_append_basic(t, SD_BUS_TYPE_STRING, e->message, (const void**) &t->error.message);
775 t->error._need_free = -1;
785 _public_ sd_bus_message* sd_bus_message_ref(sd_bus_message *m) {
786 assert_return(m, NULL);
788 assert(m->n_ref > 0);
794 _public_ sd_bus_message* sd_bus_message_unref(sd_bus_message *m) {
799 assert(m->n_ref > 0);
808 _public_ int sd_bus_message_get_type(sd_bus_message *m, uint8_t *type) {
809 assert_return(m, -EINVAL);
810 assert_return(type, -EINVAL);
812 *type = m->header->type;
816 _public_ int sd_bus_message_get_serial(sd_bus_message *m, uint64_t *serial) {
817 assert_return(m, -EINVAL);
818 assert_return(serial, -EINVAL);
819 assert_return(m->header->serial != 0, -ENOENT);
821 *serial = BUS_MESSAGE_SERIAL(m);
825 _public_ int sd_bus_message_get_reply_serial(sd_bus_message *m, uint64_t *serial) {
826 assert_return(m, -EINVAL);
827 assert_return(serial, -EINVAL);
828 assert_return(m->reply_serial != 0, -ENOENT);
830 *serial = m->reply_serial;
834 _public_ int sd_bus_message_get_no_reply(sd_bus_message *m) {
835 assert_return(m, -EINVAL);
837 return m->header->type == SD_BUS_MESSAGE_METHOD_CALL ? !!(m->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED) : 0;
840 _public_ int sd_bus_message_get_no_auto_start(sd_bus_message *m) {
841 assert_return(m, -EINVAL);
843 return !!(m->header->flags & BUS_MESSAGE_NO_AUTO_START);
846 _public_ const char *sd_bus_message_get_path(sd_bus_message *m) {
847 assert_return(m, NULL);
852 _public_ const char *sd_bus_message_get_interface(sd_bus_message *m) {
853 assert_return(m, NULL);
858 _public_ const char *sd_bus_message_get_member(sd_bus_message *m) {
859 assert_return(m, NULL);
864 _public_ const char *sd_bus_message_get_destination(sd_bus_message *m) {
865 assert_return(m, NULL);
867 return m->destination;
870 _public_ const char *sd_bus_message_get_sender(sd_bus_message *m) {
871 assert_return(m, NULL);
876 _public_ const sd_bus_error *sd_bus_message_get_error(sd_bus_message *m) {
877 assert_return(m, NULL);
878 assert_return(sd_bus_error_is_set(&m->error), NULL);
883 _public_ int sd_bus_message_get_monotonic_timestamp(sd_bus_message *m, uint64_t *usec) {
884 assert_return(m, -EINVAL);
885 assert_return(usec, -EINVAL);
886 assert_return(m->monotonic > 0, -ENODATA);
888 *usec = m->monotonic;
892 _public_ int sd_bus_message_get_realtime_timestamp(sd_bus_message *m, uint64_t *usec) {
893 assert_return(m, -EINVAL);
894 assert_return(usec, -EINVAL);
895 assert_return(m->realtime > 0, -ENODATA);
901 _public_ sd_bus_creds *sd_bus_message_get_creds(sd_bus_message *m) {
902 assert_return(m, NULL);
904 if (m->creds.mask == 0)
910 _public_ int sd_bus_message_is_signal(sd_bus_message *m,
911 const char *interface,
912 const char *member) {
913 assert_return(m, -EINVAL);
915 if (m->header->type != SD_BUS_MESSAGE_SIGNAL)
918 if (interface && (!m->interface || !streq(m->interface, interface)))
921 if (member && (!m->member || !streq(m->member, member)))
927 _public_ int sd_bus_message_is_method_call(sd_bus_message *m,
928 const char *interface,
929 const char *member) {
930 assert_return(m, -EINVAL);
932 if (m->header->type != SD_BUS_MESSAGE_METHOD_CALL)
935 if (interface && (!m->interface || !streq(m->interface, interface)))
938 if (member && (!m->member || !streq(m->member, member)))
944 _public_ int sd_bus_message_is_method_error(sd_bus_message *m, const char *name) {
945 assert_return(m, -EINVAL);
947 if (m->header->type != SD_BUS_MESSAGE_METHOD_ERROR)
950 if (name && (!m->error.name || !streq(m->error.name, name)))
956 _public_ int sd_bus_message_set_no_reply(sd_bus_message *m, int b) {
957 assert_return(m, -EINVAL);
958 assert_return(!m->sealed, -EPERM);
959 assert_return(m->header->type == SD_BUS_MESSAGE_METHOD_CALL, -EPERM);
962 m->header->flags |= BUS_MESSAGE_NO_REPLY_EXPECTED;
964 m->header->flags &= ~BUS_MESSAGE_NO_REPLY_EXPECTED;
969 _public_ int sd_bus_message_set_no_auto_start(sd_bus_message *m, int b) {
970 assert_return(m, -EINVAL);
971 assert_return(!m->sealed, -EPERM);
974 m->header->flags |= BUS_MESSAGE_NO_AUTO_START;
976 m->header->flags &= ~BUS_MESSAGE_NO_AUTO_START;
981 static struct bus_container *message_get_container(sd_bus_message *m) {
984 if (m->n_containers == 0)
985 return &m->root_container;
987 assert(m->containers);
988 return m->containers + m->n_containers - 1;
991 struct bus_body_part *message_append_part(sd_bus_message *m) {
992 struct bus_body_part *part;
999 if (m->n_body_parts <= 0) {
1003 assert(m->body_end);
1005 part = new0(struct bus_body_part, 1);
1011 m->body_end->next = part;
1021 static void part_zero(struct bus_body_part *part, size_t sz) {
1026 /* All other fields can be left in their defaults */
1027 assert(!part->data);
1028 assert(part->memfd < 0);
1031 part->is_zero = true;
1032 part->sealed = true;
1035 static int part_make_space(
1036 struct sd_bus_message *m,
1037 struct bus_body_part *part,
1046 assert(!part->sealed);
1051 if (!part->data && part->memfd < 0)
1052 part->memfd = bus_kernel_pop_memfd(m->bus, &part->data, &part->mapped);
1054 if (part->memfd >= 0) {
1057 r = ioctl(part->memfd, KDBUS_CMD_MEMFD_SIZE_SET, &u);
1063 if (!part->data || sz > part->mapped) {
1064 size_t psz = PAGE_ALIGN(sz > 0 ? sz : 1);
1066 if (part->mapped <= 0)
1067 n = mmap(NULL, psz, PROT_READ|PROT_WRITE, MAP_SHARED, part->memfd, 0);
1069 n = mremap(part->data, part->mapped, psz, MREMAP_MAYMOVE);
1071 if (n == MAP_FAILED) {
1080 part->munmap_this = true;
1082 n = realloc(part->data, MAX(sz, 1u));
1089 part->free_this = true;
1093 *q = part->data ? (uint8_t*) part->data + part->size : NULL;
1099 static int message_add_offset(sd_bus_message *m, size_t offset) {
1100 struct bus_container *c;
1103 assert(BUS_MESSAGE_IS_GVARIANT(m));
1105 /* Add offset to current container, unless this is the first
1106 * item in it, which will have the 0 offset, which we can
1108 c = message_get_container(m);
1110 if (!c->need_offsets)
1113 if (!GREEDY_REALLOC(c->offsets, c->offsets_allocated, c->n_offsets + 1))
1116 c->offsets[c->n_offsets++] = offset;
1120 static void message_extend_containers(sd_bus_message *m, size_t expand) {
1121 struct bus_container *c;
1128 /* Update counters */
1129 for (c = m->containers; c < m->containers + m->n_containers; c++) {
1132 *c->array_size += expand;
1136 static void *message_extend_body(sd_bus_message *m, size_t align, size_t sz, bool add_offset) {
1137 size_t start_body, end_body, padding, added;
1148 start_body = ALIGN_TO((size_t) m->header->body_size, align);
1149 end_body = start_body + sz;
1151 padding = start_body - m->header->body_size;
1152 added = padding + sz;
1154 /* Check for 32bit overflows */
1155 if (end_body > (size_t) ((uint32_t) -1)) {
1161 struct bus_body_part *part = NULL;
1165 m->n_body_parts <= 0 ||
1166 m->body_end->sealed ||
1167 padding != ALIGN_TO(m->body_end->size, align) - m->body_end->size;
1171 part = message_append_part(m);
1175 part_zero(part, padding);
1178 part = message_append_part(m);
1182 r = part_make_space(m, part, sz, &p);
1186 struct bus_container *c;
1188 size_t os, start_part, end_part;
1194 start_part = ALIGN_TO(part->size, align);
1195 end_part = start_part + sz;
1197 r = part_make_space(m, part, end_part, &p);
1202 memset(p, 0, padding);
1203 p = (uint8_t*) p + padding;
1206 /* Readjust pointers */
1207 for (c = m->containers; c < m->containers + m->n_containers; c++)
1208 c->array_size = adjust_pointer(c->array_size, op, os, part->data);
1210 m->error.message = (const char*) adjust_pointer(m->error.message, op, os, part->data);
1213 /* Return something that is not NULL and is aligned */
1214 p = (uint8_t *) NULL + align;
1216 m->header->body_size = end_body;
1217 message_extend_containers(m, added);
1220 r = message_add_offset(m, end_body);
1230 static int message_push_fd(sd_bus_message *m, int fd) {
1241 copy = fcntl(fd, F_DUPFD_CLOEXEC, 3);
1245 f = realloc(m->fds, sizeof(int) * (m->n_fds + 1));
1248 close_nointr_nofail(copy);
1253 m->fds[m->n_fds] = copy;
1259 int message_append_basic(sd_bus_message *m, char type, const void *p, const void **stored) {
1260 _cleanup_close_ int fd = -1;
1261 struct bus_container *c;
1265 assert_return(m, -EINVAL);
1266 assert_return(!m->sealed, -EPERM);
1267 assert_return(bus_type_is_basic(type), -EINVAL);
1268 assert_return(!m->poisoned, -ESTALE);
1270 c = message_get_container(m);
1272 if (c->signature && c->signature[c->index]) {
1273 /* Container signature is already set */
1275 if (c->signature[c->index] != type)
1280 /* Maybe we can append to the signature? But only if this is the top-level container*/
1281 if (c->enclosing != 0)
1284 e = strextend(&c->signature, CHAR_TO_STR(type), NULL);
1291 if (BUS_MESSAGE_IS_GVARIANT(m)) {
1297 case SD_BUS_TYPE_SIGNATURE:
1298 case SD_BUS_TYPE_STRING:
1301 /* Fall through... */
1302 case SD_BUS_TYPE_OBJECT_PATH:
1310 case SD_BUS_TYPE_BOOLEAN:
1312 u8 = p && *(int*) p;
1318 case SD_BUS_TYPE_UNIX_FD:
1323 fd = message_push_fd(m, *(int*) p);
1334 align = bus_gvariant_get_alignment(CHAR_TO_STR(type));
1335 sz = bus_gvariant_get_size(CHAR_TO_STR(type));
1342 a = message_extend_body(m, align, sz, true);
1349 *stored = (const uint8_t*) a;
1356 case SD_BUS_TYPE_STRING:
1357 /* To make things easy we'll serialize a NULL string
1358 * into the empty string */
1361 /* Fall through... */
1362 case SD_BUS_TYPE_OBJECT_PATH:
1368 sz = 4 + strlen(p) + 1;
1371 case SD_BUS_TYPE_SIGNATURE:
1376 sz = 1 + strlen(p) + 1;
1379 case SD_BUS_TYPE_BOOLEAN:
1381 u32 = p && *(int*) p;
1387 case SD_BUS_TYPE_UNIX_FD:
1392 fd = message_push_fd(m, *(int*) p);
1403 align = bus_type_get_alignment(type);
1404 sz = bus_type_get_size(type);
1411 a = message_extend_body(m, align, sz, false);
1415 if (type == SD_BUS_TYPE_STRING || type == SD_BUS_TYPE_OBJECT_PATH) {
1416 *(uint32_t*) a = sz - 5;
1417 memcpy((uint8_t*) a + 4, p, sz - 4);
1420 *stored = (const uint8_t*) a + 4;
1422 } else if (type == SD_BUS_TYPE_SIGNATURE) {
1423 *(uint8_t*) a = sz - 1;
1424 memcpy((uint8_t*) a + 1, p, sz - 1);
1427 *stored = (const uint8_t*) a + 1;
1436 if (type == SD_BUS_TYPE_UNIX_FD)
1439 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1446 _public_ int sd_bus_message_append_basic(sd_bus_message *m, char type, const void *p) {
1447 return message_append_basic(m, type, p, NULL);
1450 _public_ int sd_bus_message_append_string_space(
1455 struct bus_container *c;
1458 assert_return(m, -EINVAL);
1459 assert_return(s, -EINVAL);
1460 assert_return(!m->sealed, -EPERM);
1461 assert_return(!m->poisoned, -ESTALE);
1463 c = message_get_container(m);
1465 if (c->signature && c->signature[c->index]) {
1466 /* Container signature is already set */
1468 if (c->signature[c->index] != SD_BUS_TYPE_STRING)
1473 /* Maybe we can append to the signature? But only if this is the top-level container*/
1474 if (c->enclosing != 0)
1477 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRING), NULL);
1484 if (BUS_MESSAGE_IS_GVARIANT(m)) {
1485 a = message_extend_body(m, 1, size + 1, true);
1491 a = message_extend_body(m, 4, 4 + size + 1, false);
1495 *(uint32_t*) a = size;
1501 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1507 _public_ int sd_bus_message_append_string_iovec(
1509 const struct iovec *iov,
1517 assert_return(m, -EINVAL);
1518 assert_return(!m->sealed, -EPERM);
1519 assert_return(iov || n == 0, -EINVAL);
1520 assert_return(!m->poisoned, -ESTALE);
1522 size = IOVEC_TOTAL_SIZE(iov, n);
1524 r = sd_bus_message_append_string_space(m, size, &p);
1528 for (i = 0; i < n; i++) {
1530 if (iov[i].iov_base)
1531 memcpy(p, iov[i].iov_base, iov[i].iov_len);
1533 memset(p, ' ', iov[i].iov_len);
1535 p += iov[i].iov_len;
1541 static int bus_message_open_array(
1543 struct bus_container *c,
1544 const char *contents,
1545 uint32_t **array_size,
1547 bool *need_offsets) {
1557 assert(need_offsets);
1559 if (!signature_is_single(contents, true))
1562 if (c->signature && c->signature[c->index]) {
1564 /* Verify the existing signature */
1566 if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
1569 if (!startswith(c->signature + c->index + 1, contents))
1572 nindex = c->index + 1 + strlen(contents);
1576 if (c->enclosing != 0)
1579 /* Extend the existing signature */
1581 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_ARRAY), contents, NULL);
1587 nindex = e - c->signature;
1590 if (BUS_MESSAGE_IS_GVARIANT(m)) {
1591 alignment = bus_gvariant_get_alignment(contents);
1595 /* Add alignment padding and add to offset list */
1596 if (!message_extend_body(m, alignment, 0, false))
1599 r = bus_gvariant_is_fixed_size(contents);
1603 *begin = m->header->body_size;
1604 *need_offsets = r == 0;
1608 struct bus_body_part *o;
1610 alignment = bus_type_get_alignment(contents[0]);
1614 a = message_extend_body(m, 4, 4, false);
1619 op = m->body_end->data;
1620 os = m->body_end->size;
1622 /* Add alignment between size and first element */
1623 if (!message_extend_body(m, alignment, 0, false))
1626 /* location of array size might have changed so let's readjust a */
1627 if (o == m->body_end)
1628 a = adjust_pointer(a, op, os, m->body_end->data);
1634 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1640 static int bus_message_open_variant(
1642 struct bus_container *c,
1643 const char *contents) {
1649 if (!signature_is_single(contents, false))
1652 if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
1655 if (c->signature && c->signature[c->index]) {
1657 if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
1663 if (c->enclosing != 0)
1666 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_VARIANT), NULL);
1673 if (BUS_MESSAGE_IS_GVARIANT(m)) {
1674 /* Variants are always aligned to 8 */
1676 if (!message_extend_body(m, 8, 0, false))
1683 l = strlen(contents);
1684 a = message_extend_body(m, 1, 1 + l + 1, false);
1689 memcpy((uint8_t*) a + 1, contents, l + 1);
1692 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1698 static int bus_message_open_struct(
1700 struct bus_container *c,
1701 const char *contents,
1703 bool *need_offsets) {
1712 assert(need_offsets);
1714 if (!signature_is_valid(contents, false))
1717 if (c->signature && c->signature[c->index]) {
1720 l = strlen(contents);
1722 if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
1723 !startswith(c->signature + c->index + 1, contents) ||
1724 c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
1727 nindex = c->index + 1 + l + 1;
1731 if (c->enclosing != 0)
1734 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_BEGIN), contents, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_END), NULL);
1740 nindex = e - c->signature;
1743 if (BUS_MESSAGE_IS_GVARIANT(m)) {
1746 alignment = bus_gvariant_get_alignment(contents);
1750 if (!message_extend_body(m, alignment, 0, false))
1753 r = bus_gvariant_is_fixed_size(contents);
1757 *begin = m->header->body_size;
1758 *need_offsets = r == 0;
1760 /* Align contents to 8 byte boundary */
1761 if (!message_extend_body(m, 8, 0, false))
1765 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1771 static int bus_message_open_dict_entry(
1773 struct bus_container *c,
1774 const char *contents,
1776 bool *need_offsets) {
1784 assert(need_offsets);
1786 if (!signature_is_pair(contents))
1789 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1792 if (c->signature && c->signature[c->index]) {
1795 l = strlen(contents);
1797 if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
1798 !startswith(c->signature + c->index + 1, contents) ||
1799 c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
1804 if (BUS_MESSAGE_IS_GVARIANT(m)) {
1807 alignment = bus_gvariant_get_alignment(contents);
1811 if (!message_extend_body(m, alignment, 0, false))
1814 r = bus_gvariant_is_fixed_size(contents);
1818 *begin = m->header->body_size;
1819 *need_offsets = r == 0;
1821 /* Align contents to 8 byte boundary */
1822 if (!message_extend_body(m, 8, 0, false))
1829 _public_ int sd_bus_message_open_container(
1832 const char *contents) {
1834 struct bus_container *c, *w;
1835 uint32_t *array_size = NULL;
1837 size_t before, begin;
1838 bool need_offsets = false;
1841 assert_return(m, -EINVAL);
1842 assert_return(!m->sealed, -EPERM);
1843 assert_return(contents, -EINVAL);
1844 assert_return(!m->poisoned, -ESTALE);
1846 /* Make sure we have space for one more container */
1847 if (!GREEDY_REALLOC(m->containers, m->containers_allocated, m->n_containers + 1)) {
1852 c = message_get_container(m);
1854 signature = strdup(contents);
1860 /* Save old index in the parent container, in case we have to
1861 * abort this container */
1862 c->saved_index = c->index;
1863 before = m->header->body_size;
1865 if (type == SD_BUS_TYPE_ARRAY)
1866 r = bus_message_open_array(m, c, contents, &array_size, &begin, &need_offsets);
1867 else if (type == SD_BUS_TYPE_VARIANT)
1868 r = bus_message_open_variant(m, c, contents);
1869 else if (type == SD_BUS_TYPE_STRUCT)
1870 r = bus_message_open_struct(m, c, contents, &begin, &need_offsets);
1871 else if (type == SD_BUS_TYPE_DICT_ENTRY)
1872 r = bus_message_open_dict_entry(m, c, contents, &begin, &need_offsets);
1881 /* OK, let's fill it in */
1882 w = m->containers + m->n_containers++;
1883 w->enclosing = type;
1884 w->signature = signature;
1886 w->array_size = array_size;
1889 w->n_offsets = w->offsets_allocated = 0;
1891 w->need_offsets = need_offsets;
1896 static size_t determine_word_size(size_t sz, size_t extra) {
1897 if (sz + extra <= 0xFF)
1899 else if (sz + extra*2 <= 0xFFFF)
1901 else if (sz + extra*4 <= 0xFFFFFFFF)
1907 static size_t read_word_le(void *p, size_t sz) {
1917 return *(uint8_t*) p;
1922 return le16toh(x.u16);
1924 return le32toh(x.u32);
1926 return le64toh(x.u64);
1928 assert_not_reached("unknown word width");
1931 static void write_word_le(void *p, size_t sz, size_t value) {
1939 assert(sz == 8 || (value < (1ULL << (sz*8))));
1942 *(uint8_t*) p = value;
1945 x.u16 = htole16((uint16_t) value);
1947 x.u32 = htole32((uint32_t) value);
1949 x.u64 = htole64((uint64_t) value);
1951 assert_not_reached("unknown word width");
1956 static int bus_message_close_array(sd_bus_message *m, struct bus_container *c) {
1961 if (!BUS_MESSAGE_IS_GVARIANT(m))
1964 if (c->need_offsets) {
1965 size_t payload, sz, i;
1968 /* Variable-width arrays */
1970 payload = c->n_offsets > 0 ? c->offsets[c->n_offsets-1] - c->begin : 0;
1971 sz = determine_word_size(payload, c->n_offsets);
1973 a = message_extend_body(m, 1, sz * c->n_offsets, true);
1977 for (i = 0; i < c->n_offsets; i++)
1978 write_word_le(a + sz*i, sz, c->offsets[i] - c->begin);
1982 /* Fixed-width or empty arrays */
1984 a = message_extend_body(m, 1, 0, true); /* let's add offset to parent */
1992 static int bus_message_close_variant(sd_bus_message *m, struct bus_container *c) {
1999 if (!BUS_MESSAGE_IS_GVARIANT(m))
2002 l = strlen(c->signature);
2004 a = message_extend_body(m, 1, 1 + l, true);
2009 memcpy(a+1, c->signature, l);
2014 static int bus_message_close_struct(sd_bus_message *m, struct bus_container *c, bool add_offset) {
2015 size_t n_variable = 0;
2024 if (!BUS_MESSAGE_IS_GVARIANT(m))
2027 p = strempty(c->signature);
2031 r = signature_element_length(p, &n);
2040 r = bus_gvariant_is_fixed_size(t);
2045 assert(i <= c->n_offsets);
2047 /* We need to add an offset for each item that has a
2048 * variable size and that is not the last one in the
2050 if (r == 0 && p[n] != 0)
2057 assert(i == c->n_offsets);
2059 if (n_variable <= 0) {
2060 a = message_extend_body(m, 1, 0, add_offset);
2067 assert(c->offsets[c->n_offsets-1] == m->header->body_size);
2069 sz = determine_word_size(m->header->body_size - c->begin, n_variable);
2071 a = message_extend_body(m, 1, sz * n_variable, add_offset);
2075 p = strempty(c->signature);
2076 for (i = 0, j = 0; i < c->n_offsets; i++) {
2080 r = signature_element_length(p, &n);
2091 r = bus_gvariant_is_fixed_size(t);
2094 if (r > 0 || p[0] == 0)
2098 k = n_variable - 1 - j;
2100 write_word_le(a + k * sz, sz, c->offsets[i] - c->begin);
2109 _public_ int sd_bus_message_close_container(sd_bus_message *m) {
2110 struct bus_container *c;
2113 assert_return(m, -EINVAL);
2114 assert_return(!m->sealed, -EPERM);
2115 assert_return(m->n_containers > 0, -EINVAL);
2116 assert_return(!m->poisoned, -ESTALE);
2118 c = message_get_container(m);
2120 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2121 if (c->signature && c->signature[c->index] != 0)
2126 if (c->enclosing == SD_BUS_TYPE_ARRAY)
2127 r = bus_message_close_array(m, c);
2128 else if (c->enclosing == SD_BUS_TYPE_VARIANT)
2129 r = bus_message_close_variant(m, c);
2130 else if (c->enclosing == SD_BUS_TYPE_STRUCT || c->enclosing == SD_BUS_TYPE_DICT_ENTRY)
2131 r = bus_message_close_struct(m, c, true);
2133 assert_not_reached("Unknown container type");
2147 static int type_stack_push(TypeStack *stack, unsigned max, unsigned *i, const char *types, unsigned n_struct, unsigned n_array) {
2154 stack[*i].types = types;
2155 stack[*i].n_struct = n_struct;
2156 stack[*i].n_array = n_array;
2162 static int type_stack_pop(TypeStack *stack, unsigned max, unsigned *i, const char **types, unsigned *n_struct, unsigned *n_array) {
2173 *types = stack[*i].types;
2174 *n_struct = stack[*i].n_struct;
2175 *n_array = stack[*i].n_array;
2180 int bus_message_append_ap(
2185 unsigned n_array, n_struct;
2186 TypeStack stack[BUS_CONTAINER_DEPTH];
2187 unsigned stack_ptr = 0;
2195 n_array = (unsigned) -1;
2196 n_struct = strlen(types);
2201 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
2202 r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
2208 r = sd_bus_message_close_container(m);
2216 if (n_array != (unsigned) -1)
2225 case SD_BUS_TYPE_BYTE: {
2228 x = (uint8_t) va_arg(ap, int);
2229 r = sd_bus_message_append_basic(m, *t, &x);
2233 case SD_BUS_TYPE_BOOLEAN:
2234 case SD_BUS_TYPE_INT32:
2235 case SD_BUS_TYPE_UINT32:
2236 case SD_BUS_TYPE_UNIX_FD: {
2239 /* We assume a boolean is the same as int32_t */
2240 assert_cc(sizeof(int32_t) == sizeof(int));
2242 x = va_arg(ap, uint32_t);
2243 r = sd_bus_message_append_basic(m, *t, &x);
2247 case SD_BUS_TYPE_INT16:
2248 case SD_BUS_TYPE_UINT16: {
2251 x = (uint16_t) va_arg(ap, int);
2252 r = sd_bus_message_append_basic(m, *t, &x);
2256 case SD_BUS_TYPE_INT64:
2257 case SD_BUS_TYPE_UINT64:
2258 case SD_BUS_TYPE_DOUBLE: {
2261 x = va_arg(ap, uint64_t);
2262 r = sd_bus_message_append_basic(m, *t, &x);
2266 case SD_BUS_TYPE_STRING:
2267 case SD_BUS_TYPE_OBJECT_PATH:
2268 case SD_BUS_TYPE_SIGNATURE: {
2271 x = va_arg(ap, const char*);
2272 r = sd_bus_message_append_basic(m, *t, x);
2276 case SD_BUS_TYPE_ARRAY: {
2279 r = signature_element_length(t + 1, &k);
2285 memcpy(s, t + 1, k);
2288 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, s);
2293 if (n_array == (unsigned) -1) {
2298 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2304 n_array = va_arg(ap, unsigned);
2309 case SD_BUS_TYPE_VARIANT: {
2312 s = va_arg(ap, const char*);
2316 r = sd_bus_message_open_container(m, SD_BUS_TYPE_VARIANT, s);
2320 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2325 n_struct = strlen(s);
2326 n_array = (unsigned) -1;
2331 case SD_BUS_TYPE_STRUCT_BEGIN:
2332 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
2335 r = signature_element_length(t, &k);
2342 memcpy(s, t + 1, k - 2);
2345 r = sd_bus_message_open_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
2350 if (n_array == (unsigned) -1) {
2355 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2361 n_array = (unsigned) -1;
2377 _public_ int sd_bus_message_append(sd_bus_message *m, const char *types, ...) {
2381 assert_return(m, -EINVAL);
2382 assert_return(types, -EINVAL);
2383 assert_return(!m->sealed, -EPERM);
2384 assert_return(!m->poisoned, -ESTALE);
2386 va_start(ap, types);
2387 r = bus_message_append_ap(m, types, ap);
2393 _public_ int sd_bus_message_append_array_space(
2403 assert_return(m, -EINVAL);
2404 assert_return(!m->sealed, -EPERM);
2405 assert_return(bus_type_is_trivial(type) && type != SD_BUS_TYPE_BOOLEAN, -EINVAL);
2406 assert_return(ptr || size == 0, -EINVAL);
2407 assert_return(!m->poisoned, -ESTALE);
2409 /* alignment and size of the trivial types (except bool) is
2410 * identical for gvariant and dbus1 marshalling */
2411 align = bus_type_get_alignment(type);
2412 sz = bus_type_get_size(type);
2414 assert_se(align > 0);
2420 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
2424 a = message_extend_body(m, align, size, false);
2428 r = sd_bus_message_close_container(m);
2436 _public_ int sd_bus_message_append_array(sd_bus_message *m,
2443 assert_return(m, -EINVAL);
2444 assert_return(!m->sealed, -EPERM);
2445 assert_return(bus_type_is_trivial(type), -EINVAL);
2446 assert_return(ptr || size == 0, -EINVAL);
2447 assert_return(!m->poisoned, -ESTALE);
2449 r = sd_bus_message_append_array_space(m, type, size, &p);
2454 memcpy(p, ptr, size);
2459 _public_ int sd_bus_message_append_array_iovec(
2462 const struct iovec *iov,
2470 assert_return(m, -EINVAL);
2471 assert_return(!m->sealed, -EPERM);
2472 assert_return(bus_type_is_trivial(type), -EINVAL);
2473 assert_return(iov || n == 0, -EINVAL);
2474 assert_return(!m->poisoned, -ESTALE);
2476 size = IOVEC_TOTAL_SIZE(iov, n);
2478 r = sd_bus_message_append_array_space(m, type, size, &p);
2482 for (i = 0; i < n; i++) {
2484 if (iov[i].iov_base)
2485 memcpy(p, iov[i].iov_base, iov[i].iov_len);
2487 memset(p, 0, iov[i].iov_len);
2489 p = (uint8_t*) p + iov[i].iov_len;
2495 _public_ int sd_bus_message_append_array_memfd(sd_bus_message *m,
2498 _cleanup_close_ int copy_fd = -1;
2499 struct bus_body_part *part;
2511 if (!bus_type_is_trivial(type))
2516 r = sd_memfd_set_sealed(memfd, true);
2520 copy_fd = sd_memfd_dup_fd(memfd);
2524 r = sd_memfd_get_size(memfd, &size);
2528 align = bus_type_get_alignment(type);
2529 sz = bus_type_get_size(type);
2531 assert_se(align > 0);
2537 if (size > (uint64_t) (uint32_t) -1)
2540 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
2544 a = message_extend_body(m, align, 0, false);
2548 part = message_append_part(m);
2552 part->memfd = copy_fd;
2553 part->sealed = true;
2557 m->header->body_size += size;
2558 message_extend_containers(m, size);
2560 return sd_bus_message_close_container(m);
2563 _public_ int sd_bus_message_append_string_memfd(sd_bus_message *m, sd_memfd *memfd) {
2564 _cleanup_close_ int copy_fd = -1;
2565 struct bus_body_part *part;
2566 struct bus_container *c;
2571 assert_return(m, -EINVAL);
2572 assert_return(memfd, -EINVAL);
2573 assert_return(!m->sealed, -EPERM);
2574 assert_return(!m->poisoned, -ESTALE);
2576 r = sd_memfd_set_sealed(memfd, true);
2580 copy_fd = sd_memfd_dup_fd(memfd);
2584 r = sd_memfd_get_size(memfd, &size);
2588 /* We require this to be NUL terminated */
2592 if (size > (uint64_t) (uint32_t) -1)
2595 c = message_get_container(m);
2596 if (c->signature && c->signature[c->index]) {
2597 /* Container signature is already set */
2599 if (c->signature[c->index] != SD_BUS_TYPE_STRING)
2604 /* Maybe we can append to the signature? But only if this is the top-level container*/
2605 if (c->enclosing != 0)
2608 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRING), NULL);
2615 if (!BUS_MESSAGE_IS_GVARIANT(m)) {
2616 a = message_extend_body(m, 4, 4, false);
2620 *(uint32_t*) a = size - 1;
2623 part = message_append_part(m);
2627 part->memfd = copy_fd;
2628 part->sealed = true;
2632 m->header->body_size += size;
2633 message_extend_containers(m, size);
2635 if (BUS_MESSAGE_IS_GVARIANT(m)) {
2636 r = message_add_offset(m, m->header->body_size);
2643 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2649 _public_ int sd_bus_message_append_strv(sd_bus_message *m, char **l) {
2653 assert_return(m, -EINVAL);
2654 assert_return(!m->sealed, -EPERM);
2655 assert_return(!m->poisoned, -ESTALE);
2657 r = sd_bus_message_open_container(m, 'a', "s");
2661 STRV_FOREACH(i, l) {
2662 r = sd_bus_message_append_basic(m, 's', *i);
2667 return sd_bus_message_close_container(m);
2670 static int bus_message_close_header(sd_bus_message *m) {
2676 if (!BUS_MESSAGE_IS_GVARIANT(m))
2679 if (m->n_header_offsets < 1)
2682 assert(m->header->fields_size == m->header_offsets[m->n_header_offsets-1]);
2684 sz = determine_word_size(m->header->fields_size, m->n_header_offsets);
2686 a = message_extend_fields(m, 1, sz * m->n_header_offsets, false);
2690 for (i = 0; i < m->n_header_offsets; i++)
2691 write_word_le(a + sz*i, sz, m->header_offsets[i]);
2696 int bus_message_seal(sd_bus_message *m, uint64_t serial, usec_t timeout) {
2697 struct bus_body_part *part;
2707 if (m->n_containers > 0)
2713 /* In vtables the return signature of method calls is listed,
2714 * let's check if they match if this is a response */
2715 if (m->header->type == SD_BUS_MESSAGE_METHOD_RETURN &&
2716 m->enforced_reply_signature &&
2717 !streq(strempty(m->root_container.signature), m->enforced_reply_signature))
2720 /* If gvariant marshalling is used we need to close the body structure */
2721 r = bus_message_close_struct(m, &m->root_container, false);
2725 /* If there's a non-trivial signature set, then add it in here */
2726 if (!isempty(m->root_container.signature)) {
2727 r = message_append_field_signature(m, BUS_MESSAGE_HEADER_SIGNATURE, m->root_container.signature, NULL);
2733 r = message_append_field_uint32(m, BUS_MESSAGE_HEADER_UNIX_FDS, m->n_fds);
2738 r = bus_message_close_header(m);
2742 m->header->serial = serial;
2743 m->timeout = m->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED ? 0 : timeout;
2745 /* Add padding at the end of the fields part, since we know
2746 * the body needs to start at an 8 byte alignment. We made
2747 * sure we allocated enough space for this, so all we need to
2748 * do here is to zero it out. */
2749 l = BUS_MESSAGE_FIELDS_SIZE(m);
2752 memset((uint8_t*) BUS_MESSAGE_FIELDS(m) + l, 0, a);
2754 /* If this is something we can send as memfd, then let's seal
2755 the memfd now. Note that we can send memfds as payload only
2756 for directed messages, and not for broadcasts. */
2757 if (m->destination && m->bus && m->bus->use_memfd) {
2758 MESSAGE_FOREACH_PART(part, i, m)
2759 if (part->memfd >= 0 && !part->sealed && (part->size > MEMFD_MIN_SIZE || m->bus->use_memfd < 0)) {
2760 bus_body_part_unmap(part);
2762 if (ioctl(part->memfd, KDBUS_CMD_MEMFD_SEAL_SET, 1) >= 0)
2763 part->sealed = true;
2767 m->root_container.end = BUS_MESSAGE_BODY_SIZE(m);
2768 m->root_container.index = 0;
2769 m->root_container.offset_index = 0;
2770 m->root_container.item_size = m->root_container.n_offsets > 0 ? m->root_container.offsets[0] : 0;
2777 int bus_body_part_map(struct bus_body_part *part) {
2786 if (part->size <= 0)
2789 /* For smaller zero parts (as used for padding) we don't need to map anything... */
2790 if (part->memfd < 0 && part->is_zero && part->size < 8) {
2791 static const uint8_t zeroes[7] = { };
2792 part->data = (void*) zeroes;
2796 psz = PAGE_ALIGN(part->size);
2798 if (part->memfd >= 0)
2799 p = mmap(NULL, psz, PROT_READ, MAP_SHARED, part->memfd, 0);
2800 else if (part->is_zero)
2801 p = mmap(NULL, psz, PROT_READ, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
2805 if (p == MAP_FAILED)
2810 part->munmap_this = true;
2815 void bus_body_part_unmap(struct bus_body_part *part) {
2819 if (part->memfd < 0)
2825 if (!part->munmap_this)
2828 assert_se(munmap(part->data, part->mapped) == 0);
2832 part->munmap_this = false;
2837 static int buffer_peek(const void *p, uint32_t sz, size_t *rindex, size_t align, size_t nbytes, void **r) {
2838 size_t k, start, end;
2843 start = ALIGN_TO((size_t) *rindex, align);
2844 end = start + nbytes;
2849 /* Verify that padding is 0 */
2850 for (k = *rindex; k < start; k++)
2851 if (((const uint8_t*) p)[k] != 0)
2855 *r = (uint8_t*) p + start;
2862 static bool message_end_of_signature(sd_bus_message *m) {
2863 struct bus_container *c;
2867 c = message_get_container(m);
2868 return !c->signature || c->signature[c->index] == 0;
2871 static bool message_end_of_array(sd_bus_message *m, size_t index) {
2872 struct bus_container *c;
2876 c = message_get_container(m);
2877 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2880 if (BUS_MESSAGE_IS_GVARIANT(m))
2881 return index >= c->end;
2883 assert(c->array_size);
2884 return index >= c->begin + BUS_MESSAGE_BSWAP32(m, *c->array_size);
2888 _public_ int sd_bus_message_at_end(sd_bus_message *m, int complete) {
2889 assert_return(m, -EINVAL);
2890 assert_return(m->sealed, -EPERM);
2892 if (complete && m->n_containers > 0)
2895 if (message_end_of_signature(m))
2898 if (message_end_of_array(m, m->rindex))
2904 static struct bus_body_part* find_part(sd_bus_message *m, size_t index, size_t sz, void **p) {
2905 struct bus_body_part *part;
2911 if (m->cached_rindex_part && index >= m->cached_rindex_part_begin) {
2912 part = m->cached_rindex_part;
2913 begin = m->cached_rindex_part_begin;
2923 if (index + sz <= begin + part->size) {
2925 r = bus_body_part_map(part);
2930 *p = (uint8_t*) part->data + index - begin;
2932 m->cached_rindex_part = part;
2933 m->cached_rindex_part_begin = begin;
2938 begin += part->size;
2945 static int container_next_item(sd_bus_message *m, struct bus_container *c, size_t *rindex) {
2952 if (!BUS_MESSAGE_IS_GVARIANT(m))
2955 if (c->enclosing == SD_BUS_TYPE_ARRAY) {
2958 sz = bus_gvariant_get_size(c->signature);
2962 if (c->offset_index+1 >= c->n_offsets)
2965 /* Variable-size array */
2967 alignment = bus_gvariant_get_alignment(c->signature);
2968 assert(alignment > 0);
2970 *rindex = ALIGN_TO(c->offsets[c->offset_index], alignment);
2971 c->item_size = c->offsets[c->offset_index+1] - *rindex;
2974 if (c->offset_index+1 >= (c->end-c->begin)/sz)
2977 /* Fixed-size array */
2978 *rindex = c->begin + (c->offset_index+1) * sz;
2984 } else if (c->enclosing == 0 ||
2985 c->enclosing == SD_BUS_TYPE_STRUCT ||
2986 c->enclosing == SD_BUS_TYPE_DICT_ENTRY) {
2991 if (c->offset_index+1 >= c->n_offsets)
2994 r = signature_element_length(c->signature + c->index, &n);
2998 r = signature_element_length(c->signature + c->index + n, &j);
3003 memcpy(t, c->signature + c->index + n, j);
3006 alignment = bus_gvariant_get_alignment(t);
3009 assert(alignment > 0);
3011 *rindex = ALIGN_TO(c->offsets[c->offset_index], alignment);
3012 c->item_size = c->offsets[c->offset_index+1] - *rindex;
3016 } else if (c->enclosing == SD_BUS_TYPE_VARIANT)
3019 assert_not_reached("Unknown container type");
3024 /* Reached the end */
3031 static int message_peek_body(
3038 size_t k, start, end, padding;
3039 struct bus_body_part *part;
3046 start = ALIGN_TO((size_t) *rindex, align);
3047 padding = start - *rindex;
3048 end = start + nbytes;
3050 if (end > BUS_MESSAGE_BODY_SIZE(m))
3053 part = find_part(m, *rindex, padding, (void**) &q);
3058 /* Verify padding */
3059 for (k = 0; k < padding; k++)
3064 part = find_part(m, start, nbytes, (void**) &q);
3065 if (!part || (nbytes > 0 && !q))
3076 static bool validate_nul(const char *s, size_t l) {
3078 /* Check for NUL chars in the string */
3079 if (memchr(s, 0, l))
3082 /* Check for NUL termination */
3089 static bool validate_string(const char *s, size_t l) {
3091 if (!validate_nul(s, l))
3094 /* Check if valid UTF8 */
3095 if (!utf8_is_valid(s))
3101 static bool validate_signature(const char *s, size_t l) {
3103 if (!validate_nul(s, l))
3106 /* Check if valid signature */
3107 if (!signature_is_valid(s, true))
3113 static bool validate_object_path(const char *s, size_t l) {
3115 if (!validate_nul(s, l))
3118 if (!object_path_is_valid(s))
3124 _public_ int sd_bus_message_read_basic(sd_bus_message *m, char type, void *p) {
3125 struct bus_container *c;
3130 assert_return(m, -EINVAL);
3131 assert_return(m->sealed, -EPERM);
3132 assert_return(bus_type_is_basic(type), -EINVAL);
3134 if (message_end_of_signature(m))
3137 if (message_end_of_array(m, m->rindex))
3140 c = message_get_container(m);
3141 if (c->signature[c->index] != type)
3146 if (BUS_MESSAGE_IS_GVARIANT(m)) {
3148 if (IN_SET(type, SD_BUS_TYPE_STRING, SD_BUS_TYPE_OBJECT_PATH, SD_BUS_TYPE_SIGNATURE)) {
3151 r = message_peek_body(m, &rindex, 1, c->item_size, &q);
3155 if (type == SD_BUS_TYPE_STRING)
3156 ok = validate_string(q, c->item_size-1);
3157 else if (type == SD_BUS_TYPE_OBJECT_PATH)
3158 ok = validate_object_path(q, c->item_size-1);
3160 ok = validate_signature(q, c->item_size-1);
3166 *(const char**) p = q;
3170 sz = bus_gvariant_get_size(CHAR_TO_STR(type));
3172 if ((size_t) sz != c->item_size)
3175 align = bus_gvariant_get_alignment(CHAR_TO_STR(type));
3178 r = message_peek_body(m, &rindex, align, c->item_size, &q);
3184 case SD_BUS_TYPE_BYTE:
3186 *(uint8_t*) p = *(uint8_t*) q;
3189 case SD_BUS_TYPE_BOOLEAN:
3191 *(int*) p = !!*(uint8_t*) q;
3194 case SD_BUS_TYPE_INT16:
3195 case SD_BUS_TYPE_UINT16:
3197 *(uint16_t*) p = BUS_MESSAGE_BSWAP16(m, *(uint16_t*) q);
3200 case SD_BUS_TYPE_INT32:
3201 case SD_BUS_TYPE_UINT32:
3203 *(uint32_t*) p = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
3206 case SD_BUS_TYPE_INT64:
3207 case SD_BUS_TYPE_UINT64:
3208 case SD_BUS_TYPE_DOUBLE:
3210 *(uint64_t*) p = BUS_MESSAGE_BSWAP64(m, *(uint64_t*) q);
3213 case SD_BUS_TYPE_UNIX_FD: {
3216 j = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
3221 *(int*) p = m->fds[j];
3227 assert_not_reached("unexpected type");
3231 r = container_next_item(m, c, &rindex);
3238 if (IN_SET(type, SD_BUS_TYPE_STRING, SD_BUS_TYPE_OBJECT_PATH)) {
3242 r = message_peek_body(m, &rindex, 4, 4, &q);
3246 l = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
3247 r = message_peek_body(m, &rindex, 1, l+1, &q);
3251 if (type == SD_BUS_TYPE_OBJECT_PATH)
3252 ok = validate_object_path(q, l);
3254 ok = validate_string(q, l);
3259 *(const char**) p = q;
3261 } else if (type == SD_BUS_TYPE_SIGNATURE) {
3264 r = message_peek_body(m, &rindex, 1, 1, &q);
3269 r = message_peek_body(m, &rindex, 1, l+1, &q);
3273 if (!validate_signature(q, l))
3277 *(const char**) p = q;
3282 align = bus_type_get_alignment(type);
3285 sz = bus_type_get_size(type);
3288 r = message_peek_body(m, &rindex, align, sz, &q);
3294 case SD_BUS_TYPE_BYTE:
3296 *(uint8_t*) p = *(uint8_t*) q;
3299 case SD_BUS_TYPE_BOOLEAN:
3301 *(int*) p = !!*(uint32_t*) q;
3304 case SD_BUS_TYPE_INT16:
3305 case SD_BUS_TYPE_UINT16:
3307 *(uint16_t*) p = BUS_MESSAGE_BSWAP16(m, *(uint16_t*) q);
3310 case SD_BUS_TYPE_INT32:
3311 case SD_BUS_TYPE_UINT32:
3313 *(uint32_t*) p = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
3316 case SD_BUS_TYPE_INT64:
3317 case SD_BUS_TYPE_UINT64:
3318 case SD_BUS_TYPE_DOUBLE:
3320 *(uint64_t*) p = BUS_MESSAGE_BSWAP64(m, *(uint64_t*) q);
3323 case SD_BUS_TYPE_UNIX_FD: {
3326 j = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
3331 *(int*) p = m->fds[j];
3336 assert_not_reached("Unknown basic type...");
3343 if (c->enclosing != SD_BUS_TYPE_ARRAY)
3349 static int bus_message_enter_array(
3351 struct bus_container *c,
3352 const char *contents,
3353 uint32_t **array_size,
3356 size_t *n_offsets) {
3370 if (!signature_is_single(contents, true))
3373 if (!c->signature || c->signature[c->index] == 0)
3376 if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
3379 if (!startswith(c->signature + c->index + 1, contents))
3384 if (!BUS_MESSAGE_IS_GVARIANT(m)) {
3387 r = message_peek_body(m, &rindex, 4, 4, &q);
3391 if (BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q) > BUS_ARRAY_MAX_SIZE)
3394 alignment = bus_type_get_alignment(contents[0]);
3398 r = message_peek_body(m, &rindex, alignment, 0, NULL);
3402 *array_size = (uint32_t*) q;
3404 } else if (c->item_size <= 0) {
3406 /* gvariant: empty array */
3411 } else if (bus_gvariant_is_fixed_size(contents)) {
3413 /* gvariant: fixed length array */
3414 *item_size = bus_gvariant_get_size(contents);
3419 size_t where, p = 0, framing, sz;
3422 /* gvariant: variable length array */
3423 sz = determine_word_size(c->item_size, 0);
3425 where = rindex + c->item_size - sz;
3426 r = message_peek_body(m, &where, 1, sz, &q);
3430 framing = read_word_le(q, sz);
3431 if (framing > c->item_size - sz)
3433 if ((c->item_size - framing) % sz != 0)
3436 *n_offsets = (c->item_size - framing) / sz;
3438 where = rindex + framing;
3439 r = message_peek_body(m, &where, 1, *n_offsets * sz, &q);
3443 *offsets = new(size_t, *n_offsets);
3447 for (i = 0; i < *n_offsets; i++) {
3450 x = read_word_le((uint8_t*) q + i * sz, sz);
3451 if (x > c->item_size - sz)
3456 (*offsets)[i] = rindex + x;
3460 *item_size = (*offsets)[0] - rindex;
3465 if (c->enclosing != SD_BUS_TYPE_ARRAY)
3466 c->index += 1 + strlen(contents);
3471 static int bus_message_enter_variant(
3473 struct bus_container *c,
3474 const char *contents,
3475 size_t *item_size) {
3487 if (!signature_is_single(contents, false))
3490 if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
3493 if (!c->signature || c->signature[c->index] == 0)
3496 if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
3501 if (BUS_MESSAGE_IS_GVARIANT(m)) {
3504 k = strlen(contents);
3505 if (1+k > c->item_size)
3508 where = rindex + c->item_size - (1+k);
3509 r = message_peek_body(m, &where, 1, 1+k, &q);
3513 if (*(char*) q != 0)
3516 if (memcmp((uint8_t*) q+1, contents, k))
3519 *item_size = c->item_size - (1+k);
3522 r = message_peek_body(m, &rindex, 1, 1, &q);
3527 r = message_peek_body(m, &rindex, 1, l+1, &q);
3531 if (!validate_signature(q, l))
3534 if (!streq(q, contents))
3540 if (c->enclosing != SD_BUS_TYPE_ARRAY)
3546 static int build_struct_offsets(
3548 const char *signature,
3552 size_t *n_offsets) {
3554 unsigned n_variable = 0, n_total = 0, v;
3555 size_t previous = 0, where;
3566 if (isempty(signature)) {
3573 sz = determine_word_size(size, 0);
3577 /* First, loop over signature and count variable elements and
3578 * elements in general. We use this to know how large the
3579 * offset array is at the end of the structure. Note that
3580 * GVariant only stores offsets for all variable size elements
3581 * that are not the last item. */
3587 r = signature_element_length(p, &n);
3596 r = bus_gvariant_is_fixed_size(t);
3601 if (r == 0 && p[n] != 0) /* except the last item */
3608 if (size < n_variable * sz)
3611 where = m->rindex + size - (n_variable * sz);
3612 r = message_peek_body(m, &where, 1, n_variable * sz, &q);
3618 *offsets = new(size_t, n_total);
3624 /* Second, loop again and build an offset table */
3630 r = signature_element_length(p, &n);
3639 k = bus_gvariant_get_size(t);
3647 x = read_word_le((uint8_t*) q + v*sz, sz);
3650 if (m->rindex + x < previous)
3653 /* The last item's end
3654 * is determined from
3657 x = size - (n_variable * sz);
3659 offset = m->rindex + x;
3665 align = bus_gvariant_get_alignment(t);
3668 offset = (*n_offsets == 0 ? m->rindex : ALIGN_TO((*offsets)[*n_offsets-1], align)) + k;
3672 previous = (*offsets)[(*n_offsets)++] = offset;
3677 assert(*n_offsets == n_total);
3679 *item_size = (*offsets)[0] - m->rindex;
3683 static int enter_struct_or_dict_entry(
3685 struct bus_container *c,
3686 const char *contents,
3689 size_t *n_offsets) {
3700 if (!BUS_MESSAGE_IS_GVARIANT(m)) {
3703 r = message_peek_body(m, &m->rindex, 8, 0, NULL);
3707 } else if (c->item_size <= 0) {
3709 /* gvariant empty struct */
3714 /* gvariant with contents */
3715 return build_struct_offsets(m, contents, c->item_size, item_size, offsets, n_offsets);
3720 static int bus_message_enter_struct(
3722 struct bus_container *c,
3723 const char *contents,
3726 size_t *n_offsets) {
3738 if (!signature_is_valid(contents, false))
3741 if (!c->signature || c->signature[c->index] == 0)
3744 l = strlen(contents);
3746 if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
3747 !startswith(c->signature + c->index + 1, contents) ||
3748 c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
3751 r = enter_struct_or_dict_entry(m, c, contents, item_size, offsets, n_offsets);
3755 if (c->enclosing != SD_BUS_TYPE_ARRAY)
3756 c->index += 1 + l + 1;
3761 static int bus_message_enter_dict_entry(
3763 struct bus_container *c,
3764 const char *contents,
3767 size_t *n_offsets) {
3776 if (!signature_is_pair(contents))
3779 if (c->enclosing != SD_BUS_TYPE_ARRAY)
3782 if (!c->signature || c->signature[c->index] == 0)
3785 l = strlen(contents);
3787 if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
3788 !startswith(c->signature + c->index + 1, contents) ||
3789 c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
3792 r = enter_struct_or_dict_entry(m, c, contents, item_size, offsets, n_offsets);
3796 if (c->enclosing != SD_BUS_TYPE_ARRAY)
3797 c->index += 1 + l + 1;
3802 _public_ int sd_bus_message_enter_container(sd_bus_message *m,
3804 const char *contents) {
3805 struct bus_container *c, *w;
3806 uint32_t *array_size = NULL;
3809 size_t *offsets = NULL;
3810 size_t n_offsets = 0, item_size = 0;
3813 assert_return(m, -EINVAL);
3814 assert_return(m->sealed, -EPERM);
3815 assert_return(type != 0 || !contents, -EINVAL);
3817 if (type == 0 || !contents) {
3821 /* Allow entering into anonymous containers */
3822 r = sd_bus_message_peek_type(m, &tt, &cc);
3826 if (type != 0 && type != tt)
3829 if (contents && !streq(contents, cc))
3837 * We enforce a global limit on container depth, that is much
3838 * higher than the 32 structs and 32 arrays the specification
3839 * mandates. This is simpler to implement for us, and we need
3840 * this only to ensure our container array doesn't grow
3841 * without bounds. We are happy to return any data from a
3842 * message as long as the data itself is valid, even if the
3843 * overall message might be not.
3845 * Note that the message signature is validated when
3846 * parsing the headers, and that validation does check the
3849 * Note that the specification defines no limits on the depth
3850 * of stacked variants, but we do.
3852 if (m->n_containers >= BUS_CONTAINER_DEPTH)
3855 if (!GREEDY_REALLOC(m->containers, m->containers_allocated, m->n_containers + 1))
3858 if (message_end_of_signature(m))
3861 if (message_end_of_array(m, m->rindex))
3864 c = message_get_container(m);
3866 signature = strdup(contents);
3870 c->saved_index = c->index;
3873 if (type == SD_BUS_TYPE_ARRAY)
3874 r = bus_message_enter_array(m, c, contents, &array_size, &item_size, &offsets, &n_offsets);
3875 else if (type == SD_BUS_TYPE_VARIANT)
3876 r = bus_message_enter_variant(m, c, contents, &item_size);
3877 else if (type == SD_BUS_TYPE_STRUCT)
3878 r = bus_message_enter_struct(m, c, contents, &item_size, &offsets, &n_offsets);
3879 else if (type == SD_BUS_TYPE_DICT_ENTRY)
3880 r = bus_message_enter_dict_entry(m, c, contents, &item_size, &offsets, &n_offsets);
3890 /* OK, let's fill it in */
3891 w = m->containers + m->n_containers++;
3892 w->enclosing = type;
3893 w->signature = signature;
3897 w->begin = m->rindex;
3898 w->end = m->rindex + c->item_size;
3900 w->array_size = array_size;
3901 w->item_size = item_size;
3902 w->offsets = offsets;
3903 w->n_offsets = n_offsets;
3904 w->offset_index = 0;
3909 _public_ int sd_bus_message_exit_container(sd_bus_message *m) {
3910 struct bus_container *c;
3914 assert_return(m, -EINVAL);
3915 assert_return(m->sealed, -EPERM);
3916 assert_return(m->n_containers > 0, -ENXIO);
3918 c = message_get_container(m);
3920 if (c->enclosing != SD_BUS_TYPE_ARRAY) {
3921 if (c->signature && c->signature[c->index] != 0)
3925 if (BUS_MESSAGE_IS_GVARIANT(m)) {
3926 if (m->rindex < c->end)
3929 } else if (c->enclosing == SD_BUS_TYPE_ARRAY) {
3932 l = BUS_MESSAGE_BSWAP32(m, *c->array_size);
3933 if (c->begin + l != m->rindex)
3941 c = message_get_container(m);
3944 c->index = c->saved_index;
3945 r = container_next_item(m, c, &m->rindex);
3953 static void message_quit_container(sd_bus_message *m) {
3954 struct bus_container *c;
3958 assert(m->n_containers > 0);
3960 c = message_get_container(m);
3963 assert(m->rindex >= c->before);
3964 m->rindex = c->before;
3966 /* Free container */
3971 /* Correct index of new top-level container */
3972 c = message_get_container(m);
3973 c->index = c->saved_index;
3976 _public_ int sd_bus_message_peek_type(sd_bus_message *m, char *type, const char **contents) {
3977 struct bus_container *c;
3980 assert_return(m, -EINVAL);
3981 assert_return(m->sealed, -EPERM);
3983 if (message_end_of_signature(m))
3986 if (message_end_of_array(m, m->rindex))
3989 c = message_get_container(m);
3991 if (bus_type_is_basic(c->signature[c->index])) {
3995 *type = c->signature[c->index];
3999 if (c->signature[c->index] == SD_BUS_TYPE_ARRAY) {
4005 r = signature_element_length(c->signature+c->index+1, &l);
4011 sig = strndup(c->signature + c->index + 1, l);
4015 free(m->peeked_signature);
4016 m->peeked_signature = sig;
4022 *type = SD_BUS_TYPE_ARRAY;
4027 if (c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ||
4028 c->signature[c->index] == SD_BUS_TYPE_DICT_ENTRY_BEGIN) {
4034 r = signature_element_length(c->signature+c->index, &l);
4039 sig = strndup(c->signature + c->index + 1, l - 2);
4043 free(m->peeked_signature);
4044 m->peeked_signature = sig;
4050 *type = c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY;
4055 if (c->signature[c->index] == SD_BUS_TYPE_VARIANT) {
4059 if (BUS_MESSAGE_IS_GVARIANT(m)) {
4062 if (c->item_size < 2)
4065 /* Look for the NUL delimiter that
4066 separates the payload from the
4067 signature. Since the body might be
4068 in a different part that then the
4069 signature we map byte by byte. */
4071 for (k = 2; k <= c->item_size; k++) {
4074 where = m->rindex + c->item_size - k;
4075 r = message_peek_body(m, &where, 1, k, &q);
4079 if (*(char*) q == 0)
4083 if (k > c->item_size)
4086 free(m->peeked_signature);
4087 m->peeked_signature = strndup((char*) q + 1, k - 1);
4088 if (!m->peeked_signature)
4091 if (!signature_is_valid(m->peeked_signature, true))
4094 *contents = m->peeked_signature;
4099 r = message_peek_body(m, &rindex, 1, 1, &q);
4104 r = message_peek_body(m, &rindex, 1, l+1, &q);
4108 if (!validate_signature(q, l))
4116 *type = SD_BUS_TYPE_VARIANT;
4131 _public_ int sd_bus_message_rewind(sd_bus_message *m, int complete) {
4132 struct bus_container *c;
4134 assert_return(m, -EINVAL);
4135 assert_return(m->sealed, -EPERM);
4138 message_reset_containers(m);
4141 c = message_get_container(m);
4143 c = message_get_container(m);
4145 c->offset_index = 0;
4147 m->rindex = c->begin;
4150 c->offset_index = 0;
4151 c->item_size = (c->n_offsets > 0 ? c->offsets[0] : c->end) - c->begin;
4153 return !isempty(c->signature);
4156 static int message_read_ap(
4161 unsigned n_array, n_struct;
4162 TypeStack stack[BUS_CONTAINER_DEPTH];
4163 unsigned stack_ptr = 0;
4164 unsigned n_loop = 0;
4172 /* Ideally, we'd just call ourselves recursively on every
4173 * complex type. However, the state of a va_list that is
4174 * passed to a function is undefined after that function
4175 * returns. This means we need to docode the va_list linearly
4176 * in a single stackframe. We hence implement our own
4177 * home-grown stack in an array. */
4179 n_array = (unsigned) -1; /* lenght of current array entries */
4180 n_struct = strlen(types); /* length of current struct contents signature */
4187 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
4188 r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
4194 r = sd_bus_message_exit_container(m);
4202 if (n_array != (unsigned) -1)
4211 case SD_BUS_TYPE_BYTE:
4212 case SD_BUS_TYPE_BOOLEAN:
4213 case SD_BUS_TYPE_INT16:
4214 case SD_BUS_TYPE_UINT16:
4215 case SD_BUS_TYPE_INT32:
4216 case SD_BUS_TYPE_UINT32:
4217 case SD_BUS_TYPE_INT64:
4218 case SD_BUS_TYPE_UINT64:
4219 case SD_BUS_TYPE_DOUBLE:
4220 case SD_BUS_TYPE_STRING:
4221 case SD_BUS_TYPE_OBJECT_PATH:
4222 case SD_BUS_TYPE_SIGNATURE:
4223 case SD_BUS_TYPE_UNIX_FD: {
4226 p = va_arg(ap, void*);
4227 r = sd_bus_message_read_basic(m, *t, p);
4240 case SD_BUS_TYPE_ARRAY: {
4243 r = signature_element_length(t + 1, &k);
4249 memcpy(s, t + 1, k);
4252 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, s);
4263 if (n_array == (unsigned) -1) {
4268 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
4274 n_array = va_arg(ap, unsigned);
4279 case SD_BUS_TYPE_VARIANT: {
4282 s = va_arg(ap, const char *);
4286 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, s);
4296 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
4301 n_struct = strlen(s);
4302 n_array = (unsigned) -1;
4307 case SD_BUS_TYPE_STRUCT_BEGIN:
4308 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
4311 r = signature_element_length(t, &k);
4317 memcpy(s, t + 1, k - 2);
4320 r = sd_bus_message_enter_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
4330 if (n_array == (unsigned) -1) {
4335 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
4341 n_array = (unsigned) -1;
4354 _public_ int sd_bus_message_read(sd_bus_message *m, const char *types, ...) {
4358 assert_return(m, -EINVAL);
4359 assert_return(m->sealed, -EPERM);
4360 assert_return(types, -EINVAL);
4362 va_start(ap, types);
4363 r = message_read_ap(m, types, ap);
4369 _public_ int sd_bus_message_skip(sd_bus_message *m, const char *types) {
4372 assert_return(m, -EINVAL);
4373 assert_return(m->sealed, -EPERM);
4374 assert_return(types, -EINVAL);
4381 case SD_BUS_TYPE_BYTE:
4382 case SD_BUS_TYPE_BOOLEAN:
4383 case SD_BUS_TYPE_INT16:
4384 case SD_BUS_TYPE_UINT16:
4385 case SD_BUS_TYPE_INT32:
4386 case SD_BUS_TYPE_UINT32:
4387 case SD_BUS_TYPE_INT64:
4388 case SD_BUS_TYPE_UINT64:
4389 case SD_BUS_TYPE_DOUBLE:
4390 case SD_BUS_TYPE_STRING:
4391 case SD_BUS_TYPE_OBJECT_PATH:
4392 case SD_BUS_TYPE_SIGNATURE:
4393 case SD_BUS_TYPE_UNIX_FD:
4395 r = sd_bus_message_read_basic(m, *types, NULL);
4399 r = sd_bus_message_skip(m, types + 1);
4405 case SD_BUS_TYPE_ARRAY: {
4408 r = signature_element_length(types + 1, &k);
4414 memcpy(s, types+1, k);
4417 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, s);
4422 r = sd_bus_message_skip(m, s);
4429 r = sd_bus_message_exit_container(m);
4434 r = sd_bus_message_skip(m, types + 1 + k);
4441 case SD_BUS_TYPE_VARIANT: {
4442 const char *contents;
4445 r = sd_bus_message_peek_type(m, &x, &contents);
4449 if (x != SD_BUS_TYPE_VARIANT)
4452 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, contents);
4456 r = sd_bus_message_skip(m, contents);
4461 r = sd_bus_message_exit_container(m);
4465 r = sd_bus_message_skip(m, types + 1);
4472 case SD_BUS_TYPE_STRUCT_BEGIN:
4473 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
4476 r = signature_element_length(types, &k);
4482 memcpy(s, types+1, k-2);
4485 r = sd_bus_message_enter_container(m, *types == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
4489 r = sd_bus_message_skip(m, s);
4494 r = sd_bus_message_exit_container(m);
4499 r = sd_bus_message_skip(m, types + k);
4511 _public_ int sd_bus_message_read_array(sd_bus_message *m,
4515 struct bus_container *c;
4521 assert_return(m, -EINVAL);
4522 assert_return(m->sealed, -EPERM);
4523 assert_return(bus_type_is_trivial(type), -EINVAL);
4524 assert_return(ptr, -EINVAL);
4525 assert_return(size, -EINVAL);
4526 assert_return(!BUS_MESSAGE_NEED_BSWAP(m), -ENOTSUP);
4528 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
4532 c = message_get_container(m);
4534 if (BUS_MESSAGE_IS_GVARIANT(m)) {
4535 align = bus_gvariant_get_alignment(CHAR_TO_STR(type));
4539 sz = c->end - c->begin;
4541 align = bus_type_get_alignment(type);
4545 sz = BUS_MESSAGE_BSWAP32(m, *c->array_size);
4549 /* Zero length array, let's return some aligned
4550 * pointer that is not NULL */
4551 p = (uint8_t*) NULL + align;
4553 r = message_peek_body(m, &m->rindex, align, sz, &p);
4558 r = sd_bus_message_exit_container(m);
4562 *ptr = (const void*) p;
4568 message_quit_container(m);
4572 static int message_peek_fields(
4583 return buffer_peek(BUS_MESSAGE_FIELDS(m), BUS_MESSAGE_FIELDS_SIZE(m), rindex, align, nbytes, ret);
4586 static int message_peek_field_uint32(
4598 if (BUS_MESSAGE_IS_GVARIANT(m) && item_size != 4)
4601 /* identical for gvariant and dbus1 */
4603 r = message_peek_fields(m, ri, 4, 4, &q);
4608 *ret = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
4613 static int message_peek_field_string(
4615 bool (*validate)(const char *p),
4627 if (BUS_MESSAGE_IS_GVARIANT(m)) {
4632 r = message_peek_fields(m, ri, 1, item_size, &q);
4638 r = message_peek_field_uint32(m, ri, 4, &l);
4642 r = message_peek_fields(m, ri, 1, l+1, &q);
4648 if (!validate_nul(q, l))
4654 if (!validate_string(q, l))
4664 static int message_peek_field_signature(
4677 if (BUS_MESSAGE_IS_GVARIANT(m)) {
4682 r = message_peek_fields(m, ri, 1, item_size, &q);
4688 r = message_peek_fields(m, ri, 1, 1, &q);
4693 r = message_peek_fields(m, ri, 1, l+1, &q);
4698 if (!validate_signature(q, l))
4707 static int message_skip_fields(
4710 uint32_t array_size,
4711 const char **signature) {
4713 size_t original_index;
4719 assert(!BUS_MESSAGE_IS_GVARIANT(m));
4721 original_index = *ri;
4727 if (array_size != (uint32_t) -1 &&
4728 array_size <= *ri - original_index)
4735 if (t == SD_BUS_TYPE_STRING) {
4737 r = message_peek_field_string(m, NULL, ri, 0, NULL);
4743 } else if (t == SD_BUS_TYPE_OBJECT_PATH) {
4745 r = message_peek_field_string(m, object_path_is_valid, ri, 0, NULL);
4751 } else if (t == SD_BUS_TYPE_SIGNATURE) {
4753 r = message_peek_field_signature(m, ri, 0, NULL);
4759 } else if (bus_type_is_basic(t)) {
4762 align = bus_type_get_alignment(t);
4763 k = bus_type_get_size(t);
4764 assert(align > 0 && k > 0);
4766 r = message_peek_fields(m, ri, align, k, NULL);
4772 } else if (t == SD_BUS_TYPE_ARRAY) {
4774 r = signature_element_length(*signature+1, &l);
4784 strncpy(sig, *signature + 1, l-1);
4787 alignment = bus_type_get_alignment(sig[0]);
4791 r = message_peek_field_uint32(m, ri, 0, &nas);
4794 if (nas > BUS_ARRAY_MAX_SIZE)
4797 r = message_peek_fields(m, ri, alignment, 0, NULL);
4801 r = message_skip_fields(m, ri, nas, (const char**) &s);
4806 (*signature) += 1 + l;
4808 } else if (t == SD_BUS_TYPE_VARIANT) {
4811 r = message_peek_field_signature(m, ri, 0, &s);
4815 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
4821 } else if (t == SD_BUS_TYPE_STRUCT ||
4822 t == SD_BUS_TYPE_DICT_ENTRY) {
4824 r = signature_element_length(*signature, &l);
4831 strncpy(sig, *signature + 1, l-1);
4834 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
4845 int bus_message_parse_fields(sd_bus_message *m) {
4848 uint32_t unix_fds = 0;
4849 void *offsets = NULL;
4850 unsigned n_offsets = 0;
4856 if (BUS_MESSAGE_IS_GVARIANT(m)) {
4859 sz = determine_word_size(BUS_MESSAGE_FIELDS_SIZE(m), 0);
4863 ri = BUS_MESSAGE_FIELDS_SIZE(m) - sz;
4864 r = message_peek_fields(m, &ri, 1, sz, &q);
4868 framing = read_word_le(q, sz);
4869 if (framing >= BUS_MESSAGE_FIELDS_SIZE(m) - sz)
4871 if ((BUS_MESSAGE_FIELDS_SIZE(m) - framing) % sz != 0)
4875 r = message_peek_fields(m, &ri, 1, BUS_MESSAGE_FIELDS_SIZE(m) - framing, &offsets);
4879 n_offsets = (BUS_MESSAGE_FIELDS_SIZE(m) - framing) / sz;
4884 while (ri < BUS_MESSAGE_FIELDS_SIZE(m)) {
4885 _cleanup_free_ char *sig = NULL;
4886 const char *signature;
4888 size_t item_size = (size_t) -1;
4890 if (BUS_MESSAGE_IS_GVARIANT(m)) {
4897 ri = ALIGN_TO(read_word_le((uint8_t*) offsets + (i-1)*sz, sz), 8);
4900 r = message_peek_fields(m, &ri, 8, 1, (void**) &header);
4904 if (BUS_MESSAGE_IS_GVARIANT(m)) {
4909 end = read_word_le((uint8_t*) offsets + i*sz, sz);
4914 where = ri = ALIGN_TO(ri, 8);
4915 item_size = end - ri;
4916 r = message_peek_fields(m, &where, 1, item_size, &q);
4920 b = memrchr(q, 0, item_size);
4924 sig = strndup(b+1, item_size - (b+1-(char*) q));
4929 item_size = b - (char*) q;
4931 r = message_peek_field_signature(m, &ri, 0, &signature);
4937 case _BUS_MESSAGE_HEADER_INVALID:
4940 case BUS_MESSAGE_HEADER_PATH:
4945 if (!streq(signature, "o"))
4948 r = message_peek_field_string(m, object_path_is_valid, &ri, item_size, &m->path);
4951 case BUS_MESSAGE_HEADER_INTERFACE:
4956 if (!streq(signature, "s"))
4959 r = message_peek_field_string(m, interface_name_is_valid, &ri, item_size, &m->interface);
4962 case BUS_MESSAGE_HEADER_MEMBER:
4967 if (!streq(signature, "s"))
4970 r = message_peek_field_string(m, member_name_is_valid, &ri, item_size, &m->member);
4973 case BUS_MESSAGE_HEADER_ERROR_NAME:
4978 if (!streq(signature, "s"))
4981 r = message_peek_field_string(m, error_name_is_valid, &ri, item_size, &m->error.name);
4983 m->error._need_free = -1;
4987 case BUS_MESSAGE_HEADER_DESTINATION:
4992 if (!streq(signature, "s"))
4995 r = message_peek_field_string(m, service_name_is_valid, &ri, item_size, &m->destination);
4998 case BUS_MESSAGE_HEADER_SENDER:
5003 if (!streq(signature, "s"))
5006 r = message_peek_field_string(m, service_name_is_valid, &ri, item_size, &m->sender);
5008 if (r >= 0 && m->sender[0] == ':' && m->bus && m->bus->bus_client && !m->bus->is_kernel) {
5009 m->creds.unique_name = (char*) m->sender;
5010 m->creds.mask |= SD_BUS_CREDS_UNIQUE_NAME & m->bus->creds_mask;
5016 case BUS_MESSAGE_HEADER_SIGNATURE: {
5020 if (m->root_container.signature)
5023 if (!streq(signature, "g"))
5026 r = message_peek_field_signature(m, &ri, item_size, &s);
5034 free(m->root_container.signature);
5035 m->root_container.signature = c;
5039 case BUS_MESSAGE_HEADER_REPLY_SERIAL:
5040 if (m->reply_serial != 0)
5043 if (!streq(signature, "u"))
5046 r = message_peek_field_uint32(m, &ri, item_size, &m->reply_serial);
5050 if (m->reply_serial == 0)
5055 case BUS_MESSAGE_HEADER_UNIX_FDS:
5059 if (!streq(signature, "u"))
5062 r = message_peek_field_uint32(m, &ri, item_size, &unix_fds);
5072 if (!BUS_MESSAGE_IS_GVARIANT(m))
5073 r = message_skip_fields(m, &ri, (uint32_t) -1, (const char **) &signature);
5082 if (m->n_fds != unix_fds)
5085 switch (m->header->type) {
5087 case SD_BUS_MESSAGE_SIGNAL:
5088 if (!m->path || !m->interface || !m->member)
5092 case SD_BUS_MESSAGE_METHOD_CALL:
5094 if (!m->path || !m->member)
5099 case SD_BUS_MESSAGE_METHOD_RETURN:
5101 if (m->reply_serial == 0)
5105 case SD_BUS_MESSAGE_METHOD_ERROR:
5107 if (m->reply_serial == 0 || !m->error.name)
5112 m->root_container.end = BUS_MESSAGE_BODY_SIZE(m);
5114 if (BUS_MESSAGE_IS_GVARIANT(m)) {
5115 r = build_struct_offsets(
5117 m->root_container.signature,
5118 BUS_MESSAGE_BODY_SIZE(m),
5119 &m->root_container.item_size,
5120 &m->root_container.offsets,
5121 &m->root_container.n_offsets);
5126 /* Try to read the error message, but if we can't it's a non-issue */
5127 if (m->header->type == SD_BUS_MESSAGE_METHOD_ERROR)
5128 sd_bus_message_read(m, "s", &m->error.message);
5133 _public_ int sd_bus_message_set_destination(sd_bus_message *m, const char *destination) {
5134 assert_return(m, -EINVAL);
5135 assert_return(destination, -EINVAL);
5136 assert_return(!m->sealed, -EPERM);
5137 assert_return(!m->destination, -EEXIST);
5139 return message_append_field_string(m, BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &m->destination);
5142 int bus_message_get_blob(sd_bus_message *m, void **buffer, size_t *sz) {
5146 struct bus_body_part *part;
5152 total = BUS_MESSAGE_SIZE(m);
5158 e = mempcpy(p, m->header, BUS_MESSAGE_BODY_BEGIN(m));
5159 MESSAGE_FOREACH_PART(part, i, m)
5160 e = mempcpy(e, part->data, part->size);
5162 assert(total == (size_t) ((uint8_t*) e - (uint8_t*) p));
5170 int bus_message_read_strv_extend(sd_bus_message *m, char ***l) {
5176 r = sd_bus_message_enter_container(m, 'a', "s");
5183 r = sd_bus_message_read_basic(m, 's', &s);
5189 r = strv_extend(l, s);
5194 r = sd_bus_message_exit_container(m);
5201 _public_ int sd_bus_message_read_strv(sd_bus_message *m, char ***l) {
5205 assert_return(m, -EINVAL);
5206 assert_return(m->sealed, -EPERM);
5207 assert_return(l, -EINVAL);
5209 r = bus_message_read_strv_extend(m, &strv);
5219 const char* bus_message_get_arg(sd_bus_message *m, unsigned i) {
5221 const char *t = NULL;
5226 r = sd_bus_message_rewind(m, true);
5230 for (j = 0; j <= i; j++) {
5233 r = sd_bus_message_peek_type(m, &type, NULL);
5237 if (type != SD_BUS_TYPE_STRING &&
5238 type != SD_BUS_TYPE_OBJECT_PATH &&
5239 type != SD_BUS_TYPE_SIGNATURE)
5242 r = sd_bus_message_read_basic(m, type, &t);
5250 bool bus_header_is_complete(struct bus_header *h, size_t size) {
5256 if (size < sizeof(struct bus_header))
5259 full = sizeof(struct bus_header) +
5260 (h->endian == BUS_NATIVE_ENDIAN ? h->fields_size : bswap_32(h->fields_size));
5262 return size >= full;
5265 int bus_header_message_size(struct bus_header *h, size_t *sum) {
5271 if (h->endian == BUS_NATIVE_ENDIAN) {
5272 fs = h->fields_size;
5274 } else if (h->endian == BUS_REVERSE_ENDIAN) {
5275 fs = bswap_32(h->fields_size);
5276 bs = bswap_32(h->body_size);
5280 *sum = sizeof(struct bus_header) + ALIGN8(fs) + bs;
5284 _public_ int sd_bus_message_get_errno(sd_bus_message *m) {
5285 assert_return(m, -EINVAL);
5287 if (m->header->type != SD_BUS_MESSAGE_METHOD_ERROR)
5290 return sd_bus_error_get_errno(&m->error);
5293 _public_ const char* sd_bus_message_get_signature(sd_bus_message *m, int complete) {
5294 struct bus_container *c;
5296 assert_return(m, NULL);
5298 c = complete ? &m->root_container : message_get_container(m);
5299 return strempty(c->signature);
5302 _public_ int sd_bus_message_copy(sd_bus_message *m, sd_bus_message *source, int all) {
5303 bool done_something = false;
5306 assert_return(m, -EINVAL);
5307 assert_return(source, -EINVAL);
5308 assert_return(!m->sealed, -EPERM);
5309 assert_return(source->sealed, -EPERM);
5312 const char *contents;
5327 r = sd_bus_message_peek_type(source, &type, &contents);
5333 done_something = true;
5335 if (bus_type_is_container(type) > 0) {
5337 r = sd_bus_message_enter_container(source, type, contents);
5341 r = sd_bus_message_open_container(m, type, contents);
5345 r = sd_bus_message_copy(m, source, true);
5349 r = sd_bus_message_close_container(m);
5353 r = sd_bus_message_exit_container(source);
5360 r = sd_bus_message_read_basic(source, type, &basic);
5366 if (type == SD_BUS_TYPE_OBJECT_PATH ||
5367 type == SD_BUS_TYPE_SIGNATURE ||
5368 type == SD_BUS_TYPE_STRING)
5369 r = sd_bus_message_append_basic(m, type, basic.string);
5371 r = sd_bus_message_append_basic(m, type, &basic);
5378 return done_something;
5381 _public_ int sd_bus_message_verify_type(sd_bus_message *m, char type, const char *contents) {
5386 assert_return(m, -EINVAL);
5387 assert_return(m->sealed, -EPERM);
5388 assert_return(!type || bus_type_is_valid(type), -EINVAL);
5389 assert_return(!contents || signature_is_valid(contents, true), -EINVAL);
5390 assert_return(type || contents, -EINVAL);
5391 assert_return(!contents || !type || bus_type_is_container(type), -EINVAL);
5393 r = sd_bus_message_peek_type(m, &t, &c);
5397 if (type != 0 && type != t)
5400 if (contents && !streq_ptr(contents, c))
5406 _public_ sd_bus *sd_bus_message_get_bus(sd_bus_message *m) {
5407 assert_return(m, NULL);
5412 int bus_message_remarshal(sd_bus *bus, sd_bus_message **m) {
5413 _cleanup_bus_message_unref_ sd_bus_message *n = NULL;
5421 switch ((*m)->header->type) {
5423 case SD_BUS_MESSAGE_SIGNAL:
5424 r = sd_bus_message_new_signal(bus, (*m)->path, (*m)->interface, (*m)->member, &n);
5430 case SD_BUS_MESSAGE_METHOD_CALL:
5431 r = sd_bus_message_new_method_call(bus, (*m)->destination, (*m)->path, (*m)->interface, (*m)->member, &n);
5437 case SD_BUS_MESSAGE_METHOD_RETURN:
5438 case SD_BUS_MESSAGE_METHOD_ERROR:
5440 n = message_new(bus, (*m)->header->type);
5444 n->reply_serial = (*m)->reply_serial;
5445 r = message_append_field_uint32(n, BUS_MESSAGE_HEADER_REPLY_SERIAL, n->reply_serial);
5449 if ((*m)->header->type == SD_BUS_MESSAGE_METHOD_ERROR && (*m)->error.name) {
5450 r = message_append_field_string(n, BUS_MESSAGE_HEADER_ERROR_NAME, SD_BUS_TYPE_STRING, (*m)->error.name, &n->error.message);
5454 n->error._need_free = -1;
5463 if ((*m)->destination && !n->destination) {
5464 r = message_append_field_string(n, BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, (*m)->destination, &n->destination);
5469 if ((*m)->sender && !n->sender) {
5470 r = message_append_field_string(n, BUS_MESSAGE_HEADER_SENDER, SD_BUS_TYPE_STRING, (*m)->sender, &n->sender);
5475 n->header->flags |= (*m)->header->flags & (BUS_MESSAGE_NO_REPLY_EXPECTED|BUS_MESSAGE_NO_AUTO_START);
5477 r = sd_bus_message_copy(n, *m, true);
5481 timeout = (*m)->timeout;
5482 if (timeout == 0 && !((*m)->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED))
5483 timeout = BUS_DEFAULT_TIMEOUT;
5485 r = bus_message_seal(n, (*m)->header->serial, timeout);
5489 sd_bus_message_unref(*m);