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, part->allocated);
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->root_container.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, &part->allocated);
1054 if (part->memfd >= 0) {
1056 if (part->allocated == 0 || sz > part->allocated) {
1057 uint64_t new_allocated;
1059 new_allocated = PAGE_ALIGN(sz > 0 ? 2 * sz : 1);
1060 r = ioctl(part->memfd, KDBUS_CMD_MEMFD_SIZE_SET, &new_allocated);
1066 part->allocated = new_allocated;
1069 if (!part->data || sz > part->mapped) {
1072 psz = PAGE_ALIGN(sz > 0 ? sz : 1);
1073 if (part->mapped <= 0)
1074 n = mmap(NULL, psz, PROT_READ|PROT_WRITE, MAP_SHARED, part->memfd, 0);
1076 n = mremap(part->data, part->mapped, psz, MREMAP_MAYMOVE);
1078 if (n == MAP_FAILED) {
1087 part->munmap_this = true;
1089 if (part->allocated == 0 || sz > part->allocated) {
1090 size_t new_allocated;
1092 new_allocated = sz > 0 ? 2 * sz : 64;
1093 n = realloc(part->data, new_allocated);
1100 part->allocated = new_allocated;
1101 part->free_this = true;
1106 *q = part->data ? (uint8_t*) part->data + part->size : NULL;
1112 static int message_add_offset(sd_bus_message *m, size_t offset) {
1113 struct bus_container *c;
1116 assert(BUS_MESSAGE_IS_GVARIANT(m));
1118 /* Add offset to current container, unless this is the first
1119 * item in it, which will have the 0 offset, which we can
1121 c = message_get_container(m);
1123 if (!c->need_offsets)
1126 if (!GREEDY_REALLOC(c->offsets, c->offsets_allocated, c->n_offsets + 1))
1129 c->offsets[c->n_offsets++] = offset;
1133 static void message_extend_containers(sd_bus_message *m, size_t expand) {
1134 struct bus_container *c;
1141 /* Update counters */
1142 for (c = m->containers; c < m->containers + m->n_containers; c++) {
1145 *c->array_size += expand;
1149 static void *message_extend_body(sd_bus_message *m, size_t align, size_t sz, bool add_offset) {
1150 size_t start_body, end_body, padding, added;
1161 start_body = ALIGN_TO((size_t) m->header->body_size, align);
1162 end_body = start_body + sz;
1164 padding = start_body - m->header->body_size;
1165 added = padding + sz;
1167 /* Check for 32bit overflows */
1168 if (end_body > (size_t) ((uint32_t) -1)) {
1174 struct bus_body_part *part = NULL;
1178 m->n_body_parts <= 0 ||
1179 m->body_end->sealed ||
1180 padding != ALIGN_TO(m->body_end->size, align) - m->body_end->size;
1184 part = message_append_part(m);
1188 part_zero(part, padding);
1191 part = message_append_part(m);
1195 r = part_make_space(m, part, sz, &p);
1199 struct bus_container *c;
1201 size_t os, start_part, end_part;
1207 start_part = ALIGN_TO(part->size, align);
1208 end_part = start_part + sz;
1210 r = part_make_space(m, part, end_part, &p);
1215 memset(p, 0, padding);
1216 p = (uint8_t*) p + padding;
1219 /* Readjust pointers */
1220 for (c = m->containers; c < m->containers + m->n_containers; c++)
1221 c->array_size = adjust_pointer(c->array_size, op, os, part->data);
1223 m->error.message = (const char*) adjust_pointer(m->error.message, op, os, part->data);
1226 /* Return something that is not NULL and is aligned */
1227 p = (uint8_t *) NULL + align;
1229 m->header->body_size = end_body;
1230 message_extend_containers(m, added);
1233 r = message_add_offset(m, end_body);
1243 static int message_push_fd(sd_bus_message *m, int fd) {
1254 copy = fcntl(fd, F_DUPFD_CLOEXEC, 3);
1258 f = realloc(m->fds, sizeof(int) * (m->n_fds + 1));
1261 close_nointr_nofail(copy);
1266 m->fds[m->n_fds] = copy;
1272 int message_append_basic(sd_bus_message *m, char type, const void *p, const void **stored) {
1273 _cleanup_close_ int fd = -1;
1274 struct bus_container *c;
1278 assert_return(m, -EINVAL);
1279 assert_return(!m->sealed, -EPERM);
1280 assert_return(bus_type_is_basic(type), -EINVAL);
1281 assert_return(!m->poisoned, -ESTALE);
1283 c = message_get_container(m);
1285 if (c->signature && c->signature[c->index]) {
1286 /* Container signature is already set */
1288 if (c->signature[c->index] != type)
1293 /* Maybe we can append to the signature? But only if this is the top-level container*/
1294 if (c->enclosing != 0)
1297 e = strextend(&c->signature, CHAR_TO_STR(type), NULL);
1304 if (BUS_MESSAGE_IS_GVARIANT(m)) {
1310 case SD_BUS_TYPE_SIGNATURE:
1311 case SD_BUS_TYPE_STRING:
1314 /* Fall through... */
1315 case SD_BUS_TYPE_OBJECT_PATH:
1323 case SD_BUS_TYPE_BOOLEAN:
1325 u8 = p && *(int*) p;
1331 case SD_BUS_TYPE_UNIX_FD:
1336 fd = message_push_fd(m, *(int*) p);
1347 align = bus_gvariant_get_alignment(CHAR_TO_STR(type));
1348 sz = bus_gvariant_get_size(CHAR_TO_STR(type));
1355 a = message_extend_body(m, align, sz, true);
1362 *stored = (const uint8_t*) a;
1369 case SD_BUS_TYPE_STRING:
1370 /* To make things easy we'll serialize a NULL string
1371 * into the empty string */
1374 /* Fall through... */
1375 case SD_BUS_TYPE_OBJECT_PATH:
1381 sz = 4 + strlen(p) + 1;
1384 case SD_BUS_TYPE_SIGNATURE:
1389 sz = 1 + strlen(p) + 1;
1392 case SD_BUS_TYPE_BOOLEAN:
1394 u32 = p && *(int*) p;
1400 case SD_BUS_TYPE_UNIX_FD:
1405 fd = message_push_fd(m, *(int*) p);
1416 align = bus_type_get_alignment(type);
1417 sz = bus_type_get_size(type);
1424 a = message_extend_body(m, align, sz, false);
1428 if (type == SD_BUS_TYPE_STRING || type == SD_BUS_TYPE_OBJECT_PATH) {
1429 *(uint32_t*) a = sz - 5;
1430 memcpy((uint8_t*) a + 4, p, sz - 4);
1433 *stored = (const uint8_t*) a + 4;
1435 } else if (type == SD_BUS_TYPE_SIGNATURE) {
1436 *(uint8_t*) a = sz - 1;
1437 memcpy((uint8_t*) a + 1, p, sz - 1);
1440 *stored = (const uint8_t*) a + 1;
1449 if (type == SD_BUS_TYPE_UNIX_FD)
1452 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1459 _public_ int sd_bus_message_append_basic(sd_bus_message *m, char type, const void *p) {
1460 return message_append_basic(m, type, p, NULL);
1463 _public_ int sd_bus_message_append_string_space(
1468 struct bus_container *c;
1471 assert_return(m, -EINVAL);
1472 assert_return(s, -EINVAL);
1473 assert_return(!m->sealed, -EPERM);
1474 assert_return(!m->poisoned, -ESTALE);
1476 c = message_get_container(m);
1478 if (c->signature && c->signature[c->index]) {
1479 /* Container signature is already set */
1481 if (c->signature[c->index] != SD_BUS_TYPE_STRING)
1486 /* Maybe we can append to the signature? But only if this is the top-level container*/
1487 if (c->enclosing != 0)
1490 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRING), NULL);
1497 if (BUS_MESSAGE_IS_GVARIANT(m)) {
1498 a = message_extend_body(m, 1, size + 1, true);
1504 a = message_extend_body(m, 4, 4 + size + 1, false);
1508 *(uint32_t*) a = size;
1514 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1520 _public_ int sd_bus_message_append_string_iovec(
1522 const struct iovec *iov,
1530 assert_return(m, -EINVAL);
1531 assert_return(!m->sealed, -EPERM);
1532 assert_return(iov || n == 0, -EINVAL);
1533 assert_return(!m->poisoned, -ESTALE);
1535 size = IOVEC_TOTAL_SIZE(iov, n);
1537 r = sd_bus_message_append_string_space(m, size, &p);
1541 for (i = 0; i < n; i++) {
1543 if (iov[i].iov_base)
1544 memcpy(p, iov[i].iov_base, iov[i].iov_len);
1546 memset(p, ' ', iov[i].iov_len);
1548 p += iov[i].iov_len;
1554 static int bus_message_open_array(
1556 struct bus_container *c,
1557 const char *contents,
1558 uint32_t **array_size,
1560 bool *need_offsets) {
1570 assert(need_offsets);
1572 if (!signature_is_single(contents, true))
1575 if (c->signature && c->signature[c->index]) {
1577 /* Verify the existing signature */
1579 if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
1582 if (!startswith(c->signature + c->index + 1, contents))
1585 nindex = c->index + 1 + strlen(contents);
1589 if (c->enclosing != 0)
1592 /* Extend the existing signature */
1594 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_ARRAY), contents, NULL);
1600 nindex = e - c->signature;
1603 if (BUS_MESSAGE_IS_GVARIANT(m)) {
1604 alignment = bus_gvariant_get_alignment(contents);
1608 /* Add alignment padding and add to offset list */
1609 if (!message_extend_body(m, alignment, 0, false))
1612 r = bus_gvariant_is_fixed_size(contents);
1616 *begin = m->header->body_size;
1617 *need_offsets = r == 0;
1621 struct bus_body_part *o;
1623 alignment = bus_type_get_alignment(contents[0]);
1627 a = message_extend_body(m, 4, 4, false);
1632 op = m->body_end->data;
1633 os = m->body_end->size;
1635 /* Add alignment between size and first element */
1636 if (!message_extend_body(m, alignment, 0, false))
1639 /* location of array size might have changed so let's readjust a */
1640 if (o == m->body_end)
1641 a = adjust_pointer(a, op, os, m->body_end->data);
1647 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1653 static int bus_message_open_variant(
1655 struct bus_container *c,
1656 const char *contents) {
1662 if (!signature_is_single(contents, false))
1665 if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
1668 if (c->signature && c->signature[c->index]) {
1670 if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
1676 if (c->enclosing != 0)
1679 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_VARIANT), NULL);
1686 if (BUS_MESSAGE_IS_GVARIANT(m)) {
1687 /* Variants are always aligned to 8 */
1689 if (!message_extend_body(m, 8, 0, false))
1696 l = strlen(contents);
1697 a = message_extend_body(m, 1, 1 + l + 1, false);
1702 memcpy((uint8_t*) a + 1, contents, l + 1);
1705 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1711 static int bus_message_open_struct(
1713 struct bus_container *c,
1714 const char *contents,
1716 bool *need_offsets) {
1725 assert(need_offsets);
1727 if (!signature_is_valid(contents, false))
1730 if (c->signature && c->signature[c->index]) {
1733 l = strlen(contents);
1735 if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
1736 !startswith(c->signature + c->index + 1, contents) ||
1737 c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
1740 nindex = c->index + 1 + l + 1;
1744 if (c->enclosing != 0)
1747 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_BEGIN), contents, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_END), NULL);
1753 nindex = e - c->signature;
1756 if (BUS_MESSAGE_IS_GVARIANT(m)) {
1759 alignment = bus_gvariant_get_alignment(contents);
1763 if (!message_extend_body(m, alignment, 0, false))
1766 r = bus_gvariant_is_fixed_size(contents);
1770 *begin = m->header->body_size;
1771 *need_offsets = r == 0;
1773 /* Align contents to 8 byte boundary */
1774 if (!message_extend_body(m, 8, 0, false))
1778 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1784 static int bus_message_open_dict_entry(
1786 struct bus_container *c,
1787 const char *contents,
1789 bool *need_offsets) {
1797 assert(need_offsets);
1799 if (!signature_is_pair(contents))
1802 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1805 if (c->signature && c->signature[c->index]) {
1808 l = strlen(contents);
1810 if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
1811 !startswith(c->signature + c->index + 1, contents) ||
1812 c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
1817 if (BUS_MESSAGE_IS_GVARIANT(m)) {
1820 alignment = bus_gvariant_get_alignment(contents);
1824 if (!message_extend_body(m, alignment, 0, false))
1827 r = bus_gvariant_is_fixed_size(contents);
1831 *begin = m->header->body_size;
1832 *need_offsets = r == 0;
1834 /* Align contents to 8 byte boundary */
1835 if (!message_extend_body(m, 8, 0, false))
1842 _public_ int sd_bus_message_open_container(
1845 const char *contents) {
1847 struct bus_container *c, *w;
1848 uint32_t *array_size = NULL;
1850 size_t before, begin;
1851 bool need_offsets = false;
1854 assert_return(m, -EINVAL);
1855 assert_return(!m->sealed, -EPERM);
1856 assert_return(contents, -EINVAL);
1857 assert_return(!m->poisoned, -ESTALE);
1859 /* Make sure we have space for one more container */
1860 if (!GREEDY_REALLOC(m->containers, m->containers_allocated, m->n_containers + 1)) {
1865 c = message_get_container(m);
1867 signature = strdup(contents);
1873 /* Save old index in the parent container, in case we have to
1874 * abort this container */
1875 c->saved_index = c->index;
1876 before = m->header->body_size;
1878 if (type == SD_BUS_TYPE_ARRAY)
1879 r = bus_message_open_array(m, c, contents, &array_size, &begin, &need_offsets);
1880 else if (type == SD_BUS_TYPE_VARIANT)
1881 r = bus_message_open_variant(m, c, contents);
1882 else if (type == SD_BUS_TYPE_STRUCT)
1883 r = bus_message_open_struct(m, c, contents, &begin, &need_offsets);
1884 else if (type == SD_BUS_TYPE_DICT_ENTRY)
1885 r = bus_message_open_dict_entry(m, c, contents, &begin, &need_offsets);
1894 /* OK, let's fill it in */
1895 w = m->containers + m->n_containers++;
1896 w->enclosing = type;
1897 w->signature = signature;
1899 w->array_size = array_size;
1902 w->n_offsets = w->offsets_allocated = 0;
1904 w->need_offsets = need_offsets;
1909 static size_t determine_word_size(size_t sz, size_t extra) {
1910 if (sz + extra <= 0xFF)
1912 else if (sz + extra*2 <= 0xFFFF)
1914 else if (sz + extra*4 <= 0xFFFFFFFF)
1920 static size_t read_word_le(void *p, size_t sz) {
1930 return *(uint8_t*) p;
1935 return le16toh(x.u16);
1937 return le32toh(x.u32);
1939 return le64toh(x.u64);
1941 assert_not_reached("unknown word width");
1944 static void write_word_le(void *p, size_t sz, size_t value) {
1952 assert(sz == 8 || (value < (1ULL << (sz*8))));
1955 *(uint8_t*) p = value;
1958 x.u16 = htole16((uint16_t) value);
1960 x.u32 = htole32((uint32_t) value);
1962 x.u64 = htole64((uint64_t) value);
1964 assert_not_reached("unknown word width");
1969 static int bus_message_close_array(sd_bus_message *m, struct bus_container *c) {
1974 if (!BUS_MESSAGE_IS_GVARIANT(m))
1977 if (c->need_offsets) {
1978 size_t payload, sz, i;
1981 /* Variable-width arrays */
1983 payload = c->n_offsets > 0 ? c->offsets[c->n_offsets-1] - c->begin : 0;
1984 sz = determine_word_size(payload, c->n_offsets);
1986 a = message_extend_body(m, 1, sz * c->n_offsets, true);
1990 for (i = 0; i < c->n_offsets; i++)
1991 write_word_le(a + sz*i, sz, c->offsets[i] - c->begin);
1995 /* Fixed-width or empty arrays */
1997 a = message_extend_body(m, 1, 0, true); /* let's add offset to parent */
2005 static int bus_message_close_variant(sd_bus_message *m, struct bus_container *c) {
2012 if (!BUS_MESSAGE_IS_GVARIANT(m))
2015 l = strlen(c->signature);
2017 a = message_extend_body(m, 1, 1 + l, true);
2022 memcpy(a+1, c->signature, l);
2027 static int bus_message_close_struct(sd_bus_message *m, struct bus_container *c, bool add_offset) {
2028 size_t n_variable = 0;
2037 if (!BUS_MESSAGE_IS_GVARIANT(m))
2040 p = strempty(c->signature);
2044 r = signature_element_length(p, &n);
2053 r = bus_gvariant_is_fixed_size(t);
2058 assert(!c->need_offsets || i <= c->n_offsets);
2060 /* We need to add an offset for each item that has a
2061 * variable size and that is not the last one in the
2063 if (r == 0 && p[n] != 0)
2070 assert(!c->need_offsets || i == c->n_offsets);
2071 assert(c->need_offsets || n_variable == 0);
2073 if (n_variable <= 0) {
2074 a = message_extend_body(m, 1, 0, add_offset);
2081 assert(c->offsets[c->n_offsets-1] == m->header->body_size);
2083 sz = determine_word_size(m->header->body_size - c->begin, n_variable);
2085 a = message_extend_body(m, 1, sz * n_variable, add_offset);
2089 p = strempty(c->signature);
2090 for (i = 0, j = 0; i < c->n_offsets; i++) {
2094 r = signature_element_length(p, &n);
2105 r = bus_gvariant_is_fixed_size(t);
2108 if (r > 0 || p[0] == 0)
2112 k = n_variable - 1 - j;
2114 write_word_le(a + k * sz, sz, c->offsets[i] - c->begin);
2123 _public_ int sd_bus_message_close_container(sd_bus_message *m) {
2124 struct bus_container *c;
2127 assert_return(m, -EINVAL);
2128 assert_return(!m->sealed, -EPERM);
2129 assert_return(m->n_containers > 0, -EINVAL);
2130 assert_return(!m->poisoned, -ESTALE);
2132 c = message_get_container(m);
2134 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2135 if (c->signature && c->signature[c->index] != 0)
2140 if (c->enclosing == SD_BUS_TYPE_ARRAY)
2141 r = bus_message_close_array(m, c);
2142 else if (c->enclosing == SD_BUS_TYPE_VARIANT)
2143 r = bus_message_close_variant(m, c);
2144 else if (c->enclosing == SD_BUS_TYPE_STRUCT || c->enclosing == SD_BUS_TYPE_DICT_ENTRY)
2145 r = bus_message_close_struct(m, c, true);
2147 assert_not_reached("Unknown container type");
2161 static int type_stack_push(TypeStack *stack, unsigned max, unsigned *i, const char *types, unsigned n_struct, unsigned n_array) {
2168 stack[*i].types = types;
2169 stack[*i].n_struct = n_struct;
2170 stack[*i].n_array = n_array;
2176 static int type_stack_pop(TypeStack *stack, unsigned max, unsigned *i, const char **types, unsigned *n_struct, unsigned *n_array) {
2187 *types = stack[*i].types;
2188 *n_struct = stack[*i].n_struct;
2189 *n_array = stack[*i].n_array;
2194 int bus_message_append_ap(
2199 unsigned n_array, n_struct;
2200 TypeStack stack[BUS_CONTAINER_DEPTH];
2201 unsigned stack_ptr = 0;
2209 n_array = (unsigned) -1;
2210 n_struct = strlen(types);
2215 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
2216 r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
2222 r = sd_bus_message_close_container(m);
2230 if (n_array != (unsigned) -1)
2239 case SD_BUS_TYPE_BYTE: {
2242 x = (uint8_t) va_arg(ap, int);
2243 r = sd_bus_message_append_basic(m, *t, &x);
2247 case SD_BUS_TYPE_BOOLEAN:
2248 case SD_BUS_TYPE_INT32:
2249 case SD_BUS_TYPE_UINT32:
2250 case SD_BUS_TYPE_UNIX_FD: {
2253 /* We assume a boolean is the same as int32_t */
2254 assert_cc(sizeof(int32_t) == sizeof(int));
2256 x = va_arg(ap, uint32_t);
2257 r = sd_bus_message_append_basic(m, *t, &x);
2261 case SD_BUS_TYPE_INT16:
2262 case SD_BUS_TYPE_UINT16: {
2265 x = (uint16_t) va_arg(ap, int);
2266 r = sd_bus_message_append_basic(m, *t, &x);
2270 case SD_BUS_TYPE_INT64:
2271 case SD_BUS_TYPE_UINT64:
2272 case SD_BUS_TYPE_DOUBLE: {
2275 x = va_arg(ap, uint64_t);
2276 r = sd_bus_message_append_basic(m, *t, &x);
2280 case SD_BUS_TYPE_STRING:
2281 case SD_BUS_TYPE_OBJECT_PATH:
2282 case SD_BUS_TYPE_SIGNATURE: {
2285 x = va_arg(ap, const char*);
2286 r = sd_bus_message_append_basic(m, *t, x);
2290 case SD_BUS_TYPE_ARRAY: {
2293 r = signature_element_length(t + 1, &k);
2299 memcpy(s, t + 1, k);
2302 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, s);
2307 if (n_array == (unsigned) -1) {
2312 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2318 n_array = va_arg(ap, unsigned);
2323 case SD_BUS_TYPE_VARIANT: {
2326 s = va_arg(ap, const char*);
2330 r = sd_bus_message_open_container(m, SD_BUS_TYPE_VARIANT, s);
2334 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2339 n_struct = strlen(s);
2340 n_array = (unsigned) -1;
2345 case SD_BUS_TYPE_STRUCT_BEGIN:
2346 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
2349 r = signature_element_length(t, &k);
2356 memcpy(s, t + 1, k - 2);
2359 r = sd_bus_message_open_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
2364 if (n_array == (unsigned) -1) {
2369 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2375 n_array = (unsigned) -1;
2391 _public_ int sd_bus_message_append(sd_bus_message *m, const char *types, ...) {
2395 assert_return(m, -EINVAL);
2396 assert_return(types, -EINVAL);
2397 assert_return(!m->sealed, -EPERM);
2398 assert_return(!m->poisoned, -ESTALE);
2400 va_start(ap, types);
2401 r = bus_message_append_ap(m, types, ap);
2407 _public_ int sd_bus_message_append_array_space(
2417 assert_return(m, -EINVAL);
2418 assert_return(!m->sealed, -EPERM);
2419 assert_return(bus_type_is_trivial(type) && type != SD_BUS_TYPE_BOOLEAN, -EINVAL);
2420 assert_return(ptr || size == 0, -EINVAL);
2421 assert_return(!m->poisoned, -ESTALE);
2423 /* alignment and size of the trivial types (except bool) is
2424 * identical for gvariant and dbus1 marshalling */
2425 align = bus_type_get_alignment(type);
2426 sz = bus_type_get_size(type);
2428 assert_se(align > 0);
2434 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
2438 a = message_extend_body(m, align, size, false);
2442 r = sd_bus_message_close_container(m);
2450 _public_ int sd_bus_message_append_array(sd_bus_message *m,
2457 assert_return(m, -EINVAL);
2458 assert_return(!m->sealed, -EPERM);
2459 assert_return(bus_type_is_trivial(type), -EINVAL);
2460 assert_return(ptr || size == 0, -EINVAL);
2461 assert_return(!m->poisoned, -ESTALE);
2463 r = sd_bus_message_append_array_space(m, type, size, &p);
2468 memcpy(p, ptr, size);
2473 _public_ int sd_bus_message_append_array_iovec(
2476 const struct iovec *iov,
2484 assert_return(m, -EINVAL);
2485 assert_return(!m->sealed, -EPERM);
2486 assert_return(bus_type_is_trivial(type), -EINVAL);
2487 assert_return(iov || n == 0, -EINVAL);
2488 assert_return(!m->poisoned, -ESTALE);
2490 size = IOVEC_TOTAL_SIZE(iov, n);
2492 r = sd_bus_message_append_array_space(m, type, size, &p);
2496 for (i = 0; i < n; i++) {
2498 if (iov[i].iov_base)
2499 memcpy(p, iov[i].iov_base, iov[i].iov_len);
2501 memset(p, 0, iov[i].iov_len);
2503 p = (uint8_t*) p + iov[i].iov_len;
2509 _public_ int sd_bus_message_append_array_memfd(sd_bus_message *m,
2512 _cleanup_close_ int copy_fd = -1;
2513 struct bus_body_part *part;
2525 if (!bus_type_is_trivial(type))
2530 r = sd_memfd_set_sealed(memfd, true);
2534 copy_fd = sd_memfd_dup_fd(memfd);
2538 r = sd_memfd_get_size(memfd, &size);
2542 align = bus_type_get_alignment(type);
2543 sz = bus_type_get_size(type);
2545 assert_se(align > 0);
2551 if (size > (uint64_t) (uint32_t) -1)
2554 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
2558 a = message_extend_body(m, align, 0, false);
2562 part = message_append_part(m);
2566 part->memfd = copy_fd;
2567 part->sealed = true;
2571 m->header->body_size += size;
2572 message_extend_containers(m, size);
2574 return sd_bus_message_close_container(m);
2577 _public_ int sd_bus_message_append_string_memfd(sd_bus_message *m, sd_memfd *memfd) {
2578 _cleanup_close_ int copy_fd = -1;
2579 struct bus_body_part *part;
2580 struct bus_container *c;
2585 assert_return(m, -EINVAL);
2586 assert_return(memfd, -EINVAL);
2587 assert_return(!m->sealed, -EPERM);
2588 assert_return(!m->poisoned, -ESTALE);
2590 r = sd_memfd_set_sealed(memfd, true);
2594 copy_fd = sd_memfd_dup_fd(memfd);
2598 r = sd_memfd_get_size(memfd, &size);
2602 /* We require this to be NUL terminated */
2606 if (size > (uint64_t) (uint32_t) -1)
2609 c = message_get_container(m);
2610 if (c->signature && c->signature[c->index]) {
2611 /* Container signature is already set */
2613 if (c->signature[c->index] != SD_BUS_TYPE_STRING)
2618 /* Maybe we can append to the signature? But only if this is the top-level container*/
2619 if (c->enclosing != 0)
2622 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRING), NULL);
2629 if (!BUS_MESSAGE_IS_GVARIANT(m)) {
2630 a = message_extend_body(m, 4, 4, false);
2634 *(uint32_t*) a = size - 1;
2637 part = message_append_part(m);
2641 part->memfd = copy_fd;
2642 part->sealed = true;
2646 m->header->body_size += size;
2647 message_extend_containers(m, size);
2649 if (BUS_MESSAGE_IS_GVARIANT(m)) {
2650 r = message_add_offset(m, m->header->body_size);
2657 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2663 _public_ int sd_bus_message_append_strv(sd_bus_message *m, char **l) {
2667 assert_return(m, -EINVAL);
2668 assert_return(!m->sealed, -EPERM);
2669 assert_return(!m->poisoned, -ESTALE);
2671 r = sd_bus_message_open_container(m, 'a', "s");
2675 STRV_FOREACH(i, l) {
2676 r = sd_bus_message_append_basic(m, 's', *i);
2681 return sd_bus_message_close_container(m);
2684 static int bus_message_close_header(sd_bus_message *m) {
2690 if (!BUS_MESSAGE_IS_GVARIANT(m))
2693 if (m->n_header_offsets < 1)
2696 assert(m->header->fields_size == m->header_offsets[m->n_header_offsets-1]);
2698 sz = determine_word_size(m->header->fields_size, m->n_header_offsets);
2700 a = message_extend_fields(m, 1, sz * m->n_header_offsets, false);
2704 for (i = 0; i < m->n_header_offsets; i++)
2705 write_word_le(a + sz*i, sz, m->header_offsets[i]);
2710 int bus_message_seal(sd_bus_message *m, uint64_t serial, usec_t timeout) {
2711 struct bus_body_part *part;
2721 if (m->n_containers > 0)
2727 /* In vtables the return signature of method calls is listed,
2728 * let's check if they match if this is a response */
2729 if (m->header->type == SD_BUS_MESSAGE_METHOD_RETURN &&
2730 m->enforced_reply_signature &&
2731 !streq(strempty(m->root_container.signature), m->enforced_reply_signature))
2734 /* If gvariant marshalling is used we need to close the body structure */
2735 r = bus_message_close_struct(m, &m->root_container, false);
2739 /* If there's a non-trivial signature set, then add it in here */
2740 if (!isempty(m->root_container.signature)) {
2741 r = message_append_field_signature(m, BUS_MESSAGE_HEADER_SIGNATURE, m->root_container.signature, NULL);
2747 r = message_append_field_uint32(m, BUS_MESSAGE_HEADER_UNIX_FDS, m->n_fds);
2752 r = bus_message_close_header(m);
2756 m->header->serial = serial;
2757 m->timeout = m->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED ? 0 : timeout;
2759 /* Add padding at the end of the fields part, since we know
2760 * the body needs to start at an 8 byte alignment. We made
2761 * sure we allocated enough space for this, so all we need to
2762 * do here is to zero it out. */
2763 l = BUS_MESSAGE_FIELDS_SIZE(m);
2766 memset((uint8_t*) BUS_MESSAGE_FIELDS(m) + l, 0, a);
2768 /* If this is something we can send as memfd, then let's seal
2769 the memfd now. Note that we can send memfds as payload only
2770 for directed messages, and not for broadcasts. */
2771 if (m->destination && m->bus && m->bus->use_memfd) {
2772 MESSAGE_FOREACH_PART(part, i, m)
2773 if (part->memfd >= 0 && !part->sealed && (part->size > MEMFD_MIN_SIZE || m->bus->use_memfd < 0)) {
2776 /* Try to seal it if that makes
2777 * sense. First, unmap our own map to
2778 * make sure we don't keep it busy. */
2779 bus_body_part_unmap(part);
2781 /* Then, sync up real memfd size */
2783 if (ioctl(part->memfd, KDBUS_CMD_MEMFD_SIZE_SET, &sz) < 0)
2786 /* Finally, try to seal */
2787 if (ioctl(part->memfd, KDBUS_CMD_MEMFD_SEAL_SET, 1) >= 0)
2788 part->sealed = true;
2792 m->root_container.end = BUS_MESSAGE_BODY_SIZE(m);
2793 m->root_container.index = 0;
2794 m->root_container.offset_index = 0;
2795 m->root_container.item_size = m->root_container.n_offsets > 0 ? m->root_container.offsets[0] : 0;
2802 int bus_body_part_map(struct bus_body_part *part) {
2811 if (part->size <= 0)
2814 /* For smaller zero parts (as used for padding) we don't need to map anything... */
2815 if (part->memfd < 0 && part->is_zero && part->size < 8) {
2816 static const uint8_t zeroes[7] = { };
2817 part->data = (void*) zeroes;
2821 psz = PAGE_ALIGN(part->size);
2823 if (part->memfd >= 0)
2824 p = mmap(NULL, psz, PROT_READ, MAP_SHARED, part->memfd, 0);
2825 else if (part->is_zero)
2826 p = mmap(NULL, psz, PROT_READ, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
2830 if (p == MAP_FAILED)
2835 part->munmap_this = true;
2840 void bus_body_part_unmap(struct bus_body_part *part) {
2844 if (part->memfd < 0)
2850 if (!part->munmap_this)
2853 assert_se(munmap(part->data, part->mapped) == 0);
2857 part->munmap_this = false;
2862 static int buffer_peek(const void *p, uint32_t sz, size_t *rindex, size_t align, size_t nbytes, void **r) {
2863 size_t k, start, end;
2868 start = ALIGN_TO((size_t) *rindex, align);
2869 end = start + nbytes;
2874 /* Verify that padding is 0 */
2875 for (k = *rindex; k < start; k++)
2876 if (((const uint8_t*) p)[k] != 0)
2880 *r = (uint8_t*) p + start;
2887 static bool message_end_of_signature(sd_bus_message *m) {
2888 struct bus_container *c;
2892 c = message_get_container(m);
2893 return !c->signature || c->signature[c->index] == 0;
2896 static bool message_end_of_array(sd_bus_message *m, size_t index) {
2897 struct bus_container *c;
2901 c = message_get_container(m);
2902 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2905 if (BUS_MESSAGE_IS_GVARIANT(m))
2906 return index >= c->end;
2908 assert(c->array_size);
2909 return index >= c->begin + BUS_MESSAGE_BSWAP32(m, *c->array_size);
2913 _public_ int sd_bus_message_at_end(sd_bus_message *m, int complete) {
2914 assert_return(m, -EINVAL);
2915 assert_return(m->sealed, -EPERM);
2917 if (complete && m->n_containers > 0)
2920 if (message_end_of_signature(m))
2923 if (message_end_of_array(m, m->rindex))
2929 static struct bus_body_part* find_part(sd_bus_message *m, size_t index, size_t sz, void **p) {
2930 struct bus_body_part *part;
2936 if (m->cached_rindex_part && index >= m->cached_rindex_part_begin) {
2937 part = m->cached_rindex_part;
2938 begin = m->cached_rindex_part_begin;
2948 if (index + sz <= begin + part->size) {
2950 r = bus_body_part_map(part);
2955 *p = (uint8_t*) part->data + index - begin;
2957 m->cached_rindex_part = part;
2958 m->cached_rindex_part_begin = begin;
2963 begin += part->size;
2970 static int container_next_item(sd_bus_message *m, struct bus_container *c, size_t *rindex) {
2977 if (!BUS_MESSAGE_IS_GVARIANT(m))
2980 if (c->enclosing == SD_BUS_TYPE_ARRAY) {
2983 sz = bus_gvariant_get_size(c->signature);
2987 if (c->offset_index+1 >= c->n_offsets)
2990 /* Variable-size array */
2992 alignment = bus_gvariant_get_alignment(c->signature);
2993 assert(alignment > 0);
2995 *rindex = ALIGN_TO(c->offsets[c->offset_index], alignment);
2996 c->item_size = c->offsets[c->offset_index+1] - *rindex;
2999 if (c->offset_index+1 >= (c->end-c->begin)/sz)
3002 /* Fixed-size array */
3003 *rindex = c->begin + (c->offset_index+1) * sz;
3009 } else if (c->enclosing == 0 ||
3010 c->enclosing == SD_BUS_TYPE_STRUCT ||
3011 c->enclosing == SD_BUS_TYPE_DICT_ENTRY) {
3016 if (c->offset_index+1 >= c->n_offsets)
3019 r = signature_element_length(c->signature + c->index, &n);
3023 r = signature_element_length(c->signature + c->index + n, &j);
3028 memcpy(t, c->signature + c->index + n, j);
3031 alignment = bus_gvariant_get_alignment(t);
3034 assert(alignment > 0);
3036 *rindex = ALIGN_TO(c->offsets[c->offset_index], alignment);
3037 c->item_size = c->offsets[c->offset_index+1] - *rindex;
3041 } else if (c->enclosing == SD_BUS_TYPE_VARIANT)
3044 assert_not_reached("Unknown container type");
3049 /* Reached the end */
3056 static int message_peek_body(
3063 size_t k, start, end, padding;
3064 struct bus_body_part *part;
3071 start = ALIGN_TO((size_t) *rindex, align);
3072 padding = start - *rindex;
3073 end = start + nbytes;
3075 if (end > BUS_MESSAGE_BODY_SIZE(m))
3078 part = find_part(m, *rindex, padding, (void**) &q);
3083 /* Verify padding */
3084 for (k = 0; k < padding; k++)
3089 part = find_part(m, start, nbytes, (void**) &q);
3090 if (!part || (nbytes > 0 && !q))
3101 static bool validate_nul(const char *s, size_t l) {
3103 /* Check for NUL chars in the string */
3104 if (memchr(s, 0, l))
3107 /* Check for NUL termination */
3114 static bool validate_string(const char *s, size_t l) {
3116 if (!validate_nul(s, l))
3119 /* Check if valid UTF8 */
3120 if (!utf8_is_valid(s))
3126 static bool validate_signature(const char *s, size_t l) {
3128 if (!validate_nul(s, l))
3131 /* Check if valid signature */
3132 if (!signature_is_valid(s, true))
3138 static bool validate_object_path(const char *s, size_t l) {
3140 if (!validate_nul(s, l))
3143 if (!object_path_is_valid(s))
3149 _public_ int sd_bus_message_read_basic(sd_bus_message *m, char type, void *p) {
3150 struct bus_container *c;
3155 assert_return(m, -EINVAL);
3156 assert_return(m->sealed, -EPERM);
3157 assert_return(bus_type_is_basic(type), -EINVAL);
3159 if (message_end_of_signature(m))
3162 if (message_end_of_array(m, m->rindex))
3165 c = message_get_container(m);
3166 if (c->signature[c->index] != type)
3171 if (BUS_MESSAGE_IS_GVARIANT(m)) {
3173 if (IN_SET(type, SD_BUS_TYPE_STRING, SD_BUS_TYPE_OBJECT_PATH, SD_BUS_TYPE_SIGNATURE)) {
3176 r = message_peek_body(m, &rindex, 1, c->item_size, &q);
3180 if (type == SD_BUS_TYPE_STRING)
3181 ok = validate_string(q, c->item_size-1);
3182 else if (type == SD_BUS_TYPE_OBJECT_PATH)
3183 ok = validate_object_path(q, c->item_size-1);
3185 ok = validate_signature(q, c->item_size-1);
3191 *(const char**) p = q;
3195 sz = bus_gvariant_get_size(CHAR_TO_STR(type));
3197 if ((size_t) sz != c->item_size)
3200 align = bus_gvariant_get_alignment(CHAR_TO_STR(type));
3203 r = message_peek_body(m, &rindex, align, c->item_size, &q);
3209 case SD_BUS_TYPE_BYTE:
3211 *(uint8_t*) p = *(uint8_t*) q;
3214 case SD_BUS_TYPE_BOOLEAN:
3216 *(int*) p = !!*(uint8_t*) q;
3219 case SD_BUS_TYPE_INT16:
3220 case SD_BUS_TYPE_UINT16:
3222 *(uint16_t*) p = BUS_MESSAGE_BSWAP16(m, *(uint16_t*) q);
3225 case SD_BUS_TYPE_INT32:
3226 case SD_BUS_TYPE_UINT32:
3228 *(uint32_t*) p = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
3231 case SD_BUS_TYPE_INT64:
3232 case SD_BUS_TYPE_UINT64:
3233 case SD_BUS_TYPE_DOUBLE:
3235 *(uint64_t*) p = BUS_MESSAGE_BSWAP64(m, *(uint64_t*) q);
3238 case SD_BUS_TYPE_UNIX_FD: {
3241 j = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
3246 *(int*) p = m->fds[j];
3252 assert_not_reached("unexpected type");
3256 r = container_next_item(m, c, &rindex);
3263 if (IN_SET(type, SD_BUS_TYPE_STRING, SD_BUS_TYPE_OBJECT_PATH)) {
3267 r = message_peek_body(m, &rindex, 4, 4, &q);
3271 l = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
3272 r = message_peek_body(m, &rindex, 1, l+1, &q);
3276 if (type == SD_BUS_TYPE_OBJECT_PATH)
3277 ok = validate_object_path(q, l);
3279 ok = validate_string(q, l);
3284 *(const char**) p = q;
3286 } else if (type == SD_BUS_TYPE_SIGNATURE) {
3289 r = message_peek_body(m, &rindex, 1, 1, &q);
3294 r = message_peek_body(m, &rindex, 1, l+1, &q);
3298 if (!validate_signature(q, l))
3302 *(const char**) p = q;
3307 align = bus_type_get_alignment(type);
3310 sz = bus_type_get_size(type);
3313 r = message_peek_body(m, &rindex, align, sz, &q);
3319 case SD_BUS_TYPE_BYTE:
3321 *(uint8_t*) p = *(uint8_t*) q;
3324 case SD_BUS_TYPE_BOOLEAN:
3326 *(int*) p = !!*(uint32_t*) q;
3329 case SD_BUS_TYPE_INT16:
3330 case SD_BUS_TYPE_UINT16:
3332 *(uint16_t*) p = BUS_MESSAGE_BSWAP16(m, *(uint16_t*) q);
3335 case SD_BUS_TYPE_INT32:
3336 case SD_BUS_TYPE_UINT32:
3338 *(uint32_t*) p = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
3341 case SD_BUS_TYPE_INT64:
3342 case SD_BUS_TYPE_UINT64:
3343 case SD_BUS_TYPE_DOUBLE:
3345 *(uint64_t*) p = BUS_MESSAGE_BSWAP64(m, *(uint64_t*) q);
3348 case SD_BUS_TYPE_UNIX_FD: {
3351 j = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
3356 *(int*) p = m->fds[j];
3361 assert_not_reached("Unknown basic type...");
3368 if (c->enclosing != SD_BUS_TYPE_ARRAY)
3374 static int bus_message_enter_array(
3376 struct bus_container *c,
3377 const char *contents,
3378 uint32_t **array_size,
3381 size_t *n_offsets) {
3395 if (!signature_is_single(contents, true))
3398 if (!c->signature || c->signature[c->index] == 0)
3401 if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
3404 if (!startswith(c->signature + c->index + 1, contents))
3409 if (!BUS_MESSAGE_IS_GVARIANT(m)) {
3412 r = message_peek_body(m, &rindex, 4, 4, &q);
3416 if (BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q) > BUS_ARRAY_MAX_SIZE)
3419 alignment = bus_type_get_alignment(contents[0]);
3423 r = message_peek_body(m, &rindex, alignment, 0, NULL);
3427 *array_size = (uint32_t*) q;
3429 } else if (c->item_size <= 0) {
3431 /* gvariant: empty array */
3436 } else if (bus_gvariant_is_fixed_size(contents)) {
3438 /* gvariant: fixed length array */
3439 *item_size = bus_gvariant_get_size(contents);
3444 size_t where, p = 0, framing, sz;
3447 /* gvariant: variable length array */
3448 sz = determine_word_size(c->item_size, 0);
3450 where = rindex + c->item_size - sz;
3451 r = message_peek_body(m, &where, 1, sz, &q);
3455 framing = read_word_le(q, sz);
3456 if (framing > c->item_size - sz)
3458 if ((c->item_size - framing) % sz != 0)
3461 *n_offsets = (c->item_size - framing) / sz;
3463 where = rindex + framing;
3464 r = message_peek_body(m, &where, 1, *n_offsets * sz, &q);
3468 *offsets = new(size_t, *n_offsets);
3472 for (i = 0; i < *n_offsets; i++) {
3475 x = read_word_le((uint8_t*) q + i * sz, sz);
3476 if (x > c->item_size - sz)
3481 (*offsets)[i] = rindex + x;
3485 *item_size = (*offsets)[0] - rindex;
3490 if (c->enclosing != SD_BUS_TYPE_ARRAY)
3491 c->index += 1 + strlen(contents);
3496 static int bus_message_enter_variant(
3498 struct bus_container *c,
3499 const char *contents,
3500 size_t *item_size) {
3512 if (!signature_is_single(contents, false))
3515 if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
3518 if (!c->signature || c->signature[c->index] == 0)
3521 if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
3526 if (BUS_MESSAGE_IS_GVARIANT(m)) {
3529 k = strlen(contents);
3530 if (1+k > c->item_size)
3533 where = rindex + c->item_size - (1+k);
3534 r = message_peek_body(m, &where, 1, 1+k, &q);
3538 if (*(char*) q != 0)
3541 if (memcmp((uint8_t*) q+1, contents, k))
3544 *item_size = c->item_size - (1+k);
3547 r = message_peek_body(m, &rindex, 1, 1, &q);
3552 r = message_peek_body(m, &rindex, 1, l+1, &q);
3556 if (!validate_signature(q, l))
3559 if (!streq(q, contents))
3565 if (c->enclosing != SD_BUS_TYPE_ARRAY)
3571 static int build_struct_offsets(
3573 const char *signature,
3577 size_t *n_offsets) {
3579 unsigned n_variable = 0, n_total = 0, v;
3580 size_t previous = 0, where;
3591 if (isempty(signature)) {
3598 sz = determine_word_size(size, 0);
3602 /* First, loop over signature and count variable elements and
3603 * elements in general. We use this to know how large the
3604 * offset array is at the end of the structure. Note that
3605 * GVariant only stores offsets for all variable size elements
3606 * that are not the last item. */
3612 r = signature_element_length(p, &n);
3621 r = bus_gvariant_is_fixed_size(t);
3626 if (r == 0 && p[n] != 0) /* except the last item */
3633 if (size < n_variable * sz)
3636 where = m->rindex + size - (n_variable * sz);
3637 r = message_peek_body(m, &where, 1, n_variable * sz, &q);
3643 *offsets = new(size_t, n_total);
3649 /* Second, loop again and build an offset table */
3655 r = signature_element_length(p, &n);
3664 k = bus_gvariant_get_size(t);
3672 x = read_word_le((uint8_t*) q + v*sz, sz);
3675 if (m->rindex + x < previous)
3678 /* The last item's end
3679 * is determined from
3682 x = size - (n_variable * sz);
3684 offset = m->rindex + x;
3690 align = bus_gvariant_get_alignment(t);
3693 offset = (*n_offsets == 0 ? m->rindex : ALIGN_TO((*offsets)[*n_offsets-1], align)) + k;
3697 previous = (*offsets)[(*n_offsets)++] = offset;
3702 assert(*n_offsets == n_total);
3704 *item_size = (*offsets)[0] - m->rindex;
3708 static int enter_struct_or_dict_entry(
3710 struct bus_container *c,
3711 const char *contents,
3714 size_t *n_offsets) {
3725 if (!BUS_MESSAGE_IS_GVARIANT(m)) {
3728 r = message_peek_body(m, &m->rindex, 8, 0, NULL);
3732 } else if (c->item_size <= 0) {
3734 /* gvariant empty struct */
3739 /* gvariant with contents */
3740 return build_struct_offsets(m, contents, c->item_size, item_size, offsets, n_offsets);
3745 static int bus_message_enter_struct(
3747 struct bus_container *c,
3748 const char *contents,
3751 size_t *n_offsets) {
3763 if (!signature_is_valid(contents, false))
3766 if (!c->signature || c->signature[c->index] == 0)
3769 l = strlen(contents);
3771 if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
3772 !startswith(c->signature + c->index + 1, contents) ||
3773 c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
3776 r = enter_struct_or_dict_entry(m, c, contents, item_size, offsets, n_offsets);
3780 if (c->enclosing != SD_BUS_TYPE_ARRAY)
3781 c->index += 1 + l + 1;
3786 static int bus_message_enter_dict_entry(
3788 struct bus_container *c,
3789 const char *contents,
3792 size_t *n_offsets) {
3801 if (!signature_is_pair(contents))
3804 if (c->enclosing != SD_BUS_TYPE_ARRAY)
3807 if (!c->signature || c->signature[c->index] == 0)
3810 l = strlen(contents);
3812 if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
3813 !startswith(c->signature + c->index + 1, contents) ||
3814 c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
3817 r = enter_struct_or_dict_entry(m, c, contents, item_size, offsets, n_offsets);
3821 if (c->enclosing != SD_BUS_TYPE_ARRAY)
3822 c->index += 1 + l + 1;
3827 _public_ int sd_bus_message_enter_container(sd_bus_message *m,
3829 const char *contents) {
3830 struct bus_container *c, *w;
3831 uint32_t *array_size = NULL;
3834 size_t *offsets = NULL;
3835 size_t n_offsets = 0, item_size = 0;
3838 assert_return(m, -EINVAL);
3839 assert_return(m->sealed, -EPERM);
3840 assert_return(type != 0 || !contents, -EINVAL);
3842 if (type == 0 || !contents) {
3846 /* Allow entering into anonymous containers */
3847 r = sd_bus_message_peek_type(m, &tt, &cc);
3851 if (type != 0 && type != tt)
3854 if (contents && !streq(contents, cc))
3862 * We enforce a global limit on container depth, that is much
3863 * higher than the 32 structs and 32 arrays the specification
3864 * mandates. This is simpler to implement for us, and we need
3865 * this only to ensure our container array doesn't grow
3866 * without bounds. We are happy to return any data from a
3867 * message as long as the data itself is valid, even if the
3868 * overall message might be not.
3870 * Note that the message signature is validated when
3871 * parsing the headers, and that validation does check the
3874 * Note that the specification defines no limits on the depth
3875 * of stacked variants, but we do.
3877 if (m->n_containers >= BUS_CONTAINER_DEPTH)
3880 if (!GREEDY_REALLOC(m->containers, m->containers_allocated, m->n_containers + 1))
3883 if (message_end_of_signature(m))
3886 if (message_end_of_array(m, m->rindex))
3889 c = message_get_container(m);
3891 signature = strdup(contents);
3895 c->saved_index = c->index;
3898 if (type == SD_BUS_TYPE_ARRAY)
3899 r = bus_message_enter_array(m, c, contents, &array_size, &item_size, &offsets, &n_offsets);
3900 else if (type == SD_BUS_TYPE_VARIANT)
3901 r = bus_message_enter_variant(m, c, contents, &item_size);
3902 else if (type == SD_BUS_TYPE_STRUCT)
3903 r = bus_message_enter_struct(m, c, contents, &item_size, &offsets, &n_offsets);
3904 else if (type == SD_BUS_TYPE_DICT_ENTRY)
3905 r = bus_message_enter_dict_entry(m, c, contents, &item_size, &offsets, &n_offsets);
3915 /* OK, let's fill it in */
3916 w = m->containers + m->n_containers++;
3917 w->enclosing = type;
3918 w->signature = signature;
3919 w->peeked_signature = NULL;
3923 w->begin = m->rindex;
3924 w->end = m->rindex + c->item_size;
3926 w->array_size = array_size;
3927 w->item_size = item_size;
3928 w->offsets = offsets;
3929 w->n_offsets = n_offsets;
3930 w->offset_index = 0;
3935 _public_ int sd_bus_message_exit_container(sd_bus_message *m) {
3936 struct bus_container *c;
3940 assert_return(m, -EINVAL);
3941 assert_return(m->sealed, -EPERM);
3942 assert_return(m->n_containers > 0, -ENXIO);
3944 c = message_get_container(m);
3946 if (c->enclosing != SD_BUS_TYPE_ARRAY) {
3947 if (c->signature && c->signature[c->index] != 0)
3951 if (BUS_MESSAGE_IS_GVARIANT(m)) {
3952 if (m->rindex < c->end)
3955 } else if (c->enclosing == SD_BUS_TYPE_ARRAY) {
3958 l = BUS_MESSAGE_BSWAP32(m, *c->array_size);
3959 if (c->begin + l != m->rindex)
3964 free(c->peeked_signature);
3968 c = message_get_container(m);
3971 c->index = c->saved_index;
3972 r = container_next_item(m, c, &m->rindex);
3980 static void message_quit_container(sd_bus_message *m) {
3981 struct bus_container *c;
3985 assert(m->n_containers > 0);
3987 c = message_get_container(m);
3990 assert(m->rindex >= c->before);
3991 m->rindex = c->before;
3993 /* Free container */
3998 /* Correct index of new top-level container */
3999 c = message_get_container(m);
4000 c->index = c->saved_index;
4003 _public_ int sd_bus_message_peek_type(sd_bus_message *m, char *type, const char **contents) {
4004 struct bus_container *c;
4007 assert_return(m, -EINVAL);
4008 assert_return(m->sealed, -EPERM);
4010 if (message_end_of_signature(m))
4013 if (message_end_of_array(m, m->rindex))
4016 c = message_get_container(m);
4018 if (bus_type_is_basic(c->signature[c->index])) {
4022 *type = c->signature[c->index];
4026 if (c->signature[c->index] == SD_BUS_TYPE_ARRAY) {
4032 r = signature_element_length(c->signature+c->index+1, &l);
4038 sig = strndup(c->signature + c->index + 1, l);
4042 free(c->peeked_signature);
4043 *contents = c->peeked_signature = sig;
4047 *type = SD_BUS_TYPE_ARRAY;
4052 if (c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ||
4053 c->signature[c->index] == SD_BUS_TYPE_DICT_ENTRY_BEGIN) {
4059 r = signature_element_length(c->signature+c->index, &l);
4064 sig = strndup(c->signature + c->index + 1, l - 2);
4068 free(c->peeked_signature);
4069 *contents = c->peeked_signature = sig;
4073 *type = c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY;
4078 if (c->signature[c->index] == SD_BUS_TYPE_VARIANT) {
4082 if (BUS_MESSAGE_IS_GVARIANT(m)) {
4085 if (c->item_size < 2)
4088 /* Look for the NUL delimiter that
4089 separates the payload from the
4090 signature. Since the body might be
4091 in a different part that then the
4092 signature we map byte by byte. */
4094 for (k = 2; k <= c->item_size; k++) {
4097 where = m->rindex + c->item_size - k;
4098 r = message_peek_body(m, &where, 1, k, &q);
4102 if (*(char*) q == 0)
4106 if (k > c->item_size)
4109 free(c->peeked_signature);
4110 c->peeked_signature = strndup((char*) q + 1, k - 1);
4111 if (!c->peeked_signature)
4114 if (!signature_is_valid(c->peeked_signature, true))
4117 *contents = c->peeked_signature;
4122 r = message_peek_body(m, &rindex, 1, 1, &q);
4127 r = message_peek_body(m, &rindex, 1, l+1, &q);
4131 if (!validate_signature(q, l))
4139 *type = SD_BUS_TYPE_VARIANT;
4154 _public_ int sd_bus_message_rewind(sd_bus_message *m, int complete) {
4155 struct bus_container *c;
4157 assert_return(m, -EINVAL);
4158 assert_return(m->sealed, -EPERM);
4161 message_reset_containers(m);
4164 c = message_get_container(m);
4166 c = message_get_container(m);
4168 c->offset_index = 0;
4170 m->rindex = c->begin;
4173 c->offset_index = 0;
4174 c->item_size = (c->n_offsets > 0 ? c->offsets[0] : c->end) - c->begin;
4176 return !isempty(c->signature);
4179 static int message_read_ap(
4184 unsigned n_array, n_struct;
4185 TypeStack stack[BUS_CONTAINER_DEPTH];
4186 unsigned stack_ptr = 0;
4187 unsigned n_loop = 0;
4195 /* Ideally, we'd just call ourselves recursively on every
4196 * complex type. However, the state of a va_list that is
4197 * passed to a function is undefined after that function
4198 * returns. This means we need to docode the va_list linearly
4199 * in a single stackframe. We hence implement our own
4200 * home-grown stack in an array. */
4202 n_array = (unsigned) -1; /* lenght of current array entries */
4203 n_struct = strlen(types); /* length of current struct contents signature */
4210 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
4211 r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
4217 r = sd_bus_message_exit_container(m);
4225 if (n_array != (unsigned) -1)
4234 case SD_BUS_TYPE_BYTE:
4235 case SD_BUS_TYPE_BOOLEAN:
4236 case SD_BUS_TYPE_INT16:
4237 case SD_BUS_TYPE_UINT16:
4238 case SD_BUS_TYPE_INT32:
4239 case SD_BUS_TYPE_UINT32:
4240 case SD_BUS_TYPE_INT64:
4241 case SD_BUS_TYPE_UINT64:
4242 case SD_BUS_TYPE_DOUBLE:
4243 case SD_BUS_TYPE_STRING:
4244 case SD_BUS_TYPE_OBJECT_PATH:
4245 case SD_BUS_TYPE_SIGNATURE:
4246 case SD_BUS_TYPE_UNIX_FD: {
4249 p = va_arg(ap, void*);
4250 r = sd_bus_message_read_basic(m, *t, p);
4263 case SD_BUS_TYPE_ARRAY: {
4266 r = signature_element_length(t + 1, &k);
4272 memcpy(s, t + 1, k);
4275 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, s);
4286 if (n_array == (unsigned) -1) {
4291 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
4297 n_array = va_arg(ap, unsigned);
4302 case SD_BUS_TYPE_VARIANT: {
4305 s = va_arg(ap, const char *);
4309 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, s);
4319 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
4324 n_struct = strlen(s);
4325 n_array = (unsigned) -1;
4330 case SD_BUS_TYPE_STRUCT_BEGIN:
4331 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
4334 r = signature_element_length(t, &k);
4340 memcpy(s, t + 1, k - 2);
4343 r = sd_bus_message_enter_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
4353 if (n_array == (unsigned) -1) {
4358 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
4364 n_array = (unsigned) -1;
4377 _public_ int sd_bus_message_read(sd_bus_message *m, const char *types, ...) {
4381 assert_return(m, -EINVAL);
4382 assert_return(m->sealed, -EPERM);
4383 assert_return(types, -EINVAL);
4385 va_start(ap, types);
4386 r = message_read_ap(m, types, ap);
4392 _public_ int sd_bus_message_skip(sd_bus_message *m, const char *types) {
4395 assert_return(m, -EINVAL);
4396 assert_return(m->sealed, -EPERM);
4397 assert_return(types, -EINVAL);
4404 case SD_BUS_TYPE_BYTE:
4405 case SD_BUS_TYPE_BOOLEAN:
4406 case SD_BUS_TYPE_INT16:
4407 case SD_BUS_TYPE_UINT16:
4408 case SD_BUS_TYPE_INT32:
4409 case SD_BUS_TYPE_UINT32:
4410 case SD_BUS_TYPE_INT64:
4411 case SD_BUS_TYPE_UINT64:
4412 case SD_BUS_TYPE_DOUBLE:
4413 case SD_BUS_TYPE_STRING:
4414 case SD_BUS_TYPE_OBJECT_PATH:
4415 case SD_BUS_TYPE_SIGNATURE:
4416 case SD_BUS_TYPE_UNIX_FD:
4418 r = sd_bus_message_read_basic(m, *types, NULL);
4422 r = sd_bus_message_skip(m, types + 1);
4428 case SD_BUS_TYPE_ARRAY: {
4431 r = signature_element_length(types + 1, &k);
4437 memcpy(s, types+1, k);
4440 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, s);
4445 r = sd_bus_message_skip(m, s);
4452 r = sd_bus_message_exit_container(m);
4457 r = sd_bus_message_skip(m, types + 1 + k);
4464 case SD_BUS_TYPE_VARIANT: {
4465 const char *contents;
4468 r = sd_bus_message_peek_type(m, &x, &contents);
4472 if (x != SD_BUS_TYPE_VARIANT)
4475 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, contents);
4479 r = sd_bus_message_skip(m, contents);
4484 r = sd_bus_message_exit_container(m);
4488 r = sd_bus_message_skip(m, types + 1);
4495 case SD_BUS_TYPE_STRUCT_BEGIN:
4496 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
4499 r = signature_element_length(types, &k);
4505 memcpy(s, types+1, k-2);
4508 r = sd_bus_message_enter_container(m, *types == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
4512 r = sd_bus_message_skip(m, s);
4517 r = sd_bus_message_exit_container(m);
4522 r = sd_bus_message_skip(m, types + k);
4534 _public_ int sd_bus_message_read_array(sd_bus_message *m,
4538 struct bus_container *c;
4544 assert_return(m, -EINVAL);
4545 assert_return(m->sealed, -EPERM);
4546 assert_return(bus_type_is_trivial(type), -EINVAL);
4547 assert_return(ptr, -EINVAL);
4548 assert_return(size, -EINVAL);
4549 assert_return(!BUS_MESSAGE_NEED_BSWAP(m), -ENOTSUP);
4551 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
4555 c = message_get_container(m);
4557 if (BUS_MESSAGE_IS_GVARIANT(m)) {
4558 align = bus_gvariant_get_alignment(CHAR_TO_STR(type));
4562 sz = c->end - c->begin;
4564 align = bus_type_get_alignment(type);
4568 sz = BUS_MESSAGE_BSWAP32(m, *c->array_size);
4572 /* Zero length array, let's return some aligned
4573 * pointer that is not NULL */
4574 p = (uint8_t*) NULL + align;
4576 r = message_peek_body(m, &m->rindex, align, sz, &p);
4581 r = sd_bus_message_exit_container(m);
4585 *ptr = (const void*) p;
4591 message_quit_container(m);
4595 static int message_peek_fields(
4606 return buffer_peek(BUS_MESSAGE_FIELDS(m), BUS_MESSAGE_FIELDS_SIZE(m), rindex, align, nbytes, ret);
4609 static int message_peek_field_uint32(
4621 if (BUS_MESSAGE_IS_GVARIANT(m) && item_size != 4)
4624 /* identical for gvariant and dbus1 */
4626 r = message_peek_fields(m, ri, 4, 4, &q);
4631 *ret = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
4636 static int message_peek_field_string(
4638 bool (*validate)(const char *p),
4650 if (BUS_MESSAGE_IS_GVARIANT(m)) {
4655 r = message_peek_fields(m, ri, 1, item_size, &q);
4661 r = message_peek_field_uint32(m, ri, 4, &l);
4665 r = message_peek_fields(m, ri, 1, l+1, &q);
4671 if (!validate_nul(q, l))
4677 if (!validate_string(q, l))
4687 static int message_peek_field_signature(
4700 if (BUS_MESSAGE_IS_GVARIANT(m)) {
4705 r = message_peek_fields(m, ri, 1, item_size, &q);
4711 r = message_peek_fields(m, ri, 1, 1, &q);
4716 r = message_peek_fields(m, ri, 1, l+1, &q);
4721 if (!validate_signature(q, l))
4730 static int message_skip_fields(
4733 uint32_t array_size,
4734 const char **signature) {
4736 size_t original_index;
4742 assert(!BUS_MESSAGE_IS_GVARIANT(m));
4744 original_index = *ri;
4750 if (array_size != (uint32_t) -1 &&
4751 array_size <= *ri - original_index)
4758 if (t == SD_BUS_TYPE_STRING) {
4760 r = message_peek_field_string(m, NULL, ri, 0, NULL);
4766 } else if (t == SD_BUS_TYPE_OBJECT_PATH) {
4768 r = message_peek_field_string(m, object_path_is_valid, ri, 0, NULL);
4774 } else if (t == SD_BUS_TYPE_SIGNATURE) {
4776 r = message_peek_field_signature(m, ri, 0, NULL);
4782 } else if (bus_type_is_basic(t)) {
4785 align = bus_type_get_alignment(t);
4786 k = bus_type_get_size(t);
4787 assert(align > 0 && k > 0);
4789 r = message_peek_fields(m, ri, align, k, NULL);
4795 } else if (t == SD_BUS_TYPE_ARRAY) {
4797 r = signature_element_length(*signature+1, &l);
4807 strncpy(sig, *signature + 1, l-1);
4810 alignment = bus_type_get_alignment(sig[0]);
4814 r = message_peek_field_uint32(m, ri, 0, &nas);
4817 if (nas > BUS_ARRAY_MAX_SIZE)
4820 r = message_peek_fields(m, ri, alignment, 0, NULL);
4824 r = message_skip_fields(m, ri, nas, (const char**) &s);
4829 (*signature) += 1 + l;
4831 } else if (t == SD_BUS_TYPE_VARIANT) {
4834 r = message_peek_field_signature(m, ri, 0, &s);
4838 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
4844 } else if (t == SD_BUS_TYPE_STRUCT ||
4845 t == SD_BUS_TYPE_DICT_ENTRY) {
4847 r = signature_element_length(*signature, &l);
4854 strncpy(sig, *signature + 1, l-1);
4857 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
4868 int bus_message_parse_fields(sd_bus_message *m) {
4871 uint32_t unix_fds = 0;
4872 void *offsets = NULL;
4873 unsigned n_offsets = 0;
4879 if (BUS_MESSAGE_IS_GVARIANT(m)) {
4882 sz = determine_word_size(BUS_MESSAGE_FIELDS_SIZE(m), 0);
4886 ri = BUS_MESSAGE_FIELDS_SIZE(m) - sz;
4887 r = message_peek_fields(m, &ri, 1, sz, &q);
4891 framing = read_word_le(q, sz);
4892 if (framing >= BUS_MESSAGE_FIELDS_SIZE(m) - sz)
4894 if ((BUS_MESSAGE_FIELDS_SIZE(m) - framing) % sz != 0)
4898 r = message_peek_fields(m, &ri, 1, BUS_MESSAGE_FIELDS_SIZE(m) - framing, &offsets);
4902 n_offsets = (BUS_MESSAGE_FIELDS_SIZE(m) - framing) / sz;
4907 while (ri < BUS_MESSAGE_FIELDS_SIZE(m)) {
4908 _cleanup_free_ char *sig = NULL;
4909 const char *signature;
4911 size_t item_size = (size_t) -1;
4913 if (BUS_MESSAGE_IS_GVARIANT(m)) {
4920 ri = ALIGN_TO(read_word_le((uint8_t*) offsets + (i-1)*sz, sz), 8);
4923 r = message_peek_fields(m, &ri, 8, 1, (void**) &header);
4927 if (BUS_MESSAGE_IS_GVARIANT(m)) {
4932 end = read_word_le((uint8_t*) offsets + i*sz, sz);
4937 where = ri = ALIGN_TO(ri, 8);
4938 item_size = end - ri;
4939 r = message_peek_fields(m, &where, 1, item_size, &q);
4943 b = memrchr(q, 0, item_size);
4947 sig = strndup(b+1, item_size - (b+1-(char*) q));
4952 item_size = b - (char*) q;
4954 r = message_peek_field_signature(m, &ri, 0, &signature);
4960 case _BUS_MESSAGE_HEADER_INVALID:
4963 case BUS_MESSAGE_HEADER_PATH:
4968 if (!streq(signature, "o"))
4971 r = message_peek_field_string(m, object_path_is_valid, &ri, item_size, &m->path);
4974 case BUS_MESSAGE_HEADER_INTERFACE:
4979 if (!streq(signature, "s"))
4982 r = message_peek_field_string(m, interface_name_is_valid, &ri, item_size, &m->interface);
4985 case BUS_MESSAGE_HEADER_MEMBER:
4990 if (!streq(signature, "s"))
4993 r = message_peek_field_string(m, member_name_is_valid, &ri, item_size, &m->member);
4996 case BUS_MESSAGE_HEADER_ERROR_NAME:
5001 if (!streq(signature, "s"))
5004 r = message_peek_field_string(m, error_name_is_valid, &ri, item_size, &m->error.name);
5006 m->error._need_free = -1;
5010 case BUS_MESSAGE_HEADER_DESTINATION:
5015 if (!streq(signature, "s"))
5018 r = message_peek_field_string(m, service_name_is_valid, &ri, item_size, &m->destination);
5021 case BUS_MESSAGE_HEADER_SENDER:
5026 if (!streq(signature, "s"))
5029 r = message_peek_field_string(m, service_name_is_valid, &ri, item_size, &m->sender);
5031 if (r >= 0 && m->sender[0] == ':' && m->bus && m->bus->bus_client && !m->bus->is_kernel) {
5032 m->creds.unique_name = (char*) m->sender;
5033 m->creds.mask |= SD_BUS_CREDS_UNIQUE_NAME & m->bus->creds_mask;
5039 case BUS_MESSAGE_HEADER_SIGNATURE: {
5043 if (m->root_container.signature)
5046 if (!streq(signature, "g"))
5049 r = message_peek_field_signature(m, &ri, item_size, &s);
5057 free(m->root_container.signature);
5058 m->root_container.signature = c;
5062 case BUS_MESSAGE_HEADER_REPLY_SERIAL:
5063 if (m->reply_serial != 0)
5066 if (!streq(signature, "u"))
5069 r = message_peek_field_uint32(m, &ri, item_size, &m->reply_serial);
5073 if (m->reply_serial == 0)
5078 case BUS_MESSAGE_HEADER_UNIX_FDS:
5082 if (!streq(signature, "u"))
5085 r = message_peek_field_uint32(m, &ri, item_size, &unix_fds);
5095 if (!BUS_MESSAGE_IS_GVARIANT(m))
5096 r = message_skip_fields(m, &ri, (uint32_t) -1, (const char **) &signature);
5105 if (m->n_fds != unix_fds)
5108 switch (m->header->type) {
5110 case SD_BUS_MESSAGE_SIGNAL:
5111 if (!m->path || !m->interface || !m->member)
5115 case SD_BUS_MESSAGE_METHOD_CALL:
5117 if (!m->path || !m->member)
5122 case SD_BUS_MESSAGE_METHOD_RETURN:
5124 if (m->reply_serial == 0)
5128 case SD_BUS_MESSAGE_METHOD_ERROR:
5130 if (m->reply_serial == 0 || !m->error.name)
5135 /* Refuse non-local messages that claim they are local */
5136 if (streq_ptr(m->path, "/org/freedesktop/DBus/Local"))
5138 if (streq_ptr(m->interface, "org.freedesktop.DBus.Local"))
5140 if (streq_ptr(m->sender, "org.freedesktop.DBus.Local"))
5143 m->root_container.end = BUS_MESSAGE_BODY_SIZE(m);
5145 if (BUS_MESSAGE_IS_GVARIANT(m)) {
5146 r = build_struct_offsets(
5148 m->root_container.signature,
5149 BUS_MESSAGE_BODY_SIZE(m),
5150 &m->root_container.item_size,
5151 &m->root_container.offsets,
5152 &m->root_container.n_offsets);
5157 /* Try to read the error message, but if we can't it's a non-issue */
5158 if (m->header->type == SD_BUS_MESSAGE_METHOD_ERROR)
5159 sd_bus_message_read(m, "s", &m->error.message);
5164 _public_ int sd_bus_message_set_destination(sd_bus_message *m, const char *destination) {
5165 assert_return(m, -EINVAL);
5166 assert_return(destination, -EINVAL);
5167 assert_return(!m->sealed, -EPERM);
5168 assert_return(!m->destination, -EEXIST);
5170 return message_append_field_string(m, BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &m->destination);
5173 int bus_message_get_blob(sd_bus_message *m, void **buffer, size_t *sz) {
5177 struct bus_body_part *part;
5183 total = BUS_MESSAGE_SIZE(m);
5189 e = mempcpy(p, m->header, BUS_MESSAGE_BODY_BEGIN(m));
5190 MESSAGE_FOREACH_PART(part, i, m)
5191 e = mempcpy(e, part->data, part->size);
5193 assert(total == (size_t) ((uint8_t*) e - (uint8_t*) p));
5201 int bus_message_read_strv_extend(sd_bus_message *m, char ***l) {
5207 r = sd_bus_message_enter_container(m, 'a', "s");
5214 r = sd_bus_message_read_basic(m, 's', &s);
5220 r = strv_extend(l, s);
5225 r = sd_bus_message_exit_container(m);
5232 _public_ int sd_bus_message_read_strv(sd_bus_message *m, char ***l) {
5236 assert_return(m, -EINVAL);
5237 assert_return(m->sealed, -EPERM);
5238 assert_return(l, -EINVAL);
5240 r = bus_message_read_strv_extend(m, &strv);
5250 const char* bus_message_get_arg(sd_bus_message *m, unsigned i) {
5252 const char *t = NULL;
5257 r = sd_bus_message_rewind(m, true);
5261 for (j = 0; j <= i; j++) {
5264 r = sd_bus_message_peek_type(m, &type, NULL);
5268 if (type != SD_BUS_TYPE_STRING &&
5269 type != SD_BUS_TYPE_OBJECT_PATH &&
5270 type != SD_BUS_TYPE_SIGNATURE)
5273 r = sd_bus_message_read_basic(m, type, &t);
5281 bool bus_header_is_complete(struct bus_header *h, size_t size) {
5287 if (size < sizeof(struct bus_header))
5290 full = sizeof(struct bus_header) +
5291 (h->endian == BUS_NATIVE_ENDIAN ? h->fields_size : bswap_32(h->fields_size));
5293 return size >= full;
5296 int bus_header_message_size(struct bus_header *h, size_t *sum) {
5302 if (h->endian == BUS_NATIVE_ENDIAN) {
5303 fs = h->fields_size;
5305 } else if (h->endian == BUS_REVERSE_ENDIAN) {
5306 fs = bswap_32(h->fields_size);
5307 bs = bswap_32(h->body_size);
5311 *sum = sizeof(struct bus_header) + ALIGN8(fs) + bs;
5315 _public_ int sd_bus_message_get_errno(sd_bus_message *m) {
5316 assert_return(m, -EINVAL);
5318 if (m->header->type != SD_BUS_MESSAGE_METHOD_ERROR)
5321 return sd_bus_error_get_errno(&m->error);
5324 _public_ const char* sd_bus_message_get_signature(sd_bus_message *m, int complete) {
5325 struct bus_container *c;
5327 assert_return(m, NULL);
5329 c = complete ? &m->root_container : message_get_container(m);
5330 return strempty(c->signature);
5333 _public_ int sd_bus_message_copy(sd_bus_message *m, sd_bus_message *source, int all) {
5334 bool done_something = false;
5337 assert_return(m, -EINVAL);
5338 assert_return(source, -EINVAL);
5339 assert_return(!m->sealed, -EPERM);
5340 assert_return(source->sealed, -EPERM);
5343 const char *contents;
5358 r = sd_bus_message_peek_type(source, &type, &contents);
5364 done_something = true;
5366 if (bus_type_is_container(type) > 0) {
5368 r = sd_bus_message_enter_container(source, type, contents);
5372 r = sd_bus_message_open_container(m, type, contents);
5376 r = sd_bus_message_copy(m, source, true);
5380 r = sd_bus_message_close_container(m);
5384 r = sd_bus_message_exit_container(source);
5391 r = sd_bus_message_read_basic(source, type, &basic);
5397 if (type == SD_BUS_TYPE_OBJECT_PATH ||
5398 type == SD_BUS_TYPE_SIGNATURE ||
5399 type == SD_BUS_TYPE_STRING)
5400 r = sd_bus_message_append_basic(m, type, basic.string);
5402 r = sd_bus_message_append_basic(m, type, &basic);
5409 return done_something;
5412 _public_ int sd_bus_message_verify_type(sd_bus_message *m, char type, const char *contents) {
5417 assert_return(m, -EINVAL);
5418 assert_return(m->sealed, -EPERM);
5419 assert_return(!type || bus_type_is_valid(type), -EINVAL);
5420 assert_return(!contents || signature_is_valid(contents, true), -EINVAL);
5421 assert_return(type || contents, -EINVAL);
5422 assert_return(!contents || !type || bus_type_is_container(type), -EINVAL);
5424 r = sd_bus_message_peek_type(m, &t, &c);
5428 if (type != 0 && type != t)
5431 if (contents && !streq_ptr(contents, c))
5437 _public_ sd_bus *sd_bus_message_get_bus(sd_bus_message *m) {
5438 assert_return(m, NULL);
5443 int bus_message_remarshal(sd_bus *bus, sd_bus_message **m) {
5444 _cleanup_bus_message_unref_ sd_bus_message *n = NULL;
5452 switch ((*m)->header->type) {
5454 case SD_BUS_MESSAGE_SIGNAL:
5455 r = sd_bus_message_new_signal(bus, (*m)->path, (*m)->interface, (*m)->member, &n);
5461 case SD_BUS_MESSAGE_METHOD_CALL:
5462 r = sd_bus_message_new_method_call(bus, (*m)->destination, (*m)->path, (*m)->interface, (*m)->member, &n);
5468 case SD_BUS_MESSAGE_METHOD_RETURN:
5469 case SD_BUS_MESSAGE_METHOD_ERROR:
5471 n = message_new(bus, (*m)->header->type);
5475 n->reply_serial = (*m)->reply_serial;
5476 r = message_append_field_uint32(n, BUS_MESSAGE_HEADER_REPLY_SERIAL, n->reply_serial);
5480 if ((*m)->header->type == SD_BUS_MESSAGE_METHOD_ERROR && (*m)->error.name) {
5481 r = message_append_field_string(n, BUS_MESSAGE_HEADER_ERROR_NAME, SD_BUS_TYPE_STRING, (*m)->error.name, &n->error.message);
5485 n->error._need_free = -1;
5494 if ((*m)->destination && !n->destination) {
5495 r = message_append_field_string(n, BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, (*m)->destination, &n->destination);
5500 if ((*m)->sender && !n->sender) {
5501 r = message_append_field_string(n, BUS_MESSAGE_HEADER_SENDER, SD_BUS_TYPE_STRING, (*m)->sender, &n->sender);
5506 n->header->flags |= (*m)->header->flags & (BUS_MESSAGE_NO_REPLY_EXPECTED|BUS_MESSAGE_NO_AUTO_START);
5508 r = sd_bus_message_copy(n, *m, true);
5512 timeout = (*m)->timeout;
5513 if (timeout == 0 && !((*m)->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED))
5514 timeout = BUS_DEFAULT_TIMEOUT;
5516 r = bus_message_seal(n, (*m)->header->serial, timeout);
5520 sd_bus_message_unref(*m);
5527 int bus_message_append_sender(sd_bus_message *m, const char *sender) {
5531 assert_return(!m->sealed, -EPERM);
5532 assert_return(!m->sender, -EPERM);
5534 return message_append_field_string(m, BUS_MESSAGE_HEADER_SENDER, SD_BUS_TYPE_STRING, sender, &m->sender);