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) {
2067 if (!BUS_MESSAGE_IS_GVARIANT(m))
2070 l = strlen(c->signature);
2072 a = message_extend_body(m, 1, 1 + l, true);
2077 memcpy(a+1, c->signature, l);
2082 static int bus_message_close_struct(sd_bus_message *m, struct bus_container *c, bool add_offset) {
2083 size_t n_variable = 0;
2092 if (!BUS_MESSAGE_IS_GVARIANT(m))
2095 p = strempty(c->signature);
2099 r = signature_element_length(p, &n);
2108 r = bus_gvariant_is_fixed_size(t);
2113 assert(!c->need_offsets || i <= c->n_offsets);
2115 /* We need to add an offset for each item that has a
2116 * variable size and that is not the last one in the
2118 if (r == 0 && p[n] != 0)
2125 assert(!c->need_offsets || i == c->n_offsets);
2126 assert(c->need_offsets || n_variable == 0);
2128 if (n_variable <= 0) {
2129 a = message_extend_body(m, 1, 0, add_offset);
2136 assert(c->offsets[c->n_offsets-1] == m->header->body_size);
2138 sz = determine_word_size(m->header->body_size - c->begin, n_variable);
2140 a = message_extend_body(m, 1, sz * n_variable, add_offset);
2144 p = strempty(c->signature);
2145 for (i = 0, j = 0; i < c->n_offsets; i++) {
2149 r = signature_element_length(p, &n);
2160 r = bus_gvariant_is_fixed_size(t);
2163 if (r > 0 || p[0] == 0)
2167 k = n_variable - 1 - j;
2169 write_word_le(a + k * sz, sz, c->offsets[i] - c->begin);
2178 _public_ int sd_bus_message_close_container(sd_bus_message *m) {
2179 struct bus_container *c;
2182 assert_return(m, -EINVAL);
2183 assert_return(!m->sealed, -EPERM);
2184 assert_return(m->n_containers > 0, -EINVAL);
2185 assert_return(!m->poisoned, -ESTALE);
2187 c = message_get_container(m);
2189 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2190 if (c->signature && c->signature[c->index] != 0)
2195 if (c->enclosing == SD_BUS_TYPE_ARRAY)
2196 r = bus_message_close_array(m, c);
2197 else if (c->enclosing == SD_BUS_TYPE_VARIANT)
2198 r = bus_message_close_variant(m, c);
2199 else if (c->enclosing == SD_BUS_TYPE_STRUCT || c->enclosing == SD_BUS_TYPE_DICT_ENTRY)
2200 r = bus_message_close_struct(m, c, true);
2202 assert_not_reached("Unknown container type");
2216 static int type_stack_push(TypeStack *stack, unsigned max, unsigned *i, const char *types, unsigned n_struct, unsigned n_array) {
2223 stack[*i].types = types;
2224 stack[*i].n_struct = n_struct;
2225 stack[*i].n_array = n_array;
2231 static int type_stack_pop(TypeStack *stack, unsigned max, unsigned *i, const char **types, unsigned *n_struct, unsigned *n_array) {
2242 *types = stack[*i].types;
2243 *n_struct = stack[*i].n_struct;
2244 *n_array = stack[*i].n_array;
2249 int bus_message_append_ap(
2254 unsigned n_array, n_struct;
2255 TypeStack stack[BUS_CONTAINER_DEPTH];
2256 unsigned stack_ptr = 0;
2264 n_array = (unsigned) -1;
2265 n_struct = strlen(types);
2270 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
2271 r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
2277 r = sd_bus_message_close_container(m);
2285 if (n_array != (unsigned) -1)
2294 case SD_BUS_TYPE_BYTE: {
2297 x = (uint8_t) va_arg(ap, int);
2298 r = sd_bus_message_append_basic(m, *t, &x);
2302 case SD_BUS_TYPE_BOOLEAN:
2303 case SD_BUS_TYPE_INT32:
2304 case SD_BUS_TYPE_UINT32:
2305 case SD_BUS_TYPE_UNIX_FD: {
2308 /* We assume a boolean is the same as int32_t */
2309 assert_cc(sizeof(int32_t) == sizeof(int));
2311 x = va_arg(ap, uint32_t);
2312 r = sd_bus_message_append_basic(m, *t, &x);
2316 case SD_BUS_TYPE_INT16:
2317 case SD_BUS_TYPE_UINT16: {
2320 x = (uint16_t) va_arg(ap, int);
2321 r = sd_bus_message_append_basic(m, *t, &x);
2325 case SD_BUS_TYPE_INT64:
2326 case SD_BUS_TYPE_UINT64:
2327 case SD_BUS_TYPE_DOUBLE: {
2330 x = va_arg(ap, uint64_t);
2331 r = sd_bus_message_append_basic(m, *t, &x);
2335 case SD_BUS_TYPE_STRING:
2336 case SD_BUS_TYPE_OBJECT_PATH:
2337 case SD_BUS_TYPE_SIGNATURE: {
2340 x = va_arg(ap, const char*);
2341 r = sd_bus_message_append_basic(m, *t, x);
2345 case SD_BUS_TYPE_ARRAY: {
2348 r = signature_element_length(t + 1, &k);
2354 memcpy(s, t + 1, k);
2357 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, s);
2362 if (n_array == (unsigned) -1) {
2367 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2373 n_array = va_arg(ap, unsigned);
2378 case SD_BUS_TYPE_VARIANT: {
2381 s = va_arg(ap, const char*);
2385 r = sd_bus_message_open_container(m, SD_BUS_TYPE_VARIANT, s);
2389 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2394 n_struct = strlen(s);
2395 n_array = (unsigned) -1;
2400 case SD_BUS_TYPE_STRUCT_BEGIN:
2401 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
2404 r = signature_element_length(t, &k);
2411 memcpy(s, t + 1, k - 2);
2414 r = sd_bus_message_open_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
2419 if (n_array == (unsigned) -1) {
2424 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2430 n_array = (unsigned) -1;
2446 _public_ int sd_bus_message_append(sd_bus_message *m, const char *types, ...) {
2450 assert_return(m, -EINVAL);
2451 assert_return(types, -EINVAL);
2452 assert_return(!m->sealed, -EPERM);
2453 assert_return(!m->poisoned, -ESTALE);
2455 va_start(ap, types);
2456 r = bus_message_append_ap(m, types, ap);
2462 _public_ int sd_bus_message_append_array_space(
2472 assert_return(m, -EINVAL);
2473 assert_return(!m->sealed, -EPERM);
2474 assert_return(bus_type_is_trivial(type) && type != SD_BUS_TYPE_BOOLEAN, -EINVAL);
2475 assert_return(ptr || size == 0, -EINVAL);
2476 assert_return(!m->poisoned, -ESTALE);
2478 /* alignment and size of the trivial types (except bool) is
2479 * identical for gvariant and dbus1 marshalling */
2480 align = bus_type_get_alignment(type);
2481 sz = bus_type_get_size(type);
2483 assert_se(align > 0);
2489 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
2493 a = message_extend_body(m, align, size, false);
2497 r = sd_bus_message_close_container(m);
2505 _public_ int sd_bus_message_append_array(sd_bus_message *m,
2512 assert_return(m, -EINVAL);
2513 assert_return(!m->sealed, -EPERM);
2514 assert_return(bus_type_is_trivial(type), -EINVAL);
2515 assert_return(ptr || size == 0, -EINVAL);
2516 assert_return(!m->poisoned, -ESTALE);
2518 r = sd_bus_message_append_array_space(m, type, size, &p);
2523 memcpy(p, ptr, size);
2528 _public_ int sd_bus_message_append_array_iovec(
2531 const struct iovec *iov,
2539 assert_return(m, -EINVAL);
2540 assert_return(!m->sealed, -EPERM);
2541 assert_return(bus_type_is_trivial(type), -EINVAL);
2542 assert_return(iov || n == 0, -EINVAL);
2543 assert_return(!m->poisoned, -ESTALE);
2545 size = IOVEC_TOTAL_SIZE(iov, n);
2547 r = sd_bus_message_append_array_space(m, type, size, &p);
2551 for (i = 0; i < n; i++) {
2553 if (iov[i].iov_base)
2554 memcpy(p, iov[i].iov_base, iov[i].iov_len);
2556 memzero(p, iov[i].iov_len);
2558 p = (uint8_t*) p + iov[i].iov_len;
2564 _public_ int sd_bus_message_append_array_memfd(sd_bus_message *m,
2567 _cleanup_close_ int copy_fd = -1;
2568 struct bus_body_part *part;
2580 if (!bus_type_is_trivial(type))
2585 r = memfd_set_sealed(memfd);
2589 copy_fd = dup(memfd);
2593 r = memfd_get_size(memfd, &size);
2597 align = bus_type_get_alignment(type);
2598 sz = bus_type_get_size(type);
2600 assert_se(align > 0);
2606 if (size > (uint64_t) (uint32_t) -1)
2609 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
2613 a = message_extend_body(m, align, 0, false);
2617 part = message_append_part(m);
2621 part->memfd = copy_fd;
2622 part->sealed = true;
2626 m->header->body_size += size;
2627 message_extend_containers(m, size);
2629 return sd_bus_message_close_container(m);
2632 _public_ int sd_bus_message_append_string_memfd(sd_bus_message *m, int memfd) {
2633 _cleanup_close_ int copy_fd = -1;
2634 struct bus_body_part *part;
2635 struct bus_container *c;
2640 assert_return(m, -EINVAL);
2641 assert_return(memfd >= 0, -EINVAL);
2642 assert_return(!m->sealed, -EPERM);
2643 assert_return(!m->poisoned, -ESTALE);
2645 r = memfd_set_sealed(memfd);
2649 copy_fd = dup(memfd);
2653 r = memfd_get_size(memfd, &size);
2657 /* We require this to be NUL terminated */
2661 if (size > (uint64_t) (uint32_t) -1)
2664 c = message_get_container(m);
2665 if (c->signature && c->signature[c->index]) {
2666 /* Container signature is already set */
2668 if (c->signature[c->index] != SD_BUS_TYPE_STRING)
2673 /* Maybe we can append to the signature? But only if this is the top-level container*/
2674 if (c->enclosing != 0)
2677 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRING), NULL);
2684 if (!BUS_MESSAGE_IS_GVARIANT(m)) {
2685 a = message_extend_body(m, 4, 4, false);
2689 *(uint32_t*) a = size - 1;
2692 part = message_append_part(m);
2696 part->memfd = copy_fd;
2697 part->sealed = true;
2701 m->header->body_size += size;
2702 message_extend_containers(m, size);
2704 if (BUS_MESSAGE_IS_GVARIANT(m)) {
2705 r = message_add_offset(m, m->header->body_size);
2712 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2718 _public_ int sd_bus_message_append_strv(sd_bus_message *m, char **l) {
2722 assert_return(m, -EINVAL);
2723 assert_return(!m->sealed, -EPERM);
2724 assert_return(!m->poisoned, -ESTALE);
2726 r = sd_bus_message_open_container(m, 'a', "s");
2730 STRV_FOREACH(i, l) {
2731 r = sd_bus_message_append_basic(m, 's', *i);
2736 return sd_bus_message_close_container(m);
2739 static int bus_message_close_header(sd_bus_message *m) {
2745 if (!BUS_MESSAGE_IS_GVARIANT(m))
2748 if (m->n_header_offsets < 1)
2751 assert(m->header->fields_size == m->header_offsets[m->n_header_offsets-1]);
2753 sz = determine_word_size(m->header->fields_size, m->n_header_offsets);
2755 a = message_extend_fields(m, 1, sz * m->n_header_offsets, false);
2759 for (i = 0; i < m->n_header_offsets; i++)
2760 write_word_le(a + sz*i, sz, m->header_offsets[i]);
2765 int bus_message_seal(sd_bus_message *m, uint64_t cookie, usec_t timeout) {
2766 struct bus_body_part *part;
2776 if (m->n_containers > 0)
2782 /* In vtables the return signature of method calls is listed,
2783 * let's check if they match if this is a response */
2784 if (m->header->type == SD_BUS_MESSAGE_METHOD_RETURN &&
2785 m->enforced_reply_signature &&
2786 !streq(strempty(m->root_container.signature), m->enforced_reply_signature))
2789 /* If gvariant marshalling is used we need to close the body structure */
2790 r = bus_message_close_struct(m, &m->root_container, false);
2794 /* If there's a non-trivial signature set, then add it in here */
2795 if (!isempty(m->root_container.signature)) {
2796 r = message_append_field_signature(m, BUS_MESSAGE_HEADER_SIGNATURE, m->root_container.signature, NULL);
2802 r = message_append_field_uint32(m, BUS_MESSAGE_HEADER_UNIX_FDS, m->n_fds);
2807 r = bus_message_close_header(m);
2811 m->header->serial = (uint32_t) cookie;
2812 m->timeout = m->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED ? 0 : timeout;
2814 /* Add padding at the end of the fields part, since we know
2815 * the body needs to start at an 8 byte alignment. We made
2816 * sure we allocated enough space for this, so all we need to
2817 * do here is to zero it out. */
2818 l = BUS_MESSAGE_FIELDS_SIZE(m);
2821 memzero((uint8_t*) BUS_MESSAGE_FIELDS(m) + l, a);
2823 /* If this is something we can send as memfd, then let's seal
2824 the memfd now. Note that we can send memfds as payload only
2825 for directed messages, and not for broadcasts. */
2826 if (m->destination && m->bus->use_memfd) {
2827 MESSAGE_FOREACH_PART(part, i, m)
2828 if (part->memfd >= 0 && !part->sealed && (part->size > MEMFD_MIN_SIZE || m->bus->use_memfd < 0)) {
2831 /* Try to seal it if that makes
2832 * sense. First, unmap our own map to
2833 * make sure we don't keep it busy. */
2834 bus_body_part_unmap(part);
2836 /* Then, sync up real memfd size */
2838 r = memfd_set_size(part->memfd, sz);
2842 /* Finally, try to seal */
2843 if (memfd_set_sealed(part->memfd) >= 0)
2844 part->sealed = true;
2848 m->root_container.end = BUS_MESSAGE_BODY_SIZE(m);
2849 m->root_container.index = 0;
2850 m->root_container.offset_index = 0;
2851 m->root_container.item_size = m->root_container.n_offsets > 0 ? m->root_container.offsets[0] : 0;
2858 int bus_body_part_map(struct bus_body_part *part) {
2867 if (part->size <= 0)
2870 /* For smaller zero parts (as used for padding) we don't need to map anything... */
2871 if (part->memfd < 0 && part->is_zero && part->size < 8) {
2872 static const uint8_t zeroes[7] = { };
2873 part->data = (void*) zeroes;
2877 psz = PAGE_ALIGN(part->size);
2879 if (part->memfd >= 0)
2880 p = mmap(NULL, psz, PROT_READ, MAP_PRIVATE, part->memfd, 0);
2881 else if (part->is_zero)
2882 p = mmap(NULL, psz, PROT_READ, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
2886 if (p == MAP_FAILED)
2891 part->munmap_this = true;
2896 void bus_body_part_unmap(struct bus_body_part *part) {
2900 if (part->memfd < 0)
2906 if (!part->munmap_this)
2909 assert_se(munmap(part->data, part->mapped) == 0);
2913 part->munmap_this = false;
2918 static int buffer_peek(const void *p, uint32_t sz, size_t *rindex, size_t align, size_t nbytes, void **r) {
2919 size_t k, start, end;
2924 start = ALIGN_TO((size_t) *rindex, align);
2925 end = start + nbytes;
2930 /* Verify that padding is 0 */
2931 for (k = *rindex; k < start; k++)
2932 if (((const uint8_t*) p)[k] != 0)
2936 *r = (uint8_t*) p + start;
2943 static bool message_end_of_signature(sd_bus_message *m) {
2944 struct bus_container *c;
2948 c = message_get_container(m);
2949 return !c->signature || c->signature[c->index] == 0;
2952 static bool message_end_of_array(sd_bus_message *m, size_t index) {
2953 struct bus_container *c;
2957 c = message_get_container(m);
2958 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2961 if (BUS_MESSAGE_IS_GVARIANT(m))
2962 return index >= c->end;
2964 assert(c->array_size);
2965 return index >= c->begin + BUS_MESSAGE_BSWAP32(m, *c->array_size);
2969 _public_ int sd_bus_message_at_end(sd_bus_message *m, int complete) {
2970 assert_return(m, -EINVAL);
2971 assert_return(m->sealed, -EPERM);
2973 if (complete && m->n_containers > 0)
2976 if (message_end_of_signature(m))
2979 if (message_end_of_array(m, m->rindex))
2985 static struct bus_body_part* find_part(sd_bus_message *m, size_t index, size_t sz, void **p) {
2986 struct bus_body_part *part;
2992 if (m->cached_rindex_part && index >= m->cached_rindex_part_begin) {
2993 part = m->cached_rindex_part;
2994 begin = m->cached_rindex_part_begin;
3004 if (index + sz <= begin + part->size) {
3006 r = bus_body_part_map(part);
3011 *p = (uint8_t*) part->data + index - begin;
3013 m->cached_rindex_part = part;
3014 m->cached_rindex_part_begin = begin;
3019 begin += part->size;
3026 static int container_next_item(sd_bus_message *m, struct bus_container *c, size_t *rindex) {
3033 if (!BUS_MESSAGE_IS_GVARIANT(m))
3036 if (c->enclosing == SD_BUS_TYPE_ARRAY) {
3039 sz = bus_gvariant_get_size(c->signature);
3043 if (c->offset_index+1 >= c->n_offsets)
3046 /* Variable-size array */
3048 alignment = bus_gvariant_get_alignment(c->signature);
3049 assert(alignment > 0);
3051 *rindex = ALIGN_TO(c->offsets[c->offset_index], alignment);
3052 c->item_size = c->offsets[c->offset_index+1] - *rindex;
3055 if (c->offset_index+1 >= (c->end-c->begin)/sz)
3058 /* Fixed-size array */
3059 *rindex = c->begin + (c->offset_index+1) * sz;
3065 } else if (c->enclosing == 0 ||
3066 c->enclosing == SD_BUS_TYPE_STRUCT ||
3067 c->enclosing == SD_BUS_TYPE_DICT_ENTRY) {
3072 if (c->offset_index+1 >= c->n_offsets)
3075 r = signature_element_length(c->signature + c->index, &n);
3079 r = signature_element_length(c->signature + c->index + n, &j);
3084 memcpy(t, c->signature + c->index + n, j);
3087 alignment = bus_gvariant_get_alignment(t);
3090 assert(alignment > 0);
3092 *rindex = ALIGN_TO(c->offsets[c->offset_index], alignment);
3093 c->item_size = c->offsets[c->offset_index+1] - *rindex;
3097 } else if (c->enclosing == SD_BUS_TYPE_VARIANT)
3100 assert_not_reached("Unknown container type");
3105 /* Reached the end */
3112 static int message_peek_body(
3119 size_t k, start, end, padding;
3120 struct bus_body_part *part;
3127 start = ALIGN_TO((size_t) *rindex, align);
3128 padding = start - *rindex;
3129 end = start + nbytes;
3131 if (end > BUS_MESSAGE_BODY_SIZE(m))
3134 part = find_part(m, *rindex, padding, (void**) &q);
3139 /* Verify padding */
3140 for (k = 0; k < padding; k++)
3145 part = find_part(m, start, nbytes, (void**) &q);
3146 if (!part || (nbytes > 0 && !q))
3157 static bool validate_nul(const char *s, size_t l) {
3159 /* Check for NUL chars in the string */
3160 if (memchr(s, 0, l))
3163 /* Check for NUL termination */
3170 static bool validate_string(const char *s, size_t l) {
3172 if (!validate_nul(s, l))
3175 /* Check if valid UTF8 */
3176 if (!utf8_is_valid(s))
3182 static bool validate_signature(const char *s, size_t l) {
3184 if (!validate_nul(s, l))
3187 /* Check if valid signature */
3188 if (!signature_is_valid(s, true))
3194 static bool validate_object_path(const char *s, size_t l) {
3196 if (!validate_nul(s, l))
3199 if (!object_path_is_valid(s))
3205 _public_ int sd_bus_message_read_basic(sd_bus_message *m, char type, void *p) {
3206 struct bus_container *c;
3211 assert_return(m, -EINVAL);
3212 assert_return(m->sealed, -EPERM);
3213 assert_return(bus_type_is_basic(type), -EINVAL);
3215 if (message_end_of_signature(m))
3218 if (message_end_of_array(m, m->rindex))
3221 c = message_get_container(m);
3222 if (c->signature[c->index] != type)
3227 if (BUS_MESSAGE_IS_GVARIANT(m)) {
3229 if (IN_SET(type, SD_BUS_TYPE_STRING, SD_BUS_TYPE_OBJECT_PATH, SD_BUS_TYPE_SIGNATURE)) {
3232 r = message_peek_body(m, &rindex, 1, c->item_size, &q);
3236 if (type == SD_BUS_TYPE_STRING)
3237 ok = validate_string(q, c->item_size-1);
3238 else if (type == SD_BUS_TYPE_OBJECT_PATH)
3239 ok = validate_object_path(q, c->item_size-1);
3241 ok = validate_signature(q, c->item_size-1);
3247 *(const char**) p = q;
3251 sz = bus_gvariant_get_size(CHAR_TO_STR(type));
3253 if ((size_t) sz != c->item_size)
3256 align = bus_gvariant_get_alignment(CHAR_TO_STR(type));
3259 r = message_peek_body(m, &rindex, align, c->item_size, &q);
3265 case SD_BUS_TYPE_BYTE:
3267 *(uint8_t*) p = *(uint8_t*) q;
3270 case SD_BUS_TYPE_BOOLEAN:
3272 *(int*) p = !!*(uint8_t*) q;
3275 case SD_BUS_TYPE_INT16:
3276 case SD_BUS_TYPE_UINT16:
3278 *(uint16_t*) p = BUS_MESSAGE_BSWAP16(m, *(uint16_t*) q);
3281 case SD_BUS_TYPE_INT32:
3282 case SD_BUS_TYPE_UINT32:
3284 *(uint32_t*) p = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
3287 case SD_BUS_TYPE_INT64:
3288 case SD_BUS_TYPE_UINT64:
3289 case SD_BUS_TYPE_DOUBLE:
3291 *(uint64_t*) p = BUS_MESSAGE_BSWAP64(m, *(uint64_t*) q);
3294 case SD_BUS_TYPE_UNIX_FD: {
3297 j = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
3302 *(int*) p = m->fds[j];
3308 assert_not_reached("unexpected type");
3312 r = container_next_item(m, c, &rindex);
3319 if (IN_SET(type, SD_BUS_TYPE_STRING, SD_BUS_TYPE_OBJECT_PATH)) {
3323 r = message_peek_body(m, &rindex, 4, 4, &q);
3327 l = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
3328 r = message_peek_body(m, &rindex, 1, l+1, &q);
3332 if (type == SD_BUS_TYPE_OBJECT_PATH)
3333 ok = validate_object_path(q, l);
3335 ok = validate_string(q, l);
3340 *(const char**) p = q;
3342 } else if (type == SD_BUS_TYPE_SIGNATURE) {
3345 r = message_peek_body(m, &rindex, 1, 1, &q);
3350 r = message_peek_body(m, &rindex, 1, l+1, &q);
3354 if (!validate_signature(q, l))
3358 *(const char**) p = q;
3363 align = bus_type_get_alignment(type);
3366 sz = bus_type_get_size(type);
3369 r = message_peek_body(m, &rindex, align, sz, &q);
3375 case SD_BUS_TYPE_BYTE:
3377 *(uint8_t*) p = *(uint8_t*) q;
3380 case SD_BUS_TYPE_BOOLEAN:
3382 *(int*) p = !!*(uint32_t*) q;
3385 case SD_BUS_TYPE_INT16:
3386 case SD_BUS_TYPE_UINT16:
3388 *(uint16_t*) p = BUS_MESSAGE_BSWAP16(m, *(uint16_t*) q);
3391 case SD_BUS_TYPE_INT32:
3392 case SD_BUS_TYPE_UINT32:
3394 *(uint32_t*) p = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
3397 case SD_BUS_TYPE_INT64:
3398 case SD_BUS_TYPE_UINT64:
3399 case SD_BUS_TYPE_DOUBLE:
3401 *(uint64_t*) p = BUS_MESSAGE_BSWAP64(m, *(uint64_t*) q);
3404 case SD_BUS_TYPE_UNIX_FD: {
3407 j = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
3412 *(int*) p = m->fds[j];
3417 assert_not_reached("Unknown basic type...");
3424 if (c->enclosing != SD_BUS_TYPE_ARRAY)
3430 static int bus_message_enter_array(
3432 struct bus_container *c,
3433 const char *contents,
3434 uint32_t **array_size,
3437 size_t *n_offsets) {
3451 if (!signature_is_single(contents, true))
3454 if (!c->signature || c->signature[c->index] == 0)
3457 if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
3460 if (!startswith(c->signature + c->index + 1, contents))
3465 if (!BUS_MESSAGE_IS_GVARIANT(m)) {
3468 r = message_peek_body(m, &rindex, 4, 4, &q);
3472 if (BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q) > BUS_ARRAY_MAX_SIZE)
3475 alignment = bus_type_get_alignment(contents[0]);
3479 r = message_peek_body(m, &rindex, alignment, 0, NULL);
3483 *array_size = (uint32_t*) q;
3485 } else if (c->item_size <= 0) {
3487 /* gvariant: empty array */
3492 } else if (bus_gvariant_is_fixed_size(contents)) {
3494 /* gvariant: fixed length array */
3495 *item_size = bus_gvariant_get_size(contents);
3500 size_t where, p = 0, framing, sz;
3503 /* gvariant: variable length array */
3504 sz = determine_word_size(c->item_size, 0);
3506 where = rindex + c->item_size - sz;
3507 r = message_peek_body(m, &where, 1, sz, &q);
3511 framing = read_word_le(q, sz);
3512 if (framing > c->item_size - sz)
3514 if ((c->item_size - framing) % sz != 0)
3517 *n_offsets = (c->item_size - framing) / sz;
3519 where = rindex + framing;
3520 r = message_peek_body(m, &where, 1, *n_offsets * sz, &q);
3524 *offsets = new(size_t, *n_offsets);
3528 for (i = 0; i < *n_offsets; i++) {
3531 x = read_word_le((uint8_t*) q + i * sz, sz);
3532 if (x > c->item_size - sz)
3537 (*offsets)[i] = rindex + x;
3541 *item_size = (*offsets)[0] - rindex;
3546 if (c->enclosing != SD_BUS_TYPE_ARRAY)
3547 c->index += 1 + strlen(contents);
3552 static int bus_message_enter_variant(
3554 struct bus_container *c,
3555 const char *contents,
3556 size_t *item_size) {
3568 if (!signature_is_single(contents, false))
3571 if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
3574 if (!c->signature || c->signature[c->index] == 0)
3577 if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
3582 if (BUS_MESSAGE_IS_GVARIANT(m)) {
3585 k = strlen(contents);
3586 if (1+k > c->item_size)
3589 where = rindex + c->item_size - (1+k);
3590 r = message_peek_body(m, &where, 1, 1+k, &q);
3594 if (*(char*) q != 0)
3597 if (memcmp((uint8_t*) q+1, contents, k))
3600 *item_size = c->item_size - (1+k);
3603 r = message_peek_body(m, &rindex, 1, 1, &q);
3608 r = message_peek_body(m, &rindex, 1, l+1, &q);
3612 if (!validate_signature(q, l))
3615 if (!streq(q, contents))
3621 if (c->enclosing != SD_BUS_TYPE_ARRAY)
3627 static int build_struct_offsets(
3629 const char *signature,
3633 size_t *n_offsets) {
3635 unsigned n_variable = 0, n_total = 0, v;
3636 size_t previous = 0, where;
3647 if (isempty(signature)) {
3654 sz = determine_word_size(size, 0);
3658 /* First, loop over signature and count variable elements and
3659 * elements in general. We use this to know how large the
3660 * offset array is at the end of the structure. Note that
3661 * GVariant only stores offsets for all variable size elements
3662 * that are not the last item. */