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"
31 #include "memfd-util.h"
34 #include "bus-message.h"
35 #include "bus-internal.h"
37 #include "bus-signature.h"
38 #include "bus-gvariant.h"
41 static int message_append_basic(sd_bus_message *m, char type, const void *p, const void **stored);
43 static void *adjust_pointer(const void *p, void *old_base, size_t sz, void *new_base) {
48 if (old_base == new_base)
51 if ((uint8_t*) p < (uint8_t*) old_base)
54 if ((uint8_t*) p >= (uint8_t*) old_base + sz)
57 return (uint8_t*) new_base + ((uint8_t*) p - (uint8_t*) old_base);
60 static void message_free_part(sd_bus_message *m, struct bus_body_part *part) {
64 if (part->memfd >= 0) {
65 /* If we can reuse the memfd, try that. For that it
66 * can't be sealed yet. */
69 bus_kernel_push_memfd(m->bus, part->memfd, part->data, part->mapped, part->allocated);
72 assert_se(munmap(part->data, part->mapped) == 0);
74 safe_close(part->memfd);
77 } else if (part->munmap_this)
78 munmap(part->data, part->mapped);
79 else if (part->free_this)
86 static void message_reset_parts(sd_bus_message *m) {
87 struct bus_body_part *part;
92 while (m->n_body_parts > 0) {
93 struct bus_body_part *next = part->next;
94 message_free_part(m, part);
101 m->cached_rindex_part = NULL;
102 m->cached_rindex_part_begin = 0;
105 static void message_reset_containers(sd_bus_message *m) {
110 for (i = 0; i < m->n_containers; i++) {
111 free(m->containers[i].signature);
112 free(m->containers[i].offsets);
116 m->containers = NULL;
118 m->n_containers = m->containers_allocated = 0;
119 m->root_container.index = 0;
122 static void message_free(sd_bus_message *m) {
128 message_reset_parts(m);
130 if (m->release_kdbus) {
131 struct kdbus_cmd_free cmd_free;
134 cmd_free.offset = (uint8_t *)m->kdbus - (uint8_t *)m->bus->kdbus_buffer;
135 (void) ioctl(m->bus->input_fd, KDBUS_CMD_FREE, &cmd_free);
141 sd_bus_unref(m->bus);
144 close_many(m->fds, m->n_fds);
148 if (m->iovec != m->iovec_fixed)
151 if (m->destination_ptr) {
152 free(m->destination_ptr);
153 m->destination_ptr = NULL;
156 message_reset_containers(m);
157 free(m->root_container.signature);
158 free(m->root_container.offsets);
160 free(m->root_container.peeked_signature);
162 bus_creds_done(&m->creds);
166 static void *message_extend_fields(sd_bus_message *m, size_t align, size_t sz, bool add_offset) {
168 size_t old_size, new_size, start;
175 old_size = sizeof(struct bus_header) + m->header->fields_size;
176 start = ALIGN_TO(old_size, align);
177 new_size = start + sz;
179 if (old_size == new_size)
180 return (uint8_t*) m->header + old_size;
182 if (new_size > (size_t) ((uint32_t) -1))
185 if (m->free_header) {
186 np = realloc(m->header, ALIGN8(new_size));
190 /* Initially, the header is allocated as part of of
191 * the sd_bus_message itself, let's replace it by
194 np = malloc(ALIGN8(new_size));
198 memcpy(np, m->header, sizeof(struct bus_header));
201 /* Zero out padding */
202 if (start > old_size)
203 memzero((uint8_t*) np + old_size, start - old_size);
207 m->header->fields_size = new_size - sizeof(struct bus_header);
209 /* Adjust quick access pointers */
210 m->path = adjust_pointer(m->path, op, old_size, m->header);
211 m->interface = adjust_pointer(m->interface, op, old_size, m->header);
212 m->member = adjust_pointer(m->member, op, old_size, m->header);
213 m->destination = adjust_pointer(m->destination, op, old_size, m->header);
214 m->sender = adjust_pointer(m->sender, op, old_size, m->header);
215 m->error.name = adjust_pointer(m->error.name, op, old_size, m->header);
217 m->free_header = true;
220 if (m->n_header_offsets >= ELEMENTSOF(m->header_offsets))
223 m->header_offsets[m->n_header_offsets++] = new_size - sizeof(struct bus_header);
226 return (uint8_t*) np + start;
233 static int message_append_field_string(
245 /* dbus1 doesn't allow strings over 32bit, let's enforce this
246 * globally, to not risk convertability */
248 if (l > (size_t) (uint32_t) -1)
251 /* Signature "(yv)" where the variant contains "s" */
253 if (BUS_MESSAGE_IS_GVARIANT(m)) {
255 /* (field id byte + 7x padding, ((string + NUL) + NUL + signature string 's') */
256 p = message_extend_fields(m, 8, 1 + 7 + l + 1 + 1 + 1, true);
268 *ret = (char*) p + 8;
271 /* (field id byte + (signature length + signature 's' + NUL) + (string length + string + NUL)) */
272 p = message_extend_fields(m, 8, 4 + 4 + l + 1, false);
281 ((uint32_t*) p)[1] = l;
282 memcpy(p + 8, s, l + 1);
285 *ret = (char*) p + 8;
291 static int message_append_field_signature(
302 /* dbus1 doesn't allow signatures over 32bit, let's enforce
303 * this globally, to not risk convertability */
308 /* Signature "(yv)" where the variant contains "g" */
310 if (BUS_MESSAGE_IS_GVARIANT(m))
311 /* For gvariant the serialization is the same as for normal strings */
312 return message_append_field_string(m, h, 'g', s, ret);
314 /* (field id byte + (signature length + signature 'g' + NUL) + (string length + string + NUL)) */
315 p = message_extend_fields(m, 8, 4 + 1 + l + 1, false);
321 p[2] = SD_BUS_TYPE_SIGNATURE;
324 memcpy(p + 5, s, l + 1);
327 *ret = (const char*) p + 5;
333 static int message_append_field_uint32(sd_bus_message *m, uint8_t h, uint32_t x) {
338 if (BUS_MESSAGE_IS_GVARIANT(m)) {
339 /* (field id byte + 7x padding + ((value + NUL + signature string 'u') */
341 p = message_extend_fields(m, 8, 1 + 7 + 4 + 1 + 1, true);
347 *((uint32_t*) (p + 8)) = x;
351 /* (field id byte + (signature length + signature 'u' + NUL) + value) */
352 p = message_extend_fields(m, 8, 4 + 4, false);
358 p[2] = SD_BUS_TYPE_UINT32;
361 ((uint32_t*) p)[1] = x;
367 int bus_message_from_header(
373 const struct ucred *ucred,
376 sd_bus_message **ret) {
379 struct bus_header *h;
383 assert(buffer || length <= 0);
384 assert(fds || n_fds <= 0);
387 if (length < sizeof(struct bus_header))
391 if (h->version != 1 &&
398 if (h->type == _SD_BUS_MESSAGE_TYPE_INVALID)
401 if (h->endian != BUS_LITTLE_ENDIAN &&
402 h->endian != BUS_BIG_ENDIAN)
405 a = ALIGN(sizeof(sd_bus_message)) + ALIGN(extra);
408 label_sz = strlen(label);
423 m->creds.pid = ucred->pid;
424 m->creds.uid = ucred->uid;
425 m->creds.gid = ucred->gid;
427 /* Due to namespace translations some data might be
428 * missing from this ucred record. */
429 if (m->creds.pid > 0)
430 m->creds.mask |= SD_BUS_CREDS_PID;
432 if (m->creds.uid != UID_INVALID)
433 m->creds.mask |= SD_BUS_CREDS_UID;
435 if (m->creds.gid != GID_INVALID)
436 m->creds.mask |= SD_BUS_CREDS_GID;
440 m->creds.label = (char*) m + ALIGN(sizeof(sd_bus_message)) + ALIGN(extra);
441 memcpy(m->creds.label, label, label_sz + 1);
443 m->creds.mask |= SD_BUS_CREDS_SELINUX_CONTEXT;
446 m->bus = sd_bus_ref(bus);
452 int bus_message_from_malloc(
458 const struct ucred *ucred,
460 sd_bus_message **ret) {
466 r = bus_message_from_header(bus, buffer, length, fds, n_fds, ucred, label, 0, &m);
470 if (length != BUS_MESSAGE_SIZE(m)) {
475 sz = length - sizeof(struct bus_header) - ALIGN8(BUS_MESSAGE_FIELDS_SIZE(m));
478 m->body.data = (uint8_t*) buffer + sizeof(struct bus_header) + ALIGN8(BUS_MESSAGE_FIELDS_SIZE(m));
480 m->body.sealed = true;
485 m->iovec = m->iovec_fixed;
486 m->iovec[0].iov_base = buffer;
487 m->iovec[0].iov_len = length;
489 r = bus_message_parse_fields(m);
493 /* We take possession of the memory and fds now */
494 m->free_header = true;
505 static sd_bus_message *message_new(sd_bus *bus, uint8_t type) {
510 m = malloc0(ALIGN(sizeof(sd_bus_message)) + sizeof(struct bus_header));
515 m->header = (struct bus_header*) ((uint8_t*) m + ALIGN(sizeof(struct sd_bus_message)));
516 m->header->endian = BUS_NATIVE_ENDIAN;
517 m->header->type = type;
518 m->header->version = bus ? bus->message_version : 1;
519 m->allow_fds = !bus || bus->can_fds || (bus->state != BUS_HELLO && bus->state != BUS_RUNNING);
520 m->root_container.need_offsets = BUS_MESSAGE_IS_GVARIANT(m);
521 m->bus = sd_bus_ref(bus);
526 _public_ int sd_bus_message_new_signal(
530 const char *interface,
531 const char *member) {
536 assert_return(bus, -ENOTCONN);
537 assert_return(bus->state != BUS_UNSET, -ENOTCONN);
538 assert_return(object_path_is_valid(path), -EINVAL);
539 assert_return(interface_name_is_valid(interface), -EINVAL);
540 assert_return(member_name_is_valid(member), -EINVAL);
541 assert_return(m, -EINVAL);
543 t = message_new(bus, SD_BUS_MESSAGE_SIGNAL);
547 t->header->flags |= BUS_MESSAGE_NO_REPLY_EXPECTED;
549 r = message_append_field_string(t, BUS_MESSAGE_HEADER_PATH, SD_BUS_TYPE_OBJECT_PATH, path, &t->path);
552 r = message_append_field_string(t, BUS_MESSAGE_HEADER_INTERFACE, SD_BUS_TYPE_STRING, interface, &t->interface);
555 r = message_append_field_string(t, BUS_MESSAGE_HEADER_MEMBER, SD_BUS_TYPE_STRING, member, &t->member);
563 sd_bus_message_unref(t);
567 _public_ int sd_bus_message_new_method_call(
570 const char *destination,
572 const char *interface,
573 const char *member) {
578 assert_return(bus, -ENOTCONN);
579 assert_return(bus->state != BUS_UNSET, -ENOTCONN);
580 assert_return(!destination || service_name_is_valid(destination), -EINVAL);
581 assert_return(object_path_is_valid(path), -EINVAL);
582 assert_return(!interface || interface_name_is_valid(interface), -EINVAL);
583 assert_return(member_name_is_valid(member), -EINVAL);
584 assert_return(m, -EINVAL);
586 t = message_new(bus, SD_BUS_MESSAGE_METHOD_CALL);
590 r = message_append_field_string(t, BUS_MESSAGE_HEADER_PATH, SD_BUS_TYPE_OBJECT_PATH, path, &t->path);
593 r = message_append_field_string(t, BUS_MESSAGE_HEADER_MEMBER, SD_BUS_TYPE_STRING, member, &t->member);
598 r = message_append_field_string(t, BUS_MESSAGE_HEADER_INTERFACE, SD_BUS_TYPE_STRING, interface, &t->interface);
604 r = message_append_field_string(t, BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &t->destination);
617 static int message_new_reply(
618 sd_bus_message *call,
620 sd_bus_message **m) {
625 assert_return(call, -EINVAL);
626 assert_return(call->sealed, -EPERM);
627 assert_return(call->header->type == SD_BUS_MESSAGE_METHOD_CALL, -EINVAL);
628 assert_return(call->bus->state != BUS_UNSET, -ENOTCONN);
629 assert_return(m, -EINVAL);
631 t = message_new(call->bus, type);
635 t->header->flags |= BUS_MESSAGE_NO_REPLY_EXPECTED;
636 t->reply_cookie = BUS_MESSAGE_COOKIE(call);
638 r = message_append_field_uint32(t, BUS_MESSAGE_HEADER_REPLY_SERIAL, (uint32_t) t->reply_cookie);
643 r = message_append_field_string(t, BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, call->sender, &t->destination);
648 t->dont_send = !!(call->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED);
649 t->enforced_reply_signature = call->enforced_reply_signature;
659 _public_ int sd_bus_message_new_method_return(
660 sd_bus_message *call,
661 sd_bus_message **m) {
663 return message_new_reply(call, SD_BUS_MESSAGE_METHOD_RETURN, m);
666 _public_ int sd_bus_message_new_method_error(
667 sd_bus_message *call,
669 const sd_bus_error *e) {
674 assert_return(sd_bus_error_is_set(e), -EINVAL);
675 assert_return(m, -EINVAL);
677 r = message_new_reply(call, SD_BUS_MESSAGE_METHOD_ERROR, &t);
681 r = message_append_field_string(t, BUS_MESSAGE_HEADER_ERROR_NAME, SD_BUS_TYPE_STRING, e->name, &t->error.name);
686 r = message_append_basic(t, SD_BUS_TYPE_STRING, e->message, (const void**) &t->error.message);
691 t->error._need_free = -1;
701 _public_ int sd_bus_message_new_method_errorf(
702 sd_bus_message *call,
708 _cleanup_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
711 assert_return(name, -EINVAL);
712 assert_return(m, -EINVAL);
714 va_start(ap, format);
715 bus_error_setfv(&error, name, format, ap);
718 return sd_bus_message_new_method_error(call, m, &error);
721 _public_ int sd_bus_message_new_method_errno(
722 sd_bus_message *call,
725 const sd_bus_error *p) {
727 _cleanup_free_ sd_bus_error berror = SD_BUS_ERROR_NULL;
729 if (sd_bus_error_is_set(p))
730 return sd_bus_message_new_method_error(call, m, p);
732 sd_bus_error_set_errno(&berror, error);
734 return sd_bus_message_new_method_error(call, m, &berror);
737 _public_ int sd_bus_message_new_method_errnof(
738 sd_bus_message *call,
744 _cleanup_free_ sd_bus_error berror = SD_BUS_ERROR_NULL;
747 va_start(ap, format);
748 bus_error_set_errnofv(&berror, error, format, ap);
751 return sd_bus_message_new_method_error(call, m, &berror);
754 int bus_message_new_synthetic_error(
757 const sd_bus_error *e,
758 sd_bus_message **m) {
764 assert(sd_bus_error_is_set(e));
767 t = message_new(bus, SD_BUS_MESSAGE_METHOD_ERROR);
771 t->header->flags |= BUS_MESSAGE_NO_REPLY_EXPECTED;
772 t->reply_cookie = cookie;
774 r = message_append_field_uint32(t, BUS_MESSAGE_HEADER_REPLY_SERIAL, (uint32_t) t->reply_cookie);
778 if (bus && bus->unique_name) {
779 r = message_append_field_string(t, BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, bus->unique_name, &t->destination);
784 r = message_append_field_string(t, BUS_MESSAGE_HEADER_ERROR_NAME, SD_BUS_TYPE_STRING, e->name, &t->error.name);
789 r = message_append_basic(t, SD_BUS_TYPE_STRING, e->message, (const void**) &t->error.message);
794 t->error._need_free = -1;
804 _public_ sd_bus_message* sd_bus_message_ref(sd_bus_message *m) {
805 assert_return(m, NULL);
807 assert(m->n_ref > 0);
813 _public_ sd_bus_message* sd_bus_message_unref(sd_bus_message *m) {
818 assert(m->n_ref > 0);
828 _public_ int sd_bus_message_get_type(sd_bus_message *m, uint8_t *type) {
829 assert_return(m, -EINVAL);
830 assert_return(type, -EINVAL);
832 *type = m->header->type;
836 _public_ int sd_bus_message_get_cookie(sd_bus_message *m, uint64_t *cookie) {
837 assert_return(m, -EINVAL);
838 assert_return(cookie, -EINVAL);
839 assert_return(m->header->serial != 0, -ENODATA);
841 *cookie = BUS_MESSAGE_COOKIE(m);
845 _public_ int sd_bus_message_get_reply_cookie(sd_bus_message *m, uint64_t *cookie) {
846 assert_return(m, -EINVAL);
847 assert_return(cookie, -EINVAL);
848 assert_return(m->reply_cookie != 0, -ENODATA);
850 *cookie = m->reply_cookie;
854 _public_ int sd_bus_message_get_expect_reply(sd_bus_message *m) {
855 assert_return(m, -EINVAL);
857 return m->header->type == SD_BUS_MESSAGE_METHOD_CALL &&
858 !(m->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED);
861 _public_ int sd_bus_message_get_auto_start(sd_bus_message *m) {
862 assert_return(m, -EINVAL);
864 return !(m->header->flags & BUS_MESSAGE_NO_AUTO_START);
867 _public_ int sd_bus_message_get_allow_interactive_authorization(sd_bus_message *m) {
868 assert_return(m, -EINVAL);
870 return m->header->type == SD_BUS_MESSAGE_METHOD_CALL &&
871 (m->header->flags & BUS_MESSAGE_ALLOW_INTERACTIVE_AUTHORIZATION);
874 _public_ const char *sd_bus_message_get_path(sd_bus_message *m) {
875 assert_return(m, NULL);
880 _public_ const char *sd_bus_message_get_interface(sd_bus_message *m) {
881 assert_return(m, NULL);
886 _public_ const char *sd_bus_message_get_member(sd_bus_message *m) {
887 assert_return(m, NULL);
892 _public_ const char *sd_bus_message_get_destination(sd_bus_message *m) {
893 assert_return(m, NULL);
895 return m->destination;
898 _public_ const char *sd_bus_message_get_sender(sd_bus_message *m) {
899 assert_return(m, NULL);
904 _public_ const sd_bus_error *sd_bus_message_get_error(sd_bus_message *m) {
905 assert_return(m, NULL);
906 assert_return(sd_bus_error_is_set(&m->error), NULL);
911 _public_ int sd_bus_message_get_monotonic_usec(sd_bus_message *m, uint64_t *usec) {
912 assert_return(m, -EINVAL);
913 assert_return(usec, -EINVAL);
915 if (m->monotonic <= 0)
918 *usec = m->monotonic;
922 _public_ int sd_bus_message_get_realtime_usec(sd_bus_message *m, uint64_t *usec) {
923 assert_return(m, -EINVAL);
924 assert_return(usec, -EINVAL);
926 if (m->realtime <= 0)
933 _public_ int sd_bus_message_get_seqnum(sd_bus_message *m, uint64_t *seqnum) {
934 assert_return(m, -EINVAL);
935 assert_return(seqnum, -EINVAL);
944 _public_ sd_bus_creds *sd_bus_message_get_creds(sd_bus_message *m) {
945 assert_return(m, NULL);
947 if (m->creds.mask == 0)
953 _public_ int sd_bus_message_is_signal(sd_bus_message *m,
954 const char *interface,
955 const char *member) {
956 assert_return(m, -EINVAL);
958 if (m->header->type != SD_BUS_MESSAGE_SIGNAL)
961 if (interface && (!m->interface || !streq(m->interface, interface)))
964 if (member && (!m->member || !streq(m->member, member)))
970 _public_ int sd_bus_message_is_method_call(sd_bus_message *m,
971 const char *interface,
972 const char *member) {
973 assert_return(m, -EINVAL);
975 if (m->header->type != SD_BUS_MESSAGE_METHOD_CALL)
978 if (interface && (!m->interface || !streq(m->interface, interface)))
981 if (member && (!m->member || !streq(m->member, member)))
987 _public_ int sd_bus_message_is_method_error(sd_bus_message *m, const char *name) {
988 assert_return(m, -EINVAL);
990 if (m->header->type != SD_BUS_MESSAGE_METHOD_ERROR)
993 if (name && (!m->error.name || !streq(m->error.name, name)))
999 _public_ int sd_bus_message_set_expect_reply(sd_bus_message *m, int b) {
1000 assert_return(m, -EINVAL);
1001 assert_return(!m->sealed, -EPERM);
1002 assert_return(m->header->type == SD_BUS_MESSAGE_METHOD_CALL, -EPERM);
1005 m->header->flags &= ~BUS_MESSAGE_NO_REPLY_EXPECTED;
1007 m->header->flags |= BUS_MESSAGE_NO_REPLY_EXPECTED;
1012 _public_ int sd_bus_message_set_auto_start(sd_bus_message *m, int b) {
1013 assert_return(m, -EINVAL);
1014 assert_return(!m->sealed, -EPERM);
1017 m->header->flags &= ~BUS_MESSAGE_NO_AUTO_START;
1019 m->header->flags |= BUS_MESSAGE_NO_AUTO_START;
1024 _public_ int sd_bus_message_set_allow_interactive_authorization(sd_bus_message *m, int b) {
1025 assert_return(m, -EINVAL);
1026 assert_return(!m->sealed, -EPERM);
1029 m->header->flags |= BUS_MESSAGE_ALLOW_INTERACTIVE_AUTHORIZATION;
1031 m->header->flags &= ~BUS_MESSAGE_ALLOW_INTERACTIVE_AUTHORIZATION;
1036 static struct bus_container *message_get_container(sd_bus_message *m) {
1039 if (m->n_containers == 0)
1040 return &m->root_container;
1042 assert(m->containers);
1043 return m->containers + m->n_containers - 1;
1046 struct bus_body_part *message_append_part(sd_bus_message *m) {
1047 struct bus_body_part *part;
1054 if (m->n_body_parts <= 0) {
1058 assert(m->body_end);
1060 part = new0(struct bus_body_part, 1);
1066 m->body_end->next = part;
1076 static void part_zero(struct bus_body_part *part, size_t sz) {
1081 /* All other fields can be left in their defaults */
1082 assert(!part->data);
1083 assert(part->memfd < 0);
1086 part->is_zero = true;
1087 part->sealed = true;
1090 static int part_make_space(
1091 struct sd_bus_message *m,
1092 struct bus_body_part *part,
1101 assert(!part->sealed);
1106 if (!part->data && part->memfd < 0)
1107 part->memfd = bus_kernel_pop_memfd(m->bus, &part->data, &part->mapped, &part->allocated);
1109 if (part->memfd >= 0) {
1111 if (part->allocated == 0 || sz > part->allocated) {
1112 uint64_t new_allocated;
1114 new_allocated = PAGE_ALIGN(sz > 0 ? 2 * sz : 1);
1115 r = memfd_set_size(part->memfd, new_allocated);
1121 part->allocated = new_allocated;
1124 if (!part->data || sz > part->mapped) {
1127 psz = PAGE_ALIGN(sz > 0 ? sz : 1);
1128 if (part->mapped <= 0)
1129 n = mmap(NULL, psz, PROT_READ|PROT_WRITE, MAP_SHARED, part->memfd, 0);
1131 n = mremap(part->data, part->mapped, psz, MREMAP_MAYMOVE);
1133 if (n == MAP_FAILED) {
1142 part->munmap_this = true;
1144 if (part->allocated == 0 || sz > part->allocated) {
1145 size_t new_allocated;
1147 new_allocated = sz > 0 ? 2 * sz : 64;
1148 n = realloc(part->data, new_allocated);
1155 part->allocated = new_allocated;
1156 part->free_this = true;
1161 *q = part->data ? (uint8_t*) part->data + part->size : NULL;
1167 static int message_add_offset(sd_bus_message *m, size_t offset) {
1168 struct bus_container *c;
1171 assert(BUS_MESSAGE_IS_GVARIANT(m));
1173 /* Add offset to current container, unless this is the first
1174 * item in it, which will have the 0 offset, which we can
1176 c = message_get_container(m);
1178 if (!c->need_offsets)
1181 if (!GREEDY_REALLOC(c->offsets, c->offsets_allocated, c->n_offsets + 1))
1184 c->offsets[c->n_offsets++] = offset;
1188 static void message_extend_containers(sd_bus_message *m, size_t expand) {
1189 struct bus_container *c;
1196 /* Update counters */
1197 for (c = m->containers; c < m->containers + m->n_containers; c++) {
1200 *c->array_size += expand;
1204 static void *message_extend_body(sd_bus_message *m, size_t align, size_t sz, bool add_offset) {
1205 size_t start_body, end_body, padding, added;
1216 start_body = ALIGN_TO((size_t) m->header->body_size, align);
1217 end_body = start_body + sz;
1219 padding = start_body - m->header->body_size;
1220 added = padding + sz;
1222 /* Check for 32bit overflows */
1223 if (end_body > (size_t) ((uint32_t) -1)) {
1229 struct bus_body_part *part = NULL;
1233 m->n_body_parts <= 0 ||
1234 m->body_end->sealed ||
1235 padding != ALIGN_TO(m->body_end->size, align) - m->body_end->size;
1239 part = message_append_part(m);
1243 part_zero(part, padding);
1246 part = message_append_part(m);
1250 r = part_make_space(m, part, sz, &p);
1254 struct bus_container *c;
1256 size_t os, start_part, end_part;
1262 start_part = ALIGN_TO(part->size, align);
1263 end_part = start_part + sz;
1265 r = part_make_space(m, part, end_part, &p);
1270 memzero(p, padding);
1271 p = (uint8_t*) p + padding;
1274 /* Readjust pointers */
1275 for (c = m->containers; c < m->containers + m->n_containers; c++)
1276 c->array_size = adjust_pointer(c->array_size, op, os, part->data);
1278 m->error.message = (const char*) adjust_pointer(m->error.message, op, os, part->data);
1281 /* Return something that is not NULL and is aligned */
1282 p = (uint8_t *) NULL + align;
1284 m->header->body_size = end_body;
1285 message_extend_containers(m, added);
1288 r = message_add_offset(m, end_body);
1298 static int message_push_fd(sd_bus_message *m, int fd) {
1309 copy = fcntl(fd, F_DUPFD_CLOEXEC, 3);
1313 f = realloc(m->fds, sizeof(int) * (m->n_fds + 1));
1321 m->fds[m->n_fds] = copy;
1327 int message_append_basic(sd_bus_message *m, char type, const void *p, const void **stored) {
1328 _cleanup_close_ int fd = -1;
1329 struct bus_container *c;
1333 assert_return(m, -EINVAL);
1334 assert_return(!m->sealed, -EPERM);
1335 assert_return(bus_type_is_basic(type), -EINVAL);
1336 assert_return(!m->poisoned, -ESTALE);
1338 c = message_get_container(m);
1340 if (c->signature && c->signature[c->index]) {
1341 /* Container signature is already set */
1343 if (c->signature[c->index] != type)
1348 /* Maybe we can append to the signature? But only if this is the top-level container*/
1349 if (c->enclosing != 0)
1352 e = strextend(&c->signature, CHAR_TO_STR(type), NULL);
1359 if (BUS_MESSAGE_IS_GVARIANT(m)) {
1365 case SD_BUS_TYPE_SIGNATURE:
1366 case SD_BUS_TYPE_STRING:
1369 /* Fall through... */
1370 case SD_BUS_TYPE_OBJECT_PATH:
1378 case SD_BUS_TYPE_BOOLEAN:
1380 u8 = p && *(int*) p;
1386 case SD_BUS_TYPE_UNIX_FD:
1391 fd = message_push_fd(m, *(int*) p);
1402 align = bus_gvariant_get_alignment(CHAR_TO_STR(type));
1403 sz = bus_gvariant_get_size(CHAR_TO_STR(type));
1410 a = message_extend_body(m, align, sz, true);
1417 *stored = (const uint8_t*) a;
1424 case SD_BUS_TYPE_STRING:
1425 /* To make things easy we'll serialize a NULL string
1426 * into the empty string */
1429 /* Fall through... */
1430 case SD_BUS_TYPE_OBJECT_PATH:
1436 sz = 4 + strlen(p) + 1;
1439 case SD_BUS_TYPE_SIGNATURE:
1444 sz = 1 + strlen(p) + 1;
1447 case SD_BUS_TYPE_BOOLEAN:
1449 u32 = p && *(int*) p;
1455 case SD_BUS_TYPE_UNIX_FD:
1460 fd = message_push_fd(m, *(int*) p);
1471 align = bus_type_get_alignment(type);
1472 sz = bus_type_get_size(type);
1479 a = message_extend_body(m, align, sz, false);
1483 if (type == SD_BUS_TYPE_STRING || type == SD_BUS_TYPE_OBJECT_PATH) {
1484 *(uint32_t*) a = sz - 5;
1485 memcpy((uint8_t*) a + 4, p, sz - 4);
1488 *stored = (const uint8_t*) a + 4;
1490 } else if (type == SD_BUS_TYPE_SIGNATURE) {
1491 *(uint8_t*) a = sz - 2;
1492 memcpy((uint8_t*) a + 1, p, sz - 1);
1495 *stored = (const uint8_t*) a + 1;
1504 if (type == SD_BUS_TYPE_UNIX_FD)
1507 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1514 _public_ int sd_bus_message_append_basic(sd_bus_message *m, char type, const void *p) {
1515 return message_append_basic(m, type, p, NULL);
1518 _public_ int sd_bus_message_append_string_space(
1523 struct bus_container *c;
1526 assert_return(m, -EINVAL);
1527 assert_return(s, -EINVAL);
1528 assert_return(!m->sealed, -EPERM);
1529 assert_return(!m->poisoned, -ESTALE);
1531 c = message_get_container(m);
1533 if (c->signature && c->signature[c->index]) {
1534 /* Container signature is already set */
1536 if (c->signature[c->index] != SD_BUS_TYPE_STRING)
1541 /* Maybe we can append to the signature? But only if this is the top-level container*/
1542 if (c->enclosing != 0)
1545 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRING), NULL);
1552 if (BUS_MESSAGE_IS_GVARIANT(m)) {
1553 a = message_extend_body(m, 1, size + 1, true);
1559 a = message_extend_body(m, 4, 4 + size + 1, false);
1563 *(uint32_t*) a = size;
1569 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1575 _public_ int sd_bus_message_append_string_iovec(
1577 const struct iovec *iov,
1585 assert_return(m, -EINVAL);
1586 assert_return(!m->sealed, -EPERM);
1587 assert_return(iov || n == 0, -EINVAL);
1588 assert_return(!m->poisoned, -ESTALE);
1590 size = IOVEC_TOTAL_SIZE(iov, n);
1592 r = sd_bus_message_append_string_space(m, size, &p);
1596 for (i = 0; i < n; i++) {
1598 if (iov[i].iov_base)
1599 memcpy(p, iov[i].iov_base, iov[i].iov_len);
1601 memset(p, ' ', iov[i].iov_len);
1603 p += iov[i].iov_len;
1609 static int bus_message_open_array(
1611 struct bus_container *c,
1612 const char *contents,
1613 uint32_t **array_size,
1615 bool *need_offsets) {
1625 assert(need_offsets);
1627 if (!signature_is_single(contents, true))
1630 if (c->signature && c->signature[c->index]) {
1632 /* Verify the existing signature */
1634 if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
1637 if (!startswith(c->signature + c->index + 1, contents))
1640 nindex = c->index + 1 + strlen(contents);
1644 if (c->enclosing != 0)
1647 /* Extend the existing signature */
1649 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_ARRAY), contents, NULL);
1655 nindex = e - c->signature;
1658 if (BUS_MESSAGE_IS_GVARIANT(m)) {
1659 alignment = bus_gvariant_get_alignment(contents);
1663 /* Add alignment padding and add to offset list */
1664 if (!message_extend_body(m, alignment, 0, false))
1667 r = bus_gvariant_is_fixed_size(contents);
1671 *begin = m->header->body_size;
1672 *need_offsets = r == 0;
1676 struct bus_body_part *o;
1678 alignment = bus_type_get_alignment(contents[0]);
1682 a = message_extend_body(m, 4, 4, false);
1687 op = m->body_end->data;
1688 os = m->body_end->size;
1690 /* Add alignment between size and first element */
1691 if (!message_extend_body(m, alignment, 0, false))
1694 /* location of array size might have changed so let's readjust a */
1695 if (o == m->body_end)
1696 a = adjust_pointer(a, op, os, m->body_end->data);
1702 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1708 static int bus_message_open_variant(
1710 struct bus_container *c,
1711 const char *contents) {
1717 if (!signature_is_single(contents, false))
1720 if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
1723 if (c->signature && c->signature[c->index]) {
1725 if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
1731 if (c->enclosing != 0)
1734 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_VARIANT), NULL);
1741 if (BUS_MESSAGE_IS_GVARIANT(m)) {
1742 /* Variants are always aligned to 8 */
1744 if (!message_extend_body(m, 8, 0, false))
1751 l = strlen(contents);
1752 a = message_extend_body(m, 1, 1 + l + 1, false);
1757 memcpy((uint8_t*) a + 1, contents, l + 1);
1760 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1766 static int bus_message_open_struct(
1768 struct bus_container *c,
1769 const char *contents,
1771 bool *need_offsets) {
1780 assert(need_offsets);
1782 if (!signature_is_valid(contents, false))
1785 if (c->signature && c->signature[c->index]) {
1788 l = strlen(contents);
1790 if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
1791 !startswith(c->signature + c->index + 1, contents) ||
1792 c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
1795 nindex = c->index + 1 + l + 1;
1799 if (c->enclosing != 0)
1802 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_BEGIN), contents, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_END), NULL);
1808 nindex = e - c->signature;
1811 if (BUS_MESSAGE_IS_GVARIANT(m)) {
1814 alignment = bus_gvariant_get_alignment(contents);
1818 if (!message_extend_body(m, alignment, 0, false))
1821 r = bus_gvariant_is_fixed_size(contents);
1825 *begin = m->header->body_size;
1826 *need_offsets = r == 0;
1828 /* Align contents to 8 byte boundary */
1829 if (!message_extend_body(m, 8, 0, false))
1833 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1839 static int bus_message_open_dict_entry(
1841 struct bus_container *c,
1842 const char *contents,
1844 bool *need_offsets) {
1852 assert(need_offsets);
1854 if (!signature_is_pair(contents))
1857 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1860 if (c->signature && c->signature[c->index]) {
1863 l = strlen(contents);
1865 if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
1866 !startswith(c->signature + c->index + 1, contents) ||
1867 c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
1872 if (BUS_MESSAGE_IS_GVARIANT(m)) {
1875 alignment = bus_gvariant_get_alignment(contents);
1879 if (!message_extend_body(m, alignment, 0, false))
1882 r = bus_gvariant_is_fixed_size(contents);
1886 *begin = m->header->body_size;
1887 *need_offsets = r == 0;
1889 /* Align contents to 8 byte boundary */
1890 if (!message_extend_body(m, 8, 0, false))
1897 _public_ int sd_bus_message_open_container(
1900 const char *contents) {
1902 struct bus_container *c, *w;
1903 uint32_t *array_size = NULL;
1905 size_t before, begin = 0;
1906 bool need_offsets = false;
1909 assert_return(m, -EINVAL);
1910 assert_return(!m->sealed, -EPERM);
1911 assert_return(contents, -EINVAL);
1912 assert_return(!m->poisoned, -ESTALE);
1914 /* Make sure we have space for one more container */
1915 if (!GREEDY_REALLOC(m->containers, m->containers_allocated, m->n_containers + 1)) {
1920 c = message_get_container(m);
1922 signature = strdup(contents);
1928 /* Save old index in the parent container, in case we have to
1929 * abort this container */
1930 c->saved_index = c->index;
1931 before = m->header->body_size;
1933 if (type == SD_BUS_TYPE_ARRAY)
1934 r = bus_message_open_array(m, c, contents, &array_size, &begin, &need_offsets);
1935 else if (type == SD_BUS_TYPE_VARIANT)
1936 r = bus_message_open_variant(m, c, contents);
1937 else if (type == SD_BUS_TYPE_STRUCT)
1938 r = bus_message_open_struct(m, c, contents, &begin, &need_offsets);
1939 else if (type == SD_BUS_TYPE_DICT_ENTRY)
1940 r = bus_message_open_dict_entry(m, c, contents, &begin, &need_offsets);
1949 /* OK, let's fill it in */
1950 w = m->containers + m->n_containers++;
1951 w->enclosing = type;
1952 w->signature = signature;
1954 w->array_size = array_size;
1957 w->n_offsets = w->offsets_allocated = 0;
1959 w->need_offsets = need_offsets;
1964 static size_t determine_word_size(size_t sz, size_t extra) {
1965 if (sz + extra <= 0xFF)
1967 else if (sz + extra*2 <= 0xFFFF)
1969 else if (sz + extra*4 <= 0xFFFFFFFF)
1975 static size_t read_word_le(void *p, size_t sz) {
1985 return *(uint8_t*) p;
1990 return le16toh(x.u16);
1992 return le32toh(x.u32);
1994 return le64toh(x.u64);
1996 assert_not_reached("unknown word width");
1999 static void write_word_le(void *p, size_t sz, size_t value) {
2007 assert(sz == 8 || (value < (1ULL << (sz*8))));
2010 *(uint8_t*) p = value;
2013 x.u16 = htole16((uint16_t) value);
2015 x.u32 = htole32((uint32_t) value);
2017 x.u64 = htole64((uint64_t) value);
2019 assert_not_reached("unknown word width");
2024 static int bus_message_close_array(sd_bus_message *m, struct bus_container *c) {
2029 if (!BUS_MESSAGE_IS_GVARIANT(m))
2032 if (c->need_offsets) {
2033 size_t payload, sz, i;
2036 /* Variable-width arrays */
2038 payload = c->n_offsets > 0 ? c->offsets[c->n_offsets-1] - c->begin : 0;
2039 sz = determine_word_size(payload, c->n_offsets);
2041 a = message_extend_body(m, 1, sz * c->n_offsets, true);
2045 for (i = 0; i < c->n_offsets; i++)
2046 write_word_le(a + sz*i, sz, c->offsets[i] - c->begin);
2050 /* Fixed-width or empty arrays */
2052 a = message_extend_body(m, 1, 0, true); /* let's add offset to parent */
2060 static int bus_message_close_variant(sd_bus_message *m, struct bus_container *c) {
2066 assert(c->signature);
2068 if (!BUS_MESSAGE_IS_GVARIANT(m))
2071 l = strlen(c->signature);
2073 a = message_extend_body(m, 1, 1 + l, true);
2078 memcpy(a+1, c->signature, l);
2083 static int bus_message_close_struct(sd_bus_message *m, struct bus_container *c, bool add_offset) {
2084 size_t n_variable = 0;
2093 if (!BUS_MESSAGE_IS_GVARIANT(m))
2096 p = strempty(c->signature);
2100 r = signature_element_length(p, &n);
2109 r = bus_gvariant_is_fixed_size(t);
2114 assert(!c->need_offsets || i <= c->n_offsets);
2116 /* We need to add an offset for each item that has a
2117 * variable size and that is not the last one in the
2119 if (r == 0 && p[n] != 0)
2126 assert(!c->need_offsets || i == c->n_offsets);
2127 assert(c->need_offsets || n_variable == 0);
2129 if (n_variable <= 0) {
2130 a = message_extend_body(m, 1, 0, add_offset);
2137 assert(c->offsets[c->n_offsets-1] == m->header->body_size);
2139 sz = determine_word_size(m->header->body_size - c->begin, n_variable);
2141 a = message_extend_body(m, 1, sz * n_variable, add_offset);
2145 p = strempty(c->signature);
2146 for (i = 0, j = 0; i < c->n_offsets; i++) {
2150 r = signature_element_length(p, &n);
2161 r = bus_gvariant_is_fixed_size(t);
2164 if (r > 0 || p[0] == 0)
2168 k = n_variable - 1 - j;
2170 write_word_le(a + k * sz, sz, c->offsets[i] - c->begin);
2179 _public_ int sd_bus_message_close_container(sd_bus_message *m) {
2180 struct bus_container *c;
2183 assert_return(m, -EINVAL);
2184 assert_return(!m->sealed, -EPERM);
2185 assert_return(m->n_containers > 0, -EINVAL);
2186 assert_return(!m->poisoned, -ESTALE);
2188 c = message_get_container(m);
2190 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2191 if (c->signature && c->signature[c->index] != 0)
2196 if (c->enclosing == SD_BUS_TYPE_ARRAY)
2197 r = bus_message_close_array(m, c);
2198 else if (c->enclosing == SD_BUS_TYPE_VARIANT)
2199 r = bus_message_close_variant(m, c);
2200 else if (c->enclosing == SD_BUS_TYPE_STRUCT || c->enclosing == SD_BUS_TYPE_DICT_ENTRY)
2201 r = bus_message_close_struct(m, c, true);
2203 assert_not_reached("Unknown container type");
2217 static int type_stack_push(TypeStack *stack, unsigned max, unsigned *i, const char *types, unsigned n_struct, unsigned n_array) {
2224 stack[*i].types = types;
2225 stack[*i].n_struct = n_struct;
2226 stack[*i].n_array = n_array;
2232 static int type_stack_pop(TypeStack *stack, unsigned max, unsigned *i, const char **types, unsigned *n_struct, unsigned *n_array) {
2243 *types = stack[*i].types;
2244 *n_struct = stack[*i].n_struct;
2245 *n_array = stack[*i].n_array;
2250 int bus_message_append_ap(
2255 unsigned n_array, n_struct;
2256 TypeStack stack[BUS_CONTAINER_DEPTH];
2257 unsigned stack_ptr = 0;
2265 n_array = (unsigned) -1;
2266 n_struct = strlen(types);
2271 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
2272 r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
2278 r = sd_bus_message_close_container(m);
2286 if (n_array != (unsigned) -1)
2295 case SD_BUS_TYPE_BYTE: {
2298 x = (uint8_t) va_arg(ap, int);
2299 r = sd_bus_message_append_basic(m, *t, &x);
2303 case SD_BUS_TYPE_BOOLEAN:
2304 case SD_BUS_TYPE_INT32:
2305 case SD_BUS_TYPE_UINT32:
2306 case SD_BUS_TYPE_UNIX_FD: {
2309 /* We assume a boolean is the same as int32_t */
2310 assert_cc(sizeof(int32_t) == sizeof(int));
2312 x = va_arg(ap, uint32_t);
2313 r = sd_bus_message_append_basic(m, *t, &x);
2317 case SD_BUS_TYPE_INT16:
2318 case SD_BUS_TYPE_UINT16: {
2321 x = (uint16_t) va_arg(ap, int);
2322 r = sd_bus_message_append_basic(m, *t, &x);
2326 case SD_BUS_TYPE_INT64:
2327 case SD_BUS_TYPE_UINT64:
2328 case SD_BUS_TYPE_DOUBLE: {
2331 x = va_arg(ap, uint64_t);
2332 r = sd_bus_message_append_basic(m, *t, &x);
2336 case SD_BUS_TYPE_STRING:
2337 case SD_BUS_TYPE_OBJECT_PATH:
2338 case SD_BUS_TYPE_SIGNATURE: {
2341 x = va_arg(ap, const char*);
2342 r = sd_bus_message_append_basic(m, *t, x);
2346 case SD_BUS_TYPE_ARRAY: {
2349 r = signature_element_length(t + 1, &k);
2355 memcpy(s, t + 1, k);
2358 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, s);
2363 if (n_array == (unsigned) -1) {
2368 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2374 n_array = va_arg(ap, unsigned);
2379 case SD_BUS_TYPE_VARIANT: {
2382 s = va_arg(ap, const char*);
2386 r = sd_bus_message_open_container(m, SD_BUS_TYPE_VARIANT, s);
2390 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2395 n_struct = strlen(s);
2396 n_array = (unsigned) -1;
2401 case SD_BUS_TYPE_STRUCT_BEGIN:
2402 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
2405 r = signature_element_length(t, &k);
2412 memcpy(s, t + 1, k - 2);
2415 r = sd_bus_message_open_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
2420 if (n_array == (unsigned) -1) {
2425 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2431 n_array = (unsigned) -1;
2447 _public_ int sd_bus_message_append(sd_bus_message *m, const char *types, ...) {
2451 assert_return(m, -EINVAL);
2452 assert_return(types, -EINVAL);
2453 assert_return(!m->sealed, -EPERM);
2454 assert_return(!m->poisoned, -ESTALE);
2456 va_start(ap, types);
2457 r = bus_message_append_ap(m, types, ap);
2463 _public_ int sd_bus_message_append_array_space(
2473 assert_return(m, -EINVAL);
2474 assert_return(!m->sealed, -EPERM);
2475 assert_return(bus_type_is_trivial(type) && type != SD_BUS_TYPE_BOOLEAN, -EINVAL);
2476 assert_return(ptr || size == 0, -EINVAL);
2477 assert_return(!m->poisoned, -ESTALE);
2479 /* alignment and size of the trivial types (except bool) is
2480 * identical for gvariant and dbus1 marshalling */
2481 align = bus_type_get_alignment(type);
2482 sz = bus_type_get_size(type);
2484 assert_se(align > 0);
2490 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
2494 a = message_extend_body(m, align, size, false);
2498 r = sd_bus_message_close_container(m);
2506 _public_ int sd_bus_message_append_array(sd_bus_message *m,
2513 assert_return(m, -EINVAL);
2514 assert_return(!m->sealed, -EPERM);
2515 assert_return(bus_type_is_trivial(type), -EINVAL);
2516 assert_return(ptr || size == 0, -EINVAL);
2517 assert_return(!m->poisoned, -ESTALE);
2519 r = sd_bus_message_append_array_space(m, type, size, &p);
2524 memcpy(p, ptr, size);
2529 _public_ int sd_bus_message_append_array_iovec(
2532 const struct iovec *iov,
2540 assert_return(m, -EINVAL);
2541 assert_return(!m->sealed, -EPERM);
2542 assert_return(bus_type_is_trivial(type), -EINVAL);
2543 assert_return(iov || n == 0, -EINVAL);
2544 assert_return(!m->poisoned, -ESTALE);
2546 size = IOVEC_TOTAL_SIZE(iov, n);
2548 r = sd_bus_message_append_array_space(m, type, size, &p);
2552 for (i = 0; i < n; i++) {
2554 if (iov[i].iov_base)
2555 memcpy(p, iov[i].iov_base, iov[i].iov_len);
2557 memzero(p, iov[i].iov_len);
2559 p = (uint8_t*) p + iov[i].iov_len;
2565 _public_ int sd_bus_message_append_array_memfd(sd_bus_message *m,
2568 _cleanup_close_ int copy_fd = -1;
2569 struct bus_body_part *part;
2581 if (!bus_type_is_trivial(type))
2586 r = memfd_set_sealed(memfd);
2590 copy_fd = dup(memfd);
2594 r = memfd_get_size(memfd, &size);
2598 align = bus_type_get_alignment(type);
2599 sz = bus_type_get_size(type);
2601 assert_se(align > 0);
2607 if (size > (uint64_t) (uint32_t) -1)
2610 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
2614 a = message_extend_body(m, align, 0, false);
2618 part = message_append_part(m);
2622 part->memfd = copy_fd;
2623 part->sealed = true;
2627 m->header->body_size += size;
2628 message_extend_containers(m, size);
2630 return sd_bus_message_close_container(m);
2633 _public_ int sd_bus_message_append_string_memfd(sd_bus_message *m, int memfd) {
2634 _cleanup_close_ int copy_fd = -1;
2635 struct bus_body_part *part;
2636 struct bus_container *c;
2641 assert_return(m, -EINVAL);
2642 assert_return(memfd >= 0, -EINVAL);
2643 assert_return(!m->sealed, -EPERM);
2644 assert_return(!m->poisoned, -ESTALE);
2646 r = memfd_set_sealed(memfd);
2650 copy_fd = dup(memfd);
2654 r = memfd_get_size(memfd, &size);
2658 /* We require this to be NUL terminated */
2662 if (size > (uint64_t) (uint32_t) -1)
2665 c = message_get_container(m);
2666 if (c->signature && c->signature[c->index]) {
2667 /* Container signature is already set */
2669 if (c->signature[c->index] != SD_BUS_TYPE_STRING)
2674 /* Maybe we can append to the signature? But only if this is the top-level container*/
2675 if (c->enclosing != 0)
2678 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRING), NULL);
2685 if (!BUS_MESSAGE_IS_GVARIANT(m)) {
2686 a = message_extend_body(m, 4, 4, false);
2690 *(uint32_t*) a = size - 1;
2693 part = message_append_part(m);
2697 part->memfd = copy_fd;
2698 part->sealed = true;
2702 m->header->body_size += size;
2703 message_extend_containers(m, size);
2705 if (BUS_MESSAGE_IS_GVARIANT(m)) {
2706 r = message_add_offset(m, m->header->body_size);
2713 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2719 _public_ int sd_bus_message_append_strv(sd_bus_message *m, char **l) {
2723 assert_return(m, -EINVAL);
2724 assert_return(!m->sealed, -EPERM);
2725 assert_return(!m->poisoned, -ESTALE);
2727 r = sd_bus_message_open_container(m, 'a', "s");
2731 STRV_FOREACH(i, l) {
2732 r = sd_bus_message_append_basic(m, 's', *i);
2737 return sd_bus_message_close_container(m);
2740 static int bus_message_close_header(sd_bus_message *m) {
2746 if (!BUS_MESSAGE_IS_GVARIANT(m))
2749 if (m->n_header_offsets < 1)
2752 assert(m->header->fields_size == m->header_offsets[m->n_header_offsets-1]);
2754 sz = determine_word_size(m->header->fields_size, m->n_header_offsets);
2756 a = message_extend_fields(m, 1, sz * m->n_header_offsets, false);
2760 for (i = 0; i < m->n_header_offsets; i++)
2761 write_word_le(a + sz*i, sz, m->header_offsets[i]);
2766 int bus_message_seal(sd_bus_message *m, uint64_t cookie, usec_t timeout) {
2767 struct bus_body_part *part;
2777 if (m->n_containers > 0)
2783 /* In vtables the return signature of method calls is listed,
2784 * let's check if they match if this is a response */
2785 if (m->header->type == SD_BUS_MESSAGE_METHOD_RETURN &&
2786 m->enforced_reply_signature &&
2787 !streq(strempty(m->root_container.signature), m->enforced_reply_signature))
2790 /* If gvariant marshalling is used we need to close the body structure */
2791 r = bus_message_close_struct(m, &m->root_container, false);
2795 /* If there's a non-trivial signature set, then add it in here */
2796 if (!isempty(m->root_container.signature)) {
2797 r = message_append_field_signature(m, BUS_MESSAGE_HEADER_SIGNATURE, m->root_container.signature, NULL);
2803 r = message_append_field_uint32(m, BUS_MESSAGE_HEADER_UNIX_FDS, m->n_fds);
2808 r = bus_message_close_header(m);
2812 m->header->serial = (uint32_t) cookie;
2813 m->timeout = m->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED ? 0 : timeout;
2815 /* Add padding at the end of the fields part, since we know
2816 * the body needs to start at an 8 byte alignment. We made
2817 * sure we allocated enough space for this, so all we need to
2818 * do here is to zero it out. */
2819 l = BUS_MESSAGE_FIELDS_SIZE(m);
2822 memzero((uint8_t*) BUS_MESSAGE_FIELDS(m) + l, a);
2824 /* If this is something we can send as memfd, then let's seal
2825 the memfd now. Note that we can send memfds as payload only
2826 for directed messages, and not for broadcasts. */
2827 if (m->destination && m->bus->use_memfd) {
2828 MESSAGE_FOREACH_PART(part, i, m)
2829 if (part->memfd >= 0 && !part->sealed && (part->size > MEMFD_MIN_SIZE || m->bus->use_memfd < 0)) {
2832 /* Try to seal it if that makes
2833 * sense. First, unmap our own map to
2834 * make sure we don't keep it busy. */
2835 bus_body_part_unmap(part);
2837 /* Then, sync up real memfd size */
2839 r = memfd_set_size(part->memfd, sz);
2843 /* Finally, try to seal */
2844 if (memfd_set_sealed(part->memfd) >= 0)
2845 part->sealed = true;
2849 m->root_container.end = BUS_MESSAGE_BODY_SIZE(m);
2850 m->root_container.index = 0;
2851 m->root_container.offset_index = 0;
2852 m->root_container.item_size = m->root_container.n_offsets > 0 ? m->root_container.offsets[0] : 0;
2859 int bus_body_part_map(struct bus_body_part *part) {
2868 if (part->size <= 0)
2871 /* For smaller zero parts (as used for padding) we don't need to map anything... */
2872 if (part->memfd < 0 && part->is_zero && part->size < 8) {
2873 static const uint8_t zeroes[7] = { };
2874 part->data = (void*) zeroes;
2878 psz = PAGE_ALIGN(part->size);
2880 if (part->memfd >= 0)
2881 p = mmap(NULL, psz, PROT_READ, MAP_PRIVATE, part->memfd, 0);
2882 else if (part->is_zero)
2883 p = mmap(NULL, psz, PROT_READ, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
2887 if (p == MAP_FAILED)
2892 part->munmap_this = true;
2897 void bus_body_part_unmap(struct bus_body_part *part) {
2901 if (part->memfd < 0)
2907 if (!part->munmap_this)
2910 assert_se(munmap(part->data, part->mapped) == 0);
2914 part->munmap_this = false;
2919 static int buffer_peek(const void *p, uint32_t sz, size_t *rindex, size_t align, size_t nbytes, void **r) {
2920 size_t k, start, end;
2925 start = ALIGN_TO((size_t) *rindex, align);
2926 end = start + nbytes;
2931 /* Verify that padding is 0 */
2932 for (k = *rindex; k < start; k++)
2933 if (((const uint8_t*) p)[k] != 0)
2937 *r = (uint8_t*) p + start;
2944 static bool message_end_of_signature(sd_bus_message *m) {
2945 struct bus_container *c;
2949 c = message_get_container(m);
2950 return !c->signature || c->signature[c->index] == 0;
2953 static bool message_end_of_array(sd_bus_message *m, size_t index) {
2954 struct bus_container *c;
2958 c = message_get_container(m);
2959 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2962 if (BUS_MESSAGE_IS_GVARIANT(m))
2963 return index >= c->end;
2965 assert(c->array_size);
2966 return index >= c->begin + BUS_MESSAGE_BSWAP32(m, *c->array_size);
2970 _public_ int sd_bus_message_at_end(sd_bus_message *m, int complete) {
2971 assert_return(m, -EINVAL);
2972 assert_return(m->sealed, -EPERM);
2974 if (complete && m->n_containers > 0)
2977 if (message_end_of_signature(m))
2980 if (message_end_of_array(m, m->rindex))
2986 static struct bus_body_part* find_part(sd_bus_message *m, size_t index, size_t sz, void **p) {
2987 struct bus_body_part *part;
2993 if (m->cached_rindex_part && index >= m->cached_rindex_part_begin) {
2994 part = m->cached_rindex_part;
2995 begin = m->cached_rindex_part_begin;
3005 if (index + sz <= begin + part->size) {
3007 r = bus_body_part_map(part);
3012 *p = (uint8_t*) part->data + index - begin;
3014 m->cached_rindex_part = part;
3015 m->cached_rindex_part_begin = begin;
3020 begin += part->size;
3027 static int container_next_item(sd_bus_message *m, struct bus_container *c, size_t *rindex) {
3034 if (!BUS_MESSAGE_IS_GVARIANT(m))
3037 if (c->enclosing == SD_BUS_TYPE_ARRAY) {
3040 sz = bus_gvariant_get_size(c->signature);
3044 if (c->offset_index+1 >= c->n_offsets)
3047 /* Variable-size array */
3049 alignment = bus_gvariant_get_alignment(c->signature);
3050 assert(alignment > 0);
3052 *rindex = ALIGN_TO(c->offsets[c->offset_index], alignment);
3053 c->item_size = c->offsets[c->offset_index+1] - *rindex;
3056 if (c->offset_index+1 >= (c->end-c->begin)/sz)
3059 /* Fixed-size array */
3060 *rindex = c->begin + (c->offset_index+1) * sz;
3066 } else if (c->enclosing == 0 ||
3067 c->enclosing == SD_BUS_TYPE_STRUCT ||
3068 c->enclosing == SD_BUS_TYPE_DICT_ENTRY) {
3073 if (c->offset_index+1 >= c->n_offsets)
3076 r = signature_element_length(c->signature + c->index, &n);
3080 r = signature_element_length(c->signature + c->index + n, &j);
3085 memcpy(t, c->signature + c->index + n, j);
3088 alignment = bus_gvariant_get_alignment(t);
3091 assert(alignment > 0);
3093 *rindex = ALIGN_TO(c->offsets[c->offset_index], alignment);
3094 c->item_size = c->offsets[c->offset_index+1] - *rindex;
3098 } else if (c->enclosing == SD_BUS_TYPE_VARIANT)
3101 assert_not_reached("Unknown container type");
3106 /* Reached the end */
3113 static int message_peek_body(
3120 size_t k, start, end, padding;
3121 struct bus_body_part *part;
3128 start = ALIGN_TO((size_t) *rindex, align);
3129 padding = start - *rindex;
3130 end = start + nbytes;
3132 if (end > BUS_MESSAGE_BODY_SIZE(m))
3135 part = find_part(m, *rindex, padding, (void**) &q);
3140 /* Verify padding */
3141 for (k = 0; k < padding; k++)
3146 part = find_part(m, start, nbytes, (void**) &q);
3147 if (!part || (nbytes > 0 && !q))
3158 static bool validate_nul(const char *s, size_t l) {
3160 /* Check for NUL chars in the string */
3161 if (memchr(s, 0, l))
3164 /* Check for NUL termination */
3171 static bool validate_string(const char *s, size_t l) {
3173 if (!validate_nul(s, l))
3176 /* Check if valid UTF8 */
3177 if (!utf8_is_valid(s))
3183 static bool validate_signature(const char *s, size_t l) {
3185 if (!validate_nul(s, l))
3188 /* Check if valid signature */
3189 if (!signature_is_valid(s, true))
3195 static bool validate_object_path(const char *s, size_t l) {
3197 if (!validate_nul(s, l))
3200 if (!object_path_is_valid(s))
3206 _public_ int sd_bus_message_read_basic(sd_bus_message *m, char type, void *p) {
3207 struct bus_container *c;
3212 assert_return(m, -EINVAL);
3213 assert_return(m->sealed, -EPERM);
3214 assert_return(bus_type_is_basic(type), -EINVAL);
3216 if (message_end_of_signature(m))
3219 if (message_end_of_array(m, m->rindex))
3222 c = message_get_container(m);
3223 if (c->signature[c->index] != type)
3228 if (BUS_MESSAGE_IS_GVARIANT(m)) {
3230 if (IN_SET(type, SD_BUS_TYPE_STRING, SD_BUS_TYPE_OBJECT_PATH, SD_BUS_TYPE_SIGNATURE)) {
3233 r = message_peek_body(m, &rindex, 1, c->item_size, &q);
3237 if (type == SD_BUS_TYPE_STRING)
3238 ok = validate_string(q, c->item_size-1);
3239 else if (type == SD_BUS_TYPE_OBJECT_PATH)
3240 ok = validate_object_path(q, c->item_size-1);
3242 ok = validate_signature(q, c->item_size-1);
3248 *(const char**) p = q;
3252 sz = bus_gvariant_get_size(CHAR_TO_STR(type));
3254 if ((size_t) sz != c->item_size)
3257 align = bus_gvariant_get_alignment(CHAR_TO_STR(type));
3260 r = message_peek_body(m, &rindex, align, c->item_size, &q);
3266 case SD_BUS_TYPE_BYTE:
3268 *(uint8_t*) p = *(uint8_t*) q;
3271 case SD_BUS_TYPE_BOOLEAN:
3273 *(int*) p = !!*(uint8_t*) q;
3276 case SD_BUS_TYPE_INT16:
3277 case SD_BUS_TYPE_UINT16:
3279 *(uint16_t*) p = BUS_MESSAGE_BSWAP16(m, *(uint16_t*) q);
3282 case SD_BUS_TYPE_INT32:
3283 case SD_BUS_TYPE_UINT32:
3285 *(uint32_t*) p = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
3288 case SD_BUS_TYPE_INT64:
3289 case SD_BUS_TYPE_UINT64:
3290 case SD_BUS_TYPE_DOUBLE:
3292 *(uint64_t*) p = BUS_MESSAGE_BSWAP64(m, *(uint64_t*) q);
3295 case SD_BUS_TYPE_UNIX_FD: {
3298 j = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
3303 *(int*) p = m->fds[j];
3309 assert_not_reached("unexpected type");
3313 r = container_next_item(m, c, &rindex);
3320 if (IN_SET(type, SD_BUS_TYPE_STRING, SD_BUS_TYPE_OBJECT_PATH)) {
3324 r = message_peek_body(m, &rindex, 4, 4, &q);
3328 l = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
3329 r = message_peek_body(m, &rindex, 1, l+1, &q);
3333 if (type == SD_BUS_TYPE_OBJECT_PATH)
3334 ok = validate_object_path(q, l);
3336 ok = validate_string(q, l);
3341 *(const char**) p = q;
3343 } else if (type == SD_BUS_TYPE_SIGNATURE) {
3346 r = message_peek_body(m, &rindex, 1, 1, &q);
3351 r = message_peek_body(m, &rindex, 1, l+1, &q);
3355 if (!validate_signature(q, l))
3359 *(const char**) p = q;
3364 align = bus_type_get_alignment(type);
3367 sz = bus_type_get_size(type);
3370 r = message_peek_body(m, &rindex, align, sz, &q);
3376 case SD_BUS_TYPE_BYTE:
3378 *(uint8_t*) p = *(uint8_t*) q;
3381 case SD_BUS_TYPE_BOOLEAN:
3383 *(int*) p = !!*(uint32_t*) q;
3386 case SD_BUS_TYPE_INT16:
3387 case SD_BUS_TYPE_UINT16:
3389 *(uint16_t*) p = BUS_MESSAGE_BSWAP16(m, *(uint16_t*) q);
3392 case SD_BUS_TYPE_INT32:
3393 case SD_BUS_TYPE_UINT32:
3395 *(uint32_t*) p = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
3398 case SD_BUS_TYPE_INT64:
3399 case SD_BUS_TYPE_UINT64:
3400 case SD_BUS_TYPE_DOUBLE:
3402 *(uint64_t*) p = BUS_MESSAGE_BSWAP64(m, *(uint64_t*) q);
3405 case SD_BUS_TYPE_UNIX_FD: {
3408 j = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
3413 *(int*) p = m->fds[j];
3418 assert_not_reached("Unknown basic type...");
3425 if (c->enclosing != SD_BUS_TYPE_ARRAY)
3431 static int bus_message_enter_array(
3433 struct bus_container *c,
3434 const char *contents,
3435 uint32_t **array_size,
3438 size_t *n_offsets) {
3452 if (!signature_is_single(contents, true))
3455 if (!c->signature || c->signature[c->index] == 0)
3458 if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
3461 if (!startswith(c->signature + c->index + 1, contents))
3466 if (!BUS_MESSAGE_IS_GVARIANT(m)) {
3469 r = message_peek_body(m, &rindex, 4, 4, &q);
3473 if (BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q) > BUS_ARRAY_MAX_SIZE)
3476 alignment = bus_type_get_alignment(contents[0]);
3480 r = message_peek_body(m, &rindex, alignment, 0, NULL);
3484 *array_size = (uint32_t*) q;
3486 } else if (c->item_size <= 0) {
3488 /* gvariant: empty array */
3493 } else if (bus_gvariant_is_fixed_size(contents)) {
3495 /* gvariant: fixed length array */
3496 *item_size = bus_gvariant_get_size(contents);
3501 size_t where, p = 0, framing, sz;
3504 /* gvariant: variable length array */
3505 sz = determine_word_size(c->item_size, 0);
3507 where = rindex + c->item_size - sz;
3508 r = message_peek_body(m, &where, 1, sz, &q);
3512 framing = read_word_le(q, sz);
3513 if (framing > c->item_size - sz)
3515 if ((c->item_size - framing) % sz != 0)
3518 *n_offsets = (c->item_size - framing) / sz;
3520 where = rindex + framing;
3521 r = message_peek_body(m, &where, 1, *n_offsets * sz, &q);
3525 *offsets = new(size_t, *n_offsets);
3529 for (i = 0; i < *n_offsets; i++) {
3532 x = read_word_le((uint8_t*) q + i * sz, sz);
3533 if (x > c->item_size - sz)
3538 (*offsets)[i] = rindex + x;
3542 *item_size = (*offsets)[0] - rindex;
3547 if (c->enclosing != SD_BUS_TYPE_ARRAY)
3548 c->index += 1 + strlen(contents);
3553 static int bus_message_enter_variant(
3555 struct bus_container *c,
3556 const char *contents,
3557 size_t *item_size) {
3569 if (!signature_is_single(contents, false))
3572 if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
3575 if (!c->signature || c->signature[c->index] == 0)
3578 if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
3583 if (BUS_MESSAGE_IS_GVARIANT(m)) {
3586 k = strlen(contents);
3587 if (1+k > c->item_size)
3590 where = rindex + c->item_size - (1+k);
3591 r = message_peek_body(m, &where, 1, 1+k, &q);
3595 if (*(char*) q != 0)
3598 if (memcmp((uint8_t*) q+1, contents, k))
3601 *item_size = c->item_size - (1+k);
3604 r = message_peek_body(m, &rindex, 1, 1, &q);
3609 r = message_peek_body(m, &rindex, 1, l+1, &q);
3613 if (!validate_signature(q, l))
3616 if (!streq(q, contents))
3622 if (c->enclosing != SD_BUS_TYPE_ARRAY)
3628 static int build_struct_offsets(
3630 const char *signature,
3634 size_t *n_offsets) {
3636 unsigned n_variable = 0, n_total = 0, v;
3637 size_t previous = 0, where;
3648 if (isempty(signature)) {
3655 sz = determine_word_size(size, 0);
3659 /* First, loop over signature and count variable elements and
3660 * elements in general. We use this to know how large the
3661 * offset array is at the end of the structure. Note that
3662 * GVariant only stores offsets for all variable size elements
3663 * that are not the last item. */
3669 r = signature_element_length(p, &n);
3678 r = bus_gvariant_is_fixed_size(t);
3683 if (r == 0 && p[n] != 0) /* except the last item */
3690 if (size < n_variable * sz)
3693 where = m->rindex + size - (n_variable * sz);
3694 r = message_peek_body(m, &where, 1, n_variable * sz, &q);
3700 *offsets = new(size_t, n_total);
3706 /* Second, loop again and build an offset table */
3712 r = signature_element_length(p, &n);
3721 k = bus_gvariant_get_size(t);
3729 x = read_word_le((uint8_t*) q + v*sz, sz);
3732 if (m->rindex + x < previous)
3735 /* The last item's end
3736 * is determined from
3739 x = size - (n_variable * sz);
3741 offset = m->rindex + x;
3747 align = bus_gvariant_get_alignment(t);
3750 offset = (*n_offsets == 0 ? m->rindex : ALIGN_TO((*offsets)[*n_offsets-1], align)) + k;
3754 previous = (*offsets)[(*n_offsets)++] = offset;
3759 assert(*n_offsets == n_total);
3761 *item_size = (*offsets)[0] - m->rindex;
3765 static int enter_struct_or_dict_entry(
3767 struct bus_container *c,
3768 const char *contents,
3771 size_t *n_offsets) {
3782 if (!BUS_MESSAGE_IS_GVARIANT(m)) {
3785 r = message_peek_body(m, &m->rindex, 8, 0, NULL);
3789 } else if (c->item_size <= 0) {
3791 /* gvariant empty struct */
3796 /* gvariant with contents */
3797 return build_struct_offsets(m, contents, c->item_size, item_size, offsets, n_offsets);
3802 static int bus_message_enter_struct(
3804 struct bus_container *c,
3805 const char *contents,
3808 size_t *n_offsets) {
3820 if (!signature_is_valid(contents, false))
3823 if (!c->signature || c->signature[c->index] == 0)
3826 l = strlen(contents);
3828 if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
3829 !startswith(c->signature + c->index + 1, contents) ||
3830 c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
3833 r = enter_struct_or_dict_entry(m, c, contents, item_size, offsets, n_offsets);
3837 if (c->enclosing != SD_BUS_TYPE_ARRAY)
3838 c->index += 1 + l + 1;
3843 static int bus_message_enter_dict_entry(
3845 struct bus_container *c,
3846 const char *contents,
3849 size_t *n_offsets) {
3858 if (!signature_is_pair(contents))
3861 if (c->enclosing != SD_BUS_TYPE_ARRAY)
3864 if (!c->signature || c->signature[c->index] == 0)
3867 l = strlen(contents);
3869 if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
3870 !startswith(c->signature + c->index + 1, contents) ||
3871 c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
3874 r = enter_struct_or_dict_entry(m, c, contents, item_size, offsets, n_offsets);
3878 if (c->enclosing != SD_BUS_TYPE_ARRAY)
3879 c->index += 1 + l + 1;
3884 _public_ int sd_bus_message_enter_container(sd_bus_message *m,
3886 const char *contents) {
3887 struct bus_container *c, *w;
3888 uint32_t *array_size = NULL;
3891 size_t *offsets = NULL;
3892 size_t n_offsets = 0, item_size = 0;
3895 assert_return(m, -EINVAL);
3896 assert_return(m->sealed, -EPERM);
3897 assert_return(type != 0 || !contents, -EINVAL);
3899 if (type == 0 || !contents) {
3903 /* Allow entering into anonymous containers */
3904 r = sd_bus_message_peek_type(m, &tt, &cc);
3908 if (type != 0 && type != tt)
3911 if (contents && !streq(contents, cc))
3919 * We enforce a global limit on container depth, that is much
3920 * higher than the 32 structs and 32 arrays the specification
3921 * mandates. This is simpler to implement for us, and we need
3922 * this only to ensure our container array doesn't grow
3923 * without bounds. We are happy to return any data from a
3924 * message as long as the data itself is valid, even if the
3925 * overall message might be not.
3927 * Note that the message signature is validated when
3928 * parsing the headers, and that validation does check the
3931 * Note that the specification defines no limits on the depth
3932 * of stacked variants, but we do.
3934 if (m->n_containers >= BUS_CONTAINER_DEPTH)
3937 if (!GREEDY_REALLOC(m->containers, m->containers_allocated, m->n_containers + 1))
3940 if (message_end_of_signature(m))
3943 if (message_end_of_array(m, m->rindex))
3946 c = message_get_container(m);
3948 signature = strdup(contents);
3952 c->saved_index = c->index;
3955 if (type == SD_BUS_TYPE_ARRAY)
3956 r = bus_message_enter_array(m, c, contents, &array_size, &item_size, &offsets, &n_offsets);
3957 else if (type == SD_BUS_TYPE_VARIANT)
3958 r = bus_message_enter_variant(m, c, contents, &item_size);
3959 else if (type == SD_BUS_TYPE_STRUCT)
3960 r = bus_message_enter_struct(m, c, contents, &item_size, &offsets, &n_offsets);
3961 else if (type == SD_BUS_TYPE_DICT_ENTRY)
3962 r = bus_message_enter_dict_entry(m, c, contents, &item_size, &offsets, &n_offsets);
3972 /* OK, let's fill it in */
3973 w = m->containers + m->n_containers++;
3974 w->enclosing = type;
3975 w->signature = signature;
3976 w->peeked_signature = NULL;
3980 w->begin = m->rindex;
3981 w->end = m->rindex + c->item_size;
3983 w->array_size = array_size;
3984 w->item_size = item_size;
3985 w->offsets = offsets;
3986 w->n_offsets = n_offsets;
3987 w->offset_index = 0;
3992 _public_ int sd_bus_message_exit_container(sd_bus_message *m) {
3993 struct bus_container *c;
3997 assert_return(m, -EINVAL);
3998 assert_return(m->sealed, -EPERM);
3999 assert_return(m->n_containers > 0, -ENXIO);
4001 c = message_get_container(m);
4003 if (c->enclosing != SD_BUS_TYPE_ARRAY) {
4004 if (c->signature && c->signature[c->index] != 0)
4008 if (BUS_MESSAGE_IS_GVARIANT(m)) {
4009 if (m->rindex < c->end)
4012 } else if (c->enclosing == SD_BUS_TYPE_ARRAY) {
4015 l = BUS_MESSAGE_BSWAP32(m, *c->array_size);
4016 if (c->begin + l != m->rindex)
4021 free(c->peeked_signature);
4025 c = message_get_container(m);
4028 c->index = c->saved_index;
4029 r = container_next_item(m, c, &m->rindex);
4037 static void message_quit_container(sd_bus_message *m) {
4038 struct bus_container *c;
4042 assert(m->n_containers > 0);
4044 c = message_get_container(m);
4047 assert(m->rindex >= c->before);
4048 m->rindex = c->before;
4050 /* Free container */
4055 /* Correct index of new top-level container */
4056 c = message_get_container(m);
4057 c->index = c->saved_index;
4060 _public_ int sd_bus_message_peek_type(sd_bus_message *m, char *type, const char **contents) {
4061 struct bus_container *c;
4064 assert_return(m, -EINVAL);
4065 assert_return(m->sealed, -EPERM);
4067 if (message_end_of_signature(m))
4070 if (message_end_of_array(m, m->rindex))
4073 c = message_get_container(m);
4075 if (bus_type_is_basic(c->signature[c->index])) {
4079 *type = c->signature[c->index];
4083 if (c->signature[c->index] == SD_BUS_TYPE_ARRAY) {
4089 r = signature_element_length(c->signature+c->index+1, &l);
4095 sig = strndup(c->signature + c->index + 1, l);
4099 free(c->peeked_signature);
4100 *contents = c->peeked_signature = sig;
4104 *type = SD_BUS_TYPE_ARRAY;
4109 if (c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ||
4110 c->signature[c->index] == SD_BUS_TYPE_DICT_ENTRY_BEGIN) {
4116 r = signature_element_length(c->signature+c->index, &l);
4121 sig = strndup(c->signature + c->index + 1, l - 2);
4125 free(c->peeked_signature);
4126 *contents = c->peeked_signature = sig;
4130 *type = c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY;
4135 if (c->signature[c->index] == SD_BUS_TYPE_VARIANT) {
4139 if (BUS_MESSAGE_IS_GVARIANT(m)) {
4142 if (c->item_size < 2)
4145 /* Look for the NUL delimiter that
4146 separates the payload from the
4147 signature. Since the body might be
4148 in a different part that then the
4149 signature we map byte by byte. */
4151 for (k = 2; k <= c->item_size; k++) {
4154 where = m->rindex + c->item_size - k;
4155 r = message_peek_body(m, &where, 1, k, &q);
4159 if (*(char*) q == 0)
4163 if (k > c->item_size)
4166 free(c->peeked_signature);
4167 c->peeked_signature = strndup((char*) q + 1, k - 1);
4168 if (!c->peeked_signature)
4171 if (!signature_is_valid(c->peeked_signature, true))
4174 *contents = c->peeked_signature;
4179 r = message_peek_body(m, &rindex, 1, 1, &q);
4184 r = message_peek_body(m, &rindex, 1, l+1, &q);
4188 if (!validate_signature(q, l))
4196 *type = SD_BUS_TYPE_VARIANT;
4211 _public_ int sd_bus_message_rewind(sd_bus_message *m, int complete) {
4212 struct bus_container *c;
4214 assert_return(m, -EINVAL);
4215 assert_return(m->sealed, -EPERM);
4218 message_reset_containers(m);
4221 c = message_get_container(m);
4223 c = message_get_container(m);
4225 c->offset_index = 0;
4227 m->rindex = c->begin;
4230 c->offset_index = 0;
4231 c->item_size = (c->n_offsets > 0 ? c->offsets[0] : c->end) - c->begin;
4233 return !isempty(c->signature);
4236 static int message_read_ap(
4241 unsigned n_array, n_struct;
4242 TypeStack stack[BUS_CONTAINER_DEPTH];
4243 unsigned stack_ptr = 0;
4244 unsigned n_loop = 0;
4252 /* Ideally, we'd just call ourselves recursively on every
4253 * complex type. However, the state of a va_list that is
4254 * passed to a function is undefined after that function
4255 * returns. This means we need to docode the va_list linearly
4256 * in a single stackframe. We hence implement our own
4257 * home-grown stack in an array. */
4259 n_array = (unsigned) -1; /* length of current array entries */
4260 n_struct = strlen(types); /* length of current struct contents signature */
4267 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
4268 r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
4274 r = sd_bus_message_exit_container(m);
4282 if (n_array != (unsigned) -1)
4291 case SD_BUS_TYPE_BYTE:
4292 case SD_BUS_TYPE_BOOLEAN:
4293 case SD_BUS_TYPE_INT16:
4294 case SD_BUS_TYPE_UINT16:
4295 case SD_BUS_TYPE_INT32:
4296 case SD_BUS_TYPE_UINT32:
4297 case SD_BUS_TYPE_INT64:
4298 case SD_BUS_TYPE_UINT64:
4299 case SD_BUS_TYPE_DOUBLE:
4300 case SD_BUS_TYPE_STRING:
4301 case SD_BUS_TYPE_OBJECT_PATH:
4302 case SD_BUS_TYPE_SIGNATURE:
4303 case SD_BUS_TYPE_UNIX_FD: {
4306 p = va_arg(ap, void*);
4307 r = sd_bus_message_read_basic(m, *t, p);
4320 case SD_BUS_TYPE_ARRAY: {
4323 r = signature_element_length(t + 1, &k);
4329 memcpy(s, t + 1, k);
4332 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, s);
4343 if (n_array == (unsigned) -1) {
4348 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
4354 n_array = va_arg(ap, unsigned);
4359 case SD_BUS_TYPE_VARIANT: {
4362 s = va_arg(ap, const char *);
4366 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, s);
4376 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
4381 n_struct = strlen(s);
4382 n_array = (unsigned) -1;
4387 case SD_BUS_TYPE_STRUCT_BEGIN:
4388 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
4391 r = signature_element_length(t, &k);
4397 memcpy(s, t + 1, k - 2);
4400 r = sd_bus_message_enter_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
4410 if (n_array == (unsigned) -1) {
4415 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
4421 n_array = (unsigned) -1;
4434 _public_ int sd_bus_message_read(sd_bus_message *m, const char *types, ...) {
4438 assert_return(m, -EINVAL);
4439 assert_return(m->sealed, -EPERM);
4440 assert_return(types, -EINVAL);
4442 va_start(ap, types);
4443 r = message_read_ap(m, types, ap);
4449 _public_ int sd_bus_message_skip(sd_bus_message *m, const char *types) {
4452 assert_return(m, -EINVAL);
4453 assert_return(m->sealed, -EPERM);
4455 /* If types is NULL, read exactly one element */
4457 struct bus_container *c;
4460 if (message_end_of_signature(m))
4463 if (message_end_of_array(m, m->rindex))
4466 c = message_get_container(m);
4468 r = signature_element_length(c->signature + c->index, &l);
4472 types = strndupa(c->signature + c->index, l);
4477 case 0: /* Nothing to drop */
4480 case SD_BUS_TYPE_BYTE:
4481 case SD_BUS_TYPE_BOOLEAN:
4482 case SD_BUS_TYPE_INT16:
4483 case SD_BUS_TYPE_UINT16:
4484 case SD_BUS_TYPE_INT32:
4485 case SD_BUS_TYPE_UINT32:
4486 case SD_BUS_TYPE_INT64:
4487 case SD_BUS_TYPE_UINT64:
4488 case SD_BUS_TYPE_DOUBLE:
4489 case SD_BUS_TYPE_STRING:
4490 case SD_BUS_TYPE_OBJECT_PATH:
4491 case SD_BUS_TYPE_SIGNATURE:
4492 case SD_BUS_TYPE_UNIX_FD:
4494 r = sd_bus_message_read_basic(m, *types, NULL);
4498 r = sd_bus_message_skip(m, types + 1);
4504 case SD_BUS_TYPE_ARRAY: {
4507 r = signature_element_length(types + 1, &k);
4513 memcpy(s, types+1, k);
4516 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, s);
4521 r = sd_bus_message_skip(m, s);
4528 r = sd_bus_message_exit_container(m);
4533 r = sd_bus_message_skip(m, types + 1 + k);
4540 case SD_BUS_TYPE_VARIANT: {
4541 const char *contents;
4544 r = sd_bus_message_peek_type(m, &x, &contents);
4548 if (x != SD_BUS_TYPE_VARIANT)
4551 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, contents);
4555 r = sd_bus_message_skip(m, contents);
4560 r = sd_bus_message_exit_container(m);
4564 r = sd_bus_message_skip(m, types + 1);
4571 case SD_BUS_TYPE_STRUCT_BEGIN:
4572 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
4575 r = signature_element_length(types, &k);
4581 memcpy(s, types+1, k-2);
4584 r = sd_bus_message_enter_container(m, *types == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
4588 r = sd_bus_message_skip(m, s);
4593 r = sd_bus_message_exit_container(m);
4598 r = sd_bus_message_skip(m, types + k);
4610 _public_ int sd_bus_message_read_array(sd_bus_message *m,
4614 struct bus_container *c;
4620 assert_return(m, -EINVAL);
4621 assert_return(m->sealed, -EPERM);
4622 assert_return(bus_type_is_trivial(type), -EINVAL);
4623 assert_return(ptr, -EINVAL);
4624 assert_return(size, -EINVAL);
4625 assert_return(!BUS_MESSAGE_NEED_BSWAP(m), -ENOTSUP);
4627 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
4631 c = message_get_container(m);
4633 if (BUS_MESSAGE_IS_GVARIANT(m)) {
4634 align = bus_gvariant_get_alignment(CHAR_TO_STR(type));
4638 sz = c->end - c->begin;
4640 align = bus_type_get_alignment(type);
4644 sz = BUS_MESSAGE_BSWAP32(m, *c->array_size);
4648 /* Zero length array, let's return some aligned
4649 * pointer that is not NULL */
4650 p = (uint8_t*) NULL + align;
4652 r = message_peek_body(m, &m->rindex, align, sz, &p);
4657 r = sd_bus_message_exit_container(m);
4661 *ptr = (const void*) p;
4667 message_quit_container(m);
4671 static int message_peek_fields(
4682 return buffer_peek(BUS_MESSAGE_FIELDS(m), BUS_MESSAGE_FIELDS_SIZE(m), rindex, align, nbytes, ret);
4685 static int message_peek_field_uint32(
4697 if (BUS_MESSAGE_IS_GVARIANT(m) && item_size != 4)
4700 /* identical for gvariant and dbus1 */
4702 r = message_peek_fields(m, ri, 4, 4, &q);
4707 *ret = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
4712 static int message_peek_field_string(
4714 bool (*validate)(const char *p),
4726 if (BUS_MESSAGE_IS_GVARIANT(m)) {
4731 r = message_peek_fields(m, ri, 1, item_size, &q);
4737 r = message_peek_field_uint32(m, ri, 4, &l);
4741 r = message_peek_fields(m, ri, 1, l+1, &q);
4747 if (!validate_nul(q, l))
4753 if (!validate_string(q, l))
4763 static int message_peek_field_signature(
4776 if (BUS_MESSAGE_IS_GVARIANT(m)) {
4781 r = message_peek_fields(m, ri, 1, item_size, &q);
4787 r = message_peek_fields(m, ri, 1, 1, &q);
4792 r = message_peek_fields(m, ri, 1, l+1, &q);
4797 if (!validate_signature(q, l))
4806 static int message_skip_fields(
4809 uint32_t array_size,
4810 const char **signature) {
4812 size_t original_index;
4818 assert(!BUS_MESSAGE_IS_GVARIANT(m));
4820 original_index = *ri;
4826 if (array_size != (uint32_t) -1 &&
4827 array_size <= *ri - original_index)
4834 if (t == SD_BUS_TYPE_STRING) {
4836 r = message_peek_field_string(m, NULL, ri, 0, NULL);
4842 } else if (t == SD_BUS_TYPE_OBJECT_PATH) {
4844 r = message_peek_field_string(m, object_path_is_valid, ri, 0, NULL);
4850 } else if (t == SD_BUS_TYPE_SIGNATURE) {
4852 r = message_peek_field_signature(m, ri, 0, NULL);
4858 } else if (bus_type_is_basic(t)) {
4861 align = bus_type_get_alignment(t);
4862 k = bus_type_get_size(t);
4863 assert(align > 0 && k > 0);
4865 r = message_peek_fields(m, ri, align, k, NULL);
4871 } else if (t == SD_BUS_TYPE_ARRAY) {
4873 r = signature_element_length(*signature+1, &l);
4883 strncpy(sig, *signature + 1, l-1);
4886 alignment = bus_type_get_alignment(sig[0]);
4890 r = message_peek_field_uint32(m, ri, 0, &nas);
4893 if (nas > BUS_ARRAY_MAX_SIZE)
4896 r = message_peek_fields(m, ri, alignment, 0, NULL);
4900 r = message_skip_fields(m, ri, nas, (const char**) &s);
4905 (*signature) += 1 + l;
4907 } else if (t == SD_BUS_TYPE_VARIANT) {
4910 r = message_peek_field_signature(m, ri, 0, &s);
4914 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
4920 } else if (t == SD_BUS_TYPE_STRUCT ||
4921 t == SD_BUS_TYPE_DICT_ENTRY) {
4923 r = signature_element_length(*signature, &l);
4930 strncpy(sig, *signature + 1, l-1);
4933 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
4944 int bus_message_parse_fields(sd_bus_message *m) {
4947 uint32_t unix_fds = 0;
4948 bool unix_fds_set = false;
4949 void *offsets = NULL;
4950 unsigned n_offsets = 0;
4956 if (BUS_MESSAGE_IS_GVARIANT(m)) {
4959 sz = determine_word_size(BUS_MESSAGE_FIELDS_SIZE(m), 0);
4963 ri = BUS_MESSAGE_FIELDS_SIZE(m) - sz;
4964 r = message_peek_fields(m, &ri, 1, sz, &q);
4968 framing = read_word_le(q, sz);
4969 if (framing >= BUS_MESSAGE_FIELDS_SIZE(m) - sz)
4971 if ((BUS_MESSAGE_FIELDS_SIZE(m) - framing) % sz != 0)
4975 r = message_peek_fields(m, &ri, 1, BUS_MESSAGE_FIELDS_SIZE(m) - framing, &offsets);
4979 n_offsets = (BUS_MESSAGE_FIELDS_SIZE(m) - framing) / sz;
4984 while (ri < BUS_MESSAGE_FIELDS_SIZE(m)) {
4985 _cleanup_free_ char *sig = NULL;
4986 const char *signature;
4988 size_t item_size = (size_t) -1;
4990 if (BUS_MESSAGE_IS_GVARIANT(m)) {
4997 ri = ALIGN_TO(read_word_le((uint8_t*) offsets + (i-1)*sz, sz), 8);
5000 r = message_peek_fields(m, &ri, 8, 1, (void**) &header);
5004 if (BUS_MESSAGE_IS_GVARIANT(m)) {
5009 end = read_word_le((uint8_t*) offsets + i*sz, sz);
5014 where = ri = ALIGN_TO(ri, 8);
5015 item_size = end - ri;
5016 r = message_peek_fields(m, &where, 1, item_size, &q);
5020 b = memrchr(q, 0, item_size);
5024 sig = strndup(b+1, item_size - (b+1-(char*) q));
5029 item_size = b - (char*) q;
5031 r = message_peek_field_signature(m, &ri, 0, &signature);
5037 case _BUS_MESSAGE_HEADER_INVALID:
5040 case BUS_MESSAGE_HEADER_PATH:
5045 if (!streq(signature, "o"))
5048 r = message_peek_field_string(m, object_path_is_valid, &ri, item_size, &m->path);
5051 case BUS_MESSAGE_HEADER_INTERFACE:
5056 if (!streq(signature, "s"))
5059 r = message_peek_field_string(m, interface_name_is_valid, &ri, item_size, &m->interface);
5062 case BUS_MESSAGE_HEADER_MEMBER:
5067 if (!streq(signature, "s"))
5070 r = message_peek_field_string(m, member_name_is_valid, &ri, item_size, &m->member);
5073 case BUS_MESSAGE_HEADER_ERROR_NAME:
5078 if (!streq(signature, "s"))
5081 r = message_peek_field_string(m, error_name_is_valid, &ri, item_size, &m->error.name);
5083 m->error._need_free = -1;
5087 case BUS_MESSAGE_HEADER_DESTINATION:
5092 if (!streq(signature, "s"))
5095 r = message_peek_field_string(m, service_name_is_valid, &ri, item_size, &m->destination);
5098 case BUS_MESSAGE_HEADER_SENDER:
5103 if (!streq(signature, "s"))
5106 r = message_peek_field_string(m, service_name_is_valid, &ri, item_size, &m->sender);
5108 if (r >= 0 && m->sender[0] == ':' && m->bus->bus_client && !m->bus->is_kernel) {
5109 m->creds.unique_name = (char*) m->sender;
5110 m->creds.mask |= SD_BUS_CREDS_UNIQUE_NAME & m->bus->creds_mask;
5116 case BUS_MESSAGE_HEADER_SIGNATURE: {
5120 if (m->root_container.signature)
5123 if (!streq(signature, "g"))
5126 r = message_peek_field_signature(m, &ri, item_size, &s);
5134 free(m->root_container.signature);
5135 m->root_container.signature = c;
5139 case BUS_MESSAGE_HEADER_REPLY_SERIAL: {
5142 if (m->reply_cookie != 0)
5145 if (!streq(signature, "u"))
5148 r = message_peek_field_uint32(m, &ri, item_size, &serial);
5152 m->reply_cookie = serial;
5154 if (m->reply_cookie == 0)
5160 case BUS_MESSAGE_HEADER_UNIX_FDS:
5164 if (!streq(signature, "u"))
5167 r = message_peek_field_uint32(m, &ri, item_size, &unix_fds);
5171 unix_fds_set = true;
5175 if (!BUS_MESSAGE_IS_GVARIANT(m))
5176 r = message_skip_fields(m, &ri, (uint32_t) -1, (const char **) &signature);
5185 if (m->n_fds != unix_fds)
5188 switch (m->header->type) {
5190 case SD_BUS_MESSAGE_SIGNAL:
5191 if (!m->path || !m->interface || !m->member)
5194 if (m->reply_cookie != 0)
5199 case SD_BUS_MESSAGE_METHOD_CALL:
5201 if (!m->path || !m->member)
5204 if (m->reply_cookie != 0)
5209 case SD_BUS_MESSAGE_METHOD_RETURN:
5211 if (m->reply_cookie == 0)
5215 case SD_BUS_MESSAGE_METHOD_ERROR:
5217 if (m->reply_cookie == 0 || !m->error.name)
5222 /* Refuse non-local messages that claim they are local */
5223 if (streq_ptr(m->path, "/org/freedesktop/DBus/Local"))
5225 if (streq_ptr(m->interface, "org.freedesktop.DBus.Local"))
5227 if (streq_ptr(m->sender, "org.freedesktop.DBus.Local"))
5230 m->root_container.end = BUS_MESSAGE_BODY_SIZE(m);
5232 if (BUS_MESSAGE_IS_GVARIANT(m)) {
5233 r = build_struct_offsets(
5235 m->root_container.signature,
5236 BUS_MESSAGE_BODY_SIZE(m),
5237 &m->root_container.item_size,
5238 &m->root_container.offsets,
5239 &m->root_container.n_offsets);
5244 /* Try to read the error message, but if we can't it's a non-issue */
5245 if (m->header->type == SD_BUS_MESSAGE_METHOD_ERROR)
5246 sd_bus_message_read(m, "s", &m->error.message);
5251 _public_ int sd_bus_message_set_destination(sd_bus_message *m, const char *destination) {
5252 assert_return(m, -EINVAL);
5253 assert_return(destination, -EINVAL);
5254 assert_return(!m->sealed, -EPERM);
5255 assert_return(!m->destination, -EEXIST);
5257 return message_append_field_string(m, BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &m->destination);
5260 int bus_message_get_blob(sd_bus_message *m, void **buffer, size_t *sz) {
5264 struct bus_body_part *part;
5270 total = BUS_MESSAGE_SIZE(m);
5276 e = mempcpy(p, m->header, BUS_MESSAGE_BODY_BEGIN(m));
5277 MESSAGE_FOREACH_PART(part, i, m)
5278 e = mempcpy(e, part->data, part->size);
5280 assert(total == (size_t) ((uint8_t*) e - (uint8_t*) p));
5288 int bus_message_read_strv_extend(sd_bus_message *m, char ***l) {
5294 r = sd_bus_message_enter_container(m, 'a', "s");
5301 r = sd_bus_message_read_basic(m, 's', &s);
5307 r = strv_extend(l, s);
5312 r = sd_bus_message_exit_container(m);
5319 _public_ int sd_bus_message_read_strv(sd_bus_message *m, char ***l) {
5323 assert_return(m, -EINVAL);
5324 assert_return(m->sealed, -EPERM);
5325 assert_return(l, -EINVAL);
5327 r = bus_message_read_strv_extend(m, &strv);
5337 int bus_message_get_arg(sd_bus_message *m, unsigned i, const char **str, char ***strv) {
5338 const char *contents;
5347 r = sd_bus_message_rewind(m, true);
5352 r = sd_bus_message_peek_type(m, &type, &contents);
5358 /* Don't match against arguments after the first one we don't understand */
5359 if (!IN_SET(type, SD_BUS_TYPE_STRING, SD_BUS_TYPE_OBJECT_PATH, SD_BUS_TYPE_SIGNATURE) &&
5360 !(type == SD_BUS_TYPE_ARRAY && STR_IN_SET(contents, "s", "o", "g")))
5366 r = sd_bus_message_skip(m, NULL);
5371 if (type == SD_BUS_TYPE_ARRAY) {
5373 r = sd_bus_message_read_strv(m, strv);
5380 r = sd_bus_message_read_basic(m, type, str);
5390 bool bus_header_is_complete(struct bus_header *h, size_t size) {
5396 if (size < sizeof(struct bus_header))
5399 full = sizeof(struct bus_header) +
5400 (h->endian == BUS_NATIVE_ENDIAN ? h->fields_size : bswap_32(h->fields_size));
5402 return size >= full;
5405 int bus_header_message_size(struct bus_header *h, size_t *sum) {
5411 if (h->endian == BUS_NATIVE_ENDIAN) {
5412 fs = h->fields_size;
5414 } else if (h->endian == BUS_REVERSE_ENDIAN) {
5415 fs = bswap_32(h->fields_size);
5416 bs = bswap_32(h->body_size);
5420 *sum = sizeof(struct bus_header) + ALIGN8(fs) + bs;
5424 _public_ int sd_bus_message_get_errno(sd_bus_message *m) {
5425 assert_return(m, EINVAL);
5427 if (m->header->type != SD_BUS_MESSAGE_METHOD_ERROR)
5430 return sd_bus_error_get_errno(&m->error);
5433 _public_ const char* sd_bus_message_get_signature(sd_bus_message *m, int complete) {
5434 struct bus_container *c;
5436 assert_return(m, NULL);
5438 c = complete ? &m->root_container : message_get_container(m);
5439 return strempty(c->signature);
5442 _public_ int sd_bus_message_is_empty(sd_bus_message *m) {
5443 assert_return(m, -EINVAL);
5445 return isempty(m->root_container.signature);
5448 _public_ int sd_bus_message_has_signature(sd_bus_message *m, const char *signature) {
5449 assert_return(m, -EINVAL);
5451 return streq(strempty(m->root_container.signature), strempty(signature));
5454 _public_ int sd_bus_message_copy(sd_bus_message *m, sd_bus_message *source, int all) {
5455 bool done_something = false;
5458 assert_return(m, -EINVAL);
5459 assert_return(source, -EINVAL);
5460 assert_return(!m->sealed, -EPERM);
5461 assert_return(source->sealed, -EPERM);
5464 const char *contents;
5479 r = sd_bus_message_peek_type(source, &type, &contents);
5485 done_something = true;
5487 if (bus_type_is_container(type) > 0) {
5489 r = sd_bus_message_enter_container(source, type, contents);
5493 r = sd_bus_message_open_container(m, type, contents);
5497 r = sd_bus_message_copy(m, source, true);
5501 r = sd_bus_message_close_container(m);
5505 r = sd_bus_message_exit_container(source);
5512 r = sd_bus_message_read_basic(source, type, &basic);
5518 if (type == SD_BUS_TYPE_OBJECT_PATH ||
5519 type == SD_BUS_TYPE_SIGNATURE ||
5520 type == SD_BUS_TYPE_STRING)
5521 r = sd_bus_message_append_basic(m, type, basic.string);
5523 r = sd_bus_message_append_basic(m, type, &basic);
5530 return done_something;
5533 _public_ int sd_bus_message_verify_type(sd_bus_message *m, char type, const char *contents) {
5538 assert_return(m, -EINVAL);
5539 assert_return(m->sealed, -EPERM);
5540 assert_return(!type || bus_type_is_valid(type), -EINVAL);
5541 assert_return(!contents || signature_is_valid(contents, true), -EINVAL);
5542 assert_return(type || contents, -EINVAL);
5543 assert_return(!contents || !type || bus_type_is_container(type), -EINVAL);
5545 r = sd_bus_message_peek_type(m, &t, &c);
5549 if (type != 0 && type != t)
5552 if (contents && !streq_ptr(contents, c))
5558 _public_ sd_bus *sd_bus_message_get_bus(sd_bus_message *m) {
5559 assert_return(m, NULL);
5564 int bus_message_remarshal(sd_bus *bus, sd_bus_message **m) {
5565 _cleanup_bus_message_unref_ sd_bus_message *n = NULL;
5573 switch ((*m)->header->type) {
5575 case SD_BUS_MESSAGE_SIGNAL:
5576 r = sd_bus_message_new_signal(bus, &n, (*m)->path, (*m)->interface, (*m)->member);
5582 case SD_BUS_MESSAGE_METHOD_CALL:
5583 r = sd_bus_message_new_method_call(bus, &n, (*m)->destination, (*m)->path, (*m)->interface, (*m)->member);
5589 case SD_BUS_MESSAGE_METHOD_RETURN:
5590 case SD_BUS_MESSAGE_METHOD_ERROR:
5592 n = message_new(bus, (*m)->header->type);
5596 n->reply_cookie = (*m)->reply_cookie;
5597 r = message_append_field_uint32(n, BUS_MESSAGE_HEADER_REPLY_SERIAL, (uint32_t) n->reply_cookie);
5601 if ((*m)->header->type == SD_BUS_MESSAGE_METHOD_ERROR && (*m)->error.name) {
5602 r = message_append_field_string(n, BUS_MESSAGE_HEADER_ERROR_NAME, SD_BUS_TYPE_STRING, (*m)->error.name, &n->error.message);
5606 n->error._need_free = -1;
5615 if ((*m)->destination && !n->destination) {
5616 r = message_append_field_string(n, BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, (*m)->destination, &n->destination);
5621 if ((*m)->sender && !n->sender) {
5622 r = message_append_field_string(n, BUS_MESSAGE_HEADER_SENDER, SD_BUS_TYPE_STRING, (*m)->sender, &n->sender);
5627 n->header->flags |= (*m)->header->flags & (BUS_MESSAGE_NO_REPLY_EXPECTED|BUS_MESSAGE_NO_AUTO_START);
5629 r = sd_bus_message_copy(n, *m, true);
5633 timeout = (*m)->timeout;
5634 if (timeout == 0 && !((*m)->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED))
5635 timeout = BUS_DEFAULT_TIMEOUT;
5637 r = bus_message_seal(n, BUS_MESSAGE_COOKIE(*m), timeout);
5641 sd_bus_message_unref(*m);
5648 int bus_message_append_sender(sd_bus_message *m, const char *sender) {
5652 assert_return(!m->sealed, -EPERM);
5653 assert_return(!m->sender, -EPERM);
5655 return message_append_field_string(m, BUS_MESSAGE_HEADER_SENDER, SD_BUS_TYPE_STRING, sender, &m->sender);
5658 _public_ int sd_bus_message_get_priority(sd_bus_message *m, int64_t *priority) {
5659 assert_return(m, -EINVAL);
5660 assert_return(priority, -EINVAL);
5662 *priority = m->priority;
5666 _public_ int sd_bus_message_set_priority(sd_bus_message *m, int64_t priority) {
5667 assert_return(m, -EINVAL);
5668 assert_return(!m->sealed, -EPERM);
5670 m->priority = priority;