1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2013 Lennart Poettering
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
29 #include "time-util.h"
30 #include "cgroup-util.h"
33 #include "bus-message.h"
34 #include "bus-internal.h"
36 #include "bus-signature.h"
38 static int message_append_basic(sd_bus_message *m, char type, const void *p, const void **stored);
40 static void *adjust_pointer(const void *p, void *old_base, size_t sz, void *new_base) {
45 if (old_base == new_base)
48 if ((uint8_t*) p < (uint8_t*) old_base)
51 if ((uint8_t*) p >= (uint8_t*) old_base + sz)
54 return (uint8_t*) new_base + ((uint8_t*) p - (uint8_t*) old_base);
57 static void message_free_part(sd_bus_message *m, struct bus_body_part *part) {
61 if (part->memfd >= 0) {
62 /* If we can reuse the memfd, try that. For that it
63 * can't be sealed yet. */
66 bus_kernel_push_memfd(m->bus, part->memfd, part->data, part->mapped);
69 assert_se(munmap(part->data, part->mapped) == 0);
71 close_nointr_nofail(part->memfd);
74 } else if (part->munmap_this)
75 munmap(part->data, part->mapped);
76 else if (part->free_this)
83 static void message_reset_parts(sd_bus_message *m) {
84 struct bus_body_part *part;
89 while (m->n_body_parts > 0) {
90 struct bus_body_part *next = part->next;
91 message_free_part(m, part);
98 m->cached_rindex_part = NULL;
99 m->cached_rindex_part_begin = 0;
102 static void message_reset_containers(sd_bus_message *m) {
107 for (i = 0; i < m->n_containers; i++)
108 free(m->containers[i].signature);
111 m->containers = NULL;
114 m->root_container.index = 0;
117 static void message_free(sd_bus_message *m) {
123 message_reset_parts(m);
128 if (m->release_kdbus) {
131 off = (uint8_t *)m->kdbus - (uint8_t *)m->bus->kdbus_buffer;
132 ioctl(m->bus->input_fd, KDBUS_CMD_FREE, &off);
136 sd_bus_unref(m->bus);
139 close_many(m->fds, m->n_fds);
143 if (m->iovec != m->iovec_fixed)
146 message_reset_containers(m);
147 free(m->root_container.signature);
149 free(m->peeked_signature);
151 bus_creds_done(&m->creds);
155 static void *message_extend_fields(sd_bus_message *m, size_t align, size_t sz) {
157 size_t old_size, new_size, start;
164 old_size = sizeof(struct bus_header) + m->header->fields_size;
165 start = ALIGN_TO(old_size, align);
166 new_size = start + sz;
168 if (old_size == new_size)
169 return (uint8_t*) m->header + old_size;
171 if (new_size > (size_t) ((uint32_t) -1))
174 if (m->free_header) {
175 np = realloc(m->header, ALIGN8(new_size));
179 /* Initially, the header is allocated as part of of
180 * the sd_bus_message itself, let's replace it by
183 np = malloc(ALIGN8(new_size));
187 memcpy(np, m->header, sizeof(struct bus_header));
190 /* Zero out padding */
191 if (start > old_size)
192 memset((uint8_t*) np + old_size, 0, start - old_size);
196 m->header->fields_size = new_size - sizeof(struct bus_header);
198 /* Adjust quick access pointers */
199 m->path = adjust_pointer(m->path, op, old_size, m->header);
200 m->interface = adjust_pointer(m->interface, op, old_size, m->header);
201 m->member = adjust_pointer(m->member, op, old_size, m->header);
202 m->destination = adjust_pointer(m->destination, op, old_size, m->header);
203 m->sender = adjust_pointer(m->sender, op, old_size, m->header);
204 m->error.name = adjust_pointer(m->error.name, op, old_size, m->header);
206 m->free_header = true;
208 return (uint8_t*) np + start;
215 static int message_append_field_string(
228 if (l > (size_t) (uint32_t) -1)
231 /* field id byte + signature length + signature 's' + NUL + string length + string + NUL */
232 p = message_extend_fields(m, 8, 4 + 4 + l + 1);
241 ((uint32_t*) p)[1] = l;
242 memcpy(p + 8, s, l + 1);
245 *ret = (char*) p + 8;
250 static int message_append_field_signature(
265 /* field id byte + signature length + signature 'g' + NUL + string length + string + NUL */
266 p = message_extend_fields(m, 8, 4 + 1 + l + 1);
272 p[2] = SD_BUS_TYPE_SIGNATURE;
275 memcpy(p + 5, s, l + 1);
278 *ret = (const char*) p + 5;
283 static int message_append_field_uint32(sd_bus_message *m, uint8_t h, uint32_t x) {
288 /* field id byte + signature length + signature 'u' + NUL + value */
289 p = message_extend_fields(m, 8, 4 + 4);
295 p[2] = SD_BUS_TYPE_UINT32;
298 ((uint32_t*) p)[1] = x;
303 int bus_message_from_header(
309 const struct ucred *ucred,
312 sd_bus_message **ret) {
315 struct bus_header *h;
318 assert(buffer || length <= 0);
319 assert(fds || n_fds <= 0);
322 if (length < sizeof(struct bus_header))
332 if (h->type == _SD_BUS_MESSAGE_TYPE_INVALID)
335 if (h->endian != SD_BUS_LITTLE_ENDIAN &&
336 h->endian != SD_BUS_BIG_ENDIAN)
339 a = ALIGN(sizeof(sd_bus_message)) + ALIGN(extra);
342 label_sz = strlen(label);
357 m->creds.uid = ucred->uid;
358 m->creds.pid = ucred->pid;
359 m->creds.gid = ucred->gid;
360 m->creds.mask |= SD_BUS_CREDS_UID | SD_BUS_CREDS_PID | SD_BUS_CREDS_GID;
364 m->creds.label = (char*) m + ALIGN(sizeof(sd_bus_message)) + ALIGN(extra);
365 memcpy(m->creds.label, label, label_sz + 1);
367 m->creds.mask |= SD_BUS_CREDS_SELINUX_CONTEXT;
371 m->bus = sd_bus_ref(bus);
377 int bus_message_from_malloc(
383 const struct ucred *ucred,
385 sd_bus_message **ret) {
391 r = bus_message_from_header(bus, buffer, length, fds, n_fds, ucred, label, 0, &m);
395 if (length != BUS_MESSAGE_SIZE(m)) {
400 sz = length - sizeof(struct bus_header) - ALIGN8(BUS_MESSAGE_FIELDS_SIZE(m));
403 m->body.data = (uint8_t*) buffer + sizeof(struct bus_header) + ALIGN8(BUS_MESSAGE_FIELDS_SIZE(m));
405 m->body.sealed = true;
410 m->iovec = m->iovec_fixed;
411 m->iovec[0].iov_base = buffer;
412 m->iovec[0].iov_len = length;
414 r = bus_message_parse_fields(m);
418 /* We take possession of the memory and fds now */
419 m->free_header = true;
430 static sd_bus_message *message_new(sd_bus *bus, uint8_t type) {
433 m = malloc0(ALIGN(sizeof(sd_bus_message)) + sizeof(struct bus_header));
438 m->header = (struct bus_header*) ((uint8_t*) m + ALIGN(sizeof(struct sd_bus_message)));
439 m->header->endian = SD_BUS_NATIVE_ENDIAN;
440 m->header->type = type;
441 m->header->version = bus ? bus->message_version : 1;
442 m->allow_fds = !bus || bus->can_fds || (bus->state != BUS_HELLO && bus->state != BUS_RUNNING);
445 m->bus = sd_bus_ref(bus);
450 _public_ int sd_bus_message_new_signal(
453 const char *interface,
455 sd_bus_message **m) {
460 assert_return(!bus || bus->state != BUS_UNSET, -ENOTCONN);
461 assert_return(object_path_is_valid(path), -EINVAL);
462 assert_return(interface_name_is_valid(interface), -EINVAL);
463 assert_return(member_name_is_valid(member), -EINVAL);
464 assert_return(m, -EINVAL);
466 t = message_new(bus, SD_BUS_MESSAGE_SIGNAL);
470 t->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
472 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_PATH, SD_BUS_TYPE_OBJECT_PATH, path, &t->path);
475 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_INTERFACE, SD_BUS_TYPE_STRING, interface, &t->interface);
478 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_MEMBER, SD_BUS_TYPE_STRING, member, &t->member);
486 sd_bus_message_unref(t);
490 _public_ int sd_bus_message_new_method_call(
492 const char *destination,
494 const char *interface,
496 sd_bus_message **m) {
501 assert_return(!bus || bus->state != BUS_UNSET, -ENOTCONN);
502 assert_return(!destination || service_name_is_valid(destination), -EINVAL);
503 assert_return(object_path_is_valid(path), -EINVAL);
504 assert_return(!interface || interface_name_is_valid(interface), -EINVAL);
505 assert_return(member_name_is_valid(member), -EINVAL);
506 assert_return(m, -EINVAL);
508 t = message_new(bus, SD_BUS_MESSAGE_METHOD_CALL);
512 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_PATH, SD_BUS_TYPE_OBJECT_PATH, path, &t->path);
515 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_MEMBER, SD_BUS_TYPE_STRING, member, &t->member);
520 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_INTERFACE, SD_BUS_TYPE_STRING, interface, &t->interface);
526 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &t->destination);
539 static int message_new_reply(
540 sd_bus_message *call,
542 sd_bus_message **m) {
547 assert_return(call, -EINVAL);
548 assert_return(call->sealed, -EPERM);
549 assert_return(call->header->type == SD_BUS_MESSAGE_METHOD_CALL, -EINVAL);
550 assert_return(!call->bus || call->bus->state != BUS_UNSET, -ENOTCONN);
551 assert_return(m, -EINVAL);
553 t = message_new(call->bus, type);
557 t->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
558 t->reply_serial = BUS_MESSAGE_SERIAL(call);
560 r = message_append_field_uint32(t, SD_BUS_MESSAGE_HEADER_REPLY_SERIAL, t->reply_serial);
565 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, call->sender, &t->destination);
570 t->dont_send = !!(call->header->flags & SD_BUS_MESSAGE_NO_REPLY_EXPECTED);
580 _public_ int sd_bus_message_new_method_return(
581 sd_bus_message *call,
582 sd_bus_message **m) {
584 return message_new_reply(call, SD_BUS_MESSAGE_METHOD_RETURN, m);
587 _public_ int sd_bus_message_new_method_error(
588 sd_bus_message *call,
589 const sd_bus_error *e,
590 sd_bus_message **m) {
595 assert_return(sd_bus_error_is_set(e), -EINVAL);
596 assert_return(m, -EINVAL);
598 r = message_new_reply(call, SD_BUS_MESSAGE_METHOD_ERROR, &t);
602 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_ERROR_NAME, SD_BUS_TYPE_STRING, e->name, &t->error.name);
607 r = message_append_basic(t, SD_BUS_TYPE_STRING, e->message, (const void**) &t->error.message);
612 t->error._need_free = -1;
622 _public_ int sd_bus_message_new_method_errorf(
623 sd_bus_message *call,
629 _cleanup_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
632 assert_return(name, -EINVAL);
633 assert_return(m, -EINVAL);
635 va_start(ap, format);
636 bus_error_setfv(&error, name, format, ap);
639 return sd_bus_message_new_method_error(call, &error, m);
642 _public_ int sd_bus_message_new_method_errno(
643 sd_bus_message *call,
645 const sd_bus_error *p,
646 sd_bus_message **m) {
648 _cleanup_free_ sd_bus_error berror = SD_BUS_ERROR_NULL;
650 if (sd_bus_error_is_set(p))
651 return sd_bus_message_new_method_error(call, p, m);
653 sd_bus_error_set_errno(&berror, error);
655 return sd_bus_message_new_method_error(call, &berror, m);
658 _public_ int sd_bus_message_new_method_errnof(
659 sd_bus_message *call,
665 _cleanup_free_ sd_bus_error berror = SD_BUS_ERROR_NULL;
668 va_start(ap, format);
669 bus_error_set_errnofv(&berror, error, format, ap);
672 return sd_bus_message_new_method_error(call, &berror, m);
675 int bus_message_new_synthetic_error(
678 const sd_bus_error *e,
679 sd_bus_message **m) {
684 assert(sd_bus_error_is_set(e));
687 t = message_new(bus, SD_BUS_MESSAGE_METHOD_ERROR);
691 t->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
692 t->reply_serial = serial;
694 r = message_append_field_uint32(t, SD_BUS_MESSAGE_HEADER_REPLY_SERIAL, t->reply_serial);
698 if (bus && bus->unique_name) {
699 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, bus->unique_name, &t->destination);
704 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_ERROR_NAME, SD_BUS_TYPE_STRING, e->name, &t->error.name);
709 r = message_append_basic(t, SD_BUS_TYPE_STRING, e->message, (const void**) &t->error.message);
714 t->error._need_free = -1;
724 _public_ sd_bus_message* sd_bus_message_ref(sd_bus_message *m) {
725 assert_return(m, NULL);
727 assert(m->n_ref > 0);
733 _public_ sd_bus_message* sd_bus_message_unref(sd_bus_message *m) {
734 assert_return(m, NULL);
736 assert(m->n_ref > 0);
745 _public_ int sd_bus_message_get_type(sd_bus_message *m, uint8_t *type) {
746 assert_return(m, -EINVAL);
747 assert_return(type, -EINVAL);
749 *type = m->header->type;
753 _public_ int sd_bus_message_get_serial(sd_bus_message *m, uint64_t *serial) {
754 assert_return(m, -EINVAL);
755 assert_return(serial, -EINVAL);
756 assert_return(m->header->serial != 0, -ENOENT);
758 *serial = BUS_MESSAGE_SERIAL(m);
762 _public_ int sd_bus_message_get_reply_serial(sd_bus_message *m, uint64_t *serial) {
763 assert_return(m, -EINVAL);
764 assert_return(serial, -EINVAL);
765 assert_return(m->reply_serial != 0, -ENOENT);
767 *serial = m->reply_serial;
771 _public_ int sd_bus_message_get_no_reply(sd_bus_message *m) {
772 assert_return(m, -EINVAL);
774 return m->header->type == SD_BUS_MESSAGE_METHOD_CALL ? !!(m->header->flags & SD_BUS_MESSAGE_NO_REPLY_EXPECTED) : 0;
777 _public_ int sd_bus_message_get_no_auto_start(sd_bus_message *m) {
778 assert_return(m, -EINVAL);
780 return !!(m->header->flags & SD_BUS_MESSAGE_NO_AUTO_START);
783 _public_ const char *sd_bus_message_get_path(sd_bus_message *m) {
784 assert_return(m, NULL);
789 _public_ const char *sd_bus_message_get_interface(sd_bus_message *m) {
790 assert_return(m, NULL);
795 _public_ const char *sd_bus_message_get_member(sd_bus_message *m) {
796 assert_return(m, NULL);
801 _public_ const char *sd_bus_message_get_destination(sd_bus_message *m) {
802 assert_return(m, NULL);
804 return m->destination;
807 _public_ const char *sd_bus_message_get_sender(sd_bus_message *m) {
808 assert_return(m, NULL);
813 _public_ const sd_bus_error *sd_bus_message_get_error(sd_bus_message *m) {
814 assert_return(m, NULL);
815 assert_return(sd_bus_error_is_set(&m->error), NULL);
820 _public_ int sd_bus_message_get_monotonic_timestamp(sd_bus_message *m, uint64_t *usec) {
821 assert_return(m, -EINVAL);
822 assert_return(usec, -EINVAL);
823 assert_return(m->monotonic > 0, -ENODATA);
825 *usec = m->monotonic;
829 _public_ int sd_bus_message_get_realtime_timestamp(sd_bus_message *m, uint64_t *usec) {
830 assert_return(m, -EINVAL);
831 assert_return(usec, -EINVAL);
832 assert_return(m->realtime > 0, -ENODATA);
838 _public_ sd_bus_creds *sd_bus_message_get_creds(sd_bus_message *m) {
839 assert_return(m, NULL);
841 if (m->creds.mask == 0)
847 _public_ int sd_bus_message_is_signal(sd_bus_message *m,
848 const char *interface,
849 const char *member) {
850 assert_return(m, -EINVAL);
852 if (m->header->type != SD_BUS_MESSAGE_SIGNAL)
855 if (interface && (!m->interface || !streq(m->interface, interface)))
858 if (member && (!m->member || !streq(m->member, member)))
864 _public_ int sd_bus_message_is_method_call(sd_bus_message *m,
865 const char *interface,
866 const char *member) {
867 assert_return(m, -EINVAL);
869 if (m->header->type != SD_BUS_MESSAGE_METHOD_CALL)
872 if (interface && (!m->interface || !streq(m->interface, interface)))
875 if (member && (!m->member || !streq(m->member, member)))
881 _public_ int sd_bus_message_is_method_error(sd_bus_message *m, const char *name) {
882 assert_return(m, -EINVAL);
884 if (m->header->type != SD_BUS_MESSAGE_METHOD_ERROR)
887 if (name && (!m->error.name || !streq(m->error.name, name)))
893 _public_ int sd_bus_message_set_no_reply(sd_bus_message *m, int b) {
894 assert_return(m, -EINVAL);
895 assert_return(!m->sealed, -EPERM);
896 assert_return(m->header->type == SD_BUS_MESSAGE_METHOD_CALL, -EPERM);
899 m->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
901 m->header->flags &= ~SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
906 _public_ int sd_bus_message_set_no_auto_start(sd_bus_message *m, int b) {
907 assert_return(m, -EINVAL);
908 assert_return(!m->sealed, -EPERM);
911 m->header->flags |= SD_BUS_MESSAGE_NO_AUTO_START;
913 m->header->flags &= ~SD_BUS_MESSAGE_NO_AUTO_START;
918 static struct bus_container *message_get_container(sd_bus_message *m) {
921 if (m->n_containers == 0)
922 return &m->root_container;
924 assert(m->containers);
925 return m->containers + m->n_containers - 1;
928 struct bus_body_part *message_append_part(sd_bus_message *m) {
929 struct bus_body_part *part;
936 if (m->n_body_parts <= 0) {
942 part = new0(struct bus_body_part, 1);
948 m->body_end->next = part;
958 static void part_zero(struct bus_body_part *part, size_t sz) {
963 /* All other fields can be left in their defaults */
965 assert(part->memfd < 0);
968 part->is_zero = true;
972 static int part_make_space(
973 struct sd_bus_message *m,
974 struct bus_body_part *part,
983 assert(!part->sealed);
988 if (!part->data && part->memfd < 0)
989 part->memfd = bus_kernel_pop_memfd(m->bus, &part->data, &part->mapped);
991 if (part->memfd >= 0) {
994 r = ioctl(part->memfd, KDBUS_CMD_MEMFD_SIZE_SET, &u);
1000 if (!part->data || sz > part->mapped) {
1001 size_t psz = PAGE_ALIGN(sz > 0 ? sz : 1);
1003 if (part->mapped <= 0)
1004 n = mmap(NULL, psz, PROT_READ|PROT_WRITE, MAP_SHARED, part->memfd, 0);
1006 n = mremap(part->data, part->mapped, psz, MREMAP_MAYMOVE);
1008 if (n == MAP_FAILED) {
1017 part->munmap_this = true;
1019 n = realloc(part->data, MAX(sz, 1u));
1026 part->free_this = true;
1030 *q = part->data ? (uint8_t*) part->data + part->size : NULL;
1036 static void message_extend_containers(sd_bus_message *m, size_t expand) {
1037 struct bus_container *c;
1044 /* Update counters */
1045 for (c = m->containers; c < m->containers + m->n_containers; c++)
1047 *c->array_size += expand;
1050 static void *message_extend_body(sd_bus_message *m, size_t align, size_t sz) {
1051 struct bus_body_part *part = NULL;
1052 size_t start_body, end_body, padding, start_part, end_part, added;
1064 start_body = ALIGN_TO((size_t) m->header->body_size, align);
1065 end_body = start_body + sz;
1067 padding = start_body - m->header->body_size;
1068 added = padding + sz;
1070 /* Check for 32bit overflows */
1071 if (end_body > (size_t) ((uint32_t) -1)) {
1077 m->n_body_parts <= 0 ||
1078 m->body_end->sealed ||
1079 padding != ALIGN_TO(m->body_end->size, align) - m->body_end->size;
1083 part = message_append_part(m);
1087 part_zero(part, padding);
1090 part = message_append_part(m);
1094 r = part_make_space(m, part, sz, &p);
1098 struct bus_container *c;
1106 start_part = ALIGN_TO(part->size, align);
1107 end_part = start_part + sz;
1109 r = part_make_space(m, part, end_part, &p);
1114 memset(p, 0, padding);
1115 p = (uint8_t*) p + padding;
1118 /* Readjust pointers */
1119 for (c = m->containers; c < m->containers + m->n_containers; c++)
1120 c->array_size = adjust_pointer(c->array_size, op, os, part->data);
1122 m->error.message = (const char*) adjust_pointer(m->error.message, op, os, part->data);
1125 m->header->body_size = end_body;
1126 message_extend_containers(m, added);
1131 int message_append_basic(sd_bus_message *m, char type, const void *p, const void **stored) {
1132 struct bus_container *c;
1140 assert_return(m, -EINVAL);
1141 assert_return(!m->sealed, -EPERM);
1142 assert_return(bus_type_is_basic(type), -EINVAL);
1143 assert_return(!m->poisoned, -ESTALE);
1145 c = message_get_container(m);
1147 if (c->signature && c->signature[c->index]) {
1148 /* Container signature is already set */
1150 if (c->signature[c->index] != type)
1155 /* Maybe we can append to the signature? But only if this is the top-level container*/
1156 if (c->enclosing != 0)
1159 e = strextend(&c->signature, CHAR_TO_STR(type), NULL);
1168 case SD_BUS_TYPE_STRING:
1169 /* To make things easy we'll serialize a NULL string
1170 * into the empty string */
1173 /* Fall through... */
1174 case SD_BUS_TYPE_OBJECT_PATH:
1182 sz = 4 + strlen(p) + 1;
1185 case SD_BUS_TYPE_SIGNATURE:
1193 sz = 1 + strlen(p) + 1;
1196 case SD_BUS_TYPE_BOOLEAN:
1205 assert_cc(sizeof(int) == sizeof(uint32_t));
1211 case SD_BUS_TYPE_UNIX_FD: {
1219 if (!m->allow_fds) {
1232 fd = fcntl(z, F_DUPFD_CLOEXEC, 3);
1238 f = realloc(m->fds, sizeof(int) * (m->n_fds + 1));
1258 align = bus_type_get_alignment(type);
1259 sz = bus_type_get_size(type);
1266 a = message_extend_body(m, align, sz);
1272 if (type == SD_BUS_TYPE_STRING || type == SD_BUS_TYPE_OBJECT_PATH) {
1273 *(uint32_t*) a = sz - 5;
1274 memcpy((uint8_t*) a + 4, p, sz - 4);
1277 *stored = (const uint8_t*) a + 4;
1279 } else if (type == SD_BUS_TYPE_SIGNATURE) {
1280 *(uint8_t*) a = sz - 1;
1281 memcpy((uint8_t*) a + 1, p, sz - 1);
1284 *stored = (const uint8_t*) a + 1;
1285 } else if (type == SD_BUS_TYPE_UNIX_FD) {
1286 *(uint32_t*) a = fdi;
1300 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1307 close_nointr_nofail(fd);
1312 _public_ int sd_bus_message_append_basic(sd_bus_message *m, char type, const void *p) {
1313 return message_append_basic(m, type, p, NULL);
1316 _public_ int sd_bus_message_append_string_space(
1321 struct bus_container *c;
1324 assert_return(m, -EINVAL);
1325 assert_return(s, -EINVAL);
1326 assert_return(!m->sealed, -EPERM);
1327 assert_return(!m->poisoned, -ESTALE);
1329 c = message_get_container(m);
1331 if (c->signature && c->signature[c->index]) {
1332 /* Container signature is already set */
1334 if (c->signature[c->index] != SD_BUS_TYPE_STRING)
1339 /* Maybe we can append to the signature? But only if this is the top-level container*/
1340 if (c->enclosing != 0)
1343 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRING), NULL);
1350 a = message_extend_body(m, 4, 4 + size + 1);
1354 *(uint32_t*) a = size;
1359 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1365 _public_ int sd_bus_message_append_string_iovec(
1367 const struct iovec *iov,
1375 assert_return(m, -EINVAL);
1376 assert_return(!m->sealed, -EPERM);
1377 assert_return(iov || n == 0, -EINVAL);
1378 assert_return(!m->poisoned, -ESTALE);
1380 size = IOVEC_TOTAL_SIZE(iov, n);
1382 r = sd_bus_message_append_string_space(m, size, &p);
1386 for (i = 0; i < n; i++) {
1388 if (iov[i].iov_base)
1389 memcpy(p, iov[i].iov_base, iov[i].iov_len);
1391 memset(p, ' ', iov[i].iov_len);
1393 p += iov[i].iov_len;
1399 static int bus_message_open_array(
1401 struct bus_container *c,
1402 const char *contents,
1403 uint32_t **array_size) {
1409 struct bus_body_part *o;
1416 if (!signature_is_single(contents, true))
1419 alignment = bus_type_get_alignment(contents[0]);
1423 if (c->signature && c->signature[c->index]) {
1425 /* Verify the existing signature */
1427 if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
1430 if (!startswith(c->signature + c->index + 1, contents))
1433 nindex = c->index + 1 + strlen(contents);
1437 if (c->enclosing != 0)
1440 /* Extend the existing signature */
1442 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_ARRAY), contents, NULL);
1448 nindex = e - c->signature;
1451 a = message_extend_body(m, 4, 4);
1456 op = m->body_end->data;
1457 os = m->body_end->size;
1459 /* Add alignment between size and first element */
1460 if (!message_extend_body(m, alignment, 0))
1463 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1466 /* location of array size might have changed so let's readjust a */
1467 if (o == m->body_end)
1468 a = adjust_pointer(a, op, os, m->body_end->data);
1475 static int bus_message_open_variant(
1477 struct bus_container *c,
1478 const char *contents) {
1487 if (!signature_is_single(contents, false))
1490 if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
1493 if (c->signature && c->signature[c->index]) {
1495 if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
1501 if (c->enclosing != 0)
1504 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_VARIANT), NULL);
1511 l = strlen(contents);
1512 a = message_extend_body(m, 1, 1 + l + 1);
1517 memcpy((uint8_t*) a + 1, contents, l + 1);
1519 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1525 static int bus_message_open_struct(
1527 struct bus_container *c,
1528 const char *contents) {
1536 if (!signature_is_valid(contents, false))
1539 if (c->signature && c->signature[c->index]) {
1542 l = strlen(contents);
1544 if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
1545 !startswith(c->signature + c->index + 1, contents) ||
1546 c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
1549 nindex = c->index + 1 + l + 1;
1553 if (c->enclosing != 0)
1556 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_BEGIN), contents, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_END), NULL);
1562 nindex = e - c->signature;
1565 /* Align contents to 8 byte boundary */
1566 if (!message_extend_body(m, 8, 0))
1569 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1575 static int bus_message_open_dict_entry(
1577 struct bus_container *c,
1578 const char *contents) {
1586 if (!signature_is_pair(contents))
1589 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1592 if (c->signature && c->signature[c->index]) {
1595 l = strlen(contents);
1597 if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
1598 !startswith(c->signature + c->index + 1, contents) ||
1599 c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
1602 nindex = c->index + 1 + l + 1;
1606 /* Align contents to 8 byte boundary */
1607 if (!message_extend_body(m, 8, 0))
1610 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1616 _public_ int sd_bus_message_open_container(
1619 const char *contents) {
1621 struct bus_container *c, *w;
1622 uint32_t *array_size = NULL;
1627 assert_return(m, -EINVAL);
1628 assert_return(!m->sealed, -EPERM);
1629 assert_return(contents, -EINVAL);
1630 assert_return(!m->poisoned, -ESTALE);
1632 /* Make sure we have space for one more container */
1633 w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
1641 c = message_get_container(m);
1643 signature = strdup(contents);
1649 /* Save old index in the parent container, in case we have to
1650 * abort this container */
1651 c->saved_index = c->index;
1652 before = m->header->body_size;
1654 if (type == SD_BUS_TYPE_ARRAY)
1655 r = bus_message_open_array(m, c, contents, &array_size);
1656 else if (type == SD_BUS_TYPE_VARIANT)
1657 r = bus_message_open_variant(m, c, contents);
1658 else if (type == SD_BUS_TYPE_STRUCT)
1659 r = bus_message_open_struct(m, c, contents);
1660 else if (type == SD_BUS_TYPE_DICT_ENTRY)
1661 r = bus_message_open_dict_entry(m, c, contents);
1670 /* OK, let's fill it in */
1671 w += m->n_containers++;
1672 w->enclosing = type;
1673 w->signature = signature;
1675 w->array_size = array_size;
1677 w->begin = m->rindex;
1682 _public_ int sd_bus_message_close_container(sd_bus_message *m) {
1683 struct bus_container *c;
1685 assert_return(m, -EINVAL);
1686 assert_return(!m->sealed, -EPERM);
1687 assert_return(m->n_containers > 0, -EINVAL);
1688 assert_return(!m->poisoned, -ESTALE);
1690 c = message_get_container(m);
1691 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1692 if (c->signature && c->signature[c->index] != 0)
1707 static int type_stack_push(TypeStack *stack, unsigned max, unsigned *i, const char *types, unsigned n_struct, unsigned n_array) {
1714 stack[*i].types = types;
1715 stack[*i].n_struct = n_struct;
1716 stack[*i].n_array = n_array;
1722 static int type_stack_pop(TypeStack *stack, unsigned max, unsigned *i, const char **types, unsigned *n_struct, unsigned *n_array) {
1733 *types = stack[*i].types;
1734 *n_struct = stack[*i].n_struct;
1735 *n_array = stack[*i].n_array;
1740 int bus_message_append_ap(
1745 unsigned n_array, n_struct;
1746 TypeStack stack[BUS_CONTAINER_DEPTH];
1747 unsigned stack_ptr = 0;
1755 n_array = (unsigned) -1;
1756 n_struct = strlen(types);
1761 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
1762 r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
1768 r = sd_bus_message_close_container(m);
1776 if (n_array != (unsigned) -1)
1785 case SD_BUS_TYPE_BYTE: {
1788 x = (uint8_t) va_arg(ap, int);
1789 r = sd_bus_message_append_basic(m, *t, &x);
1793 case SD_BUS_TYPE_BOOLEAN:
1794 case SD_BUS_TYPE_INT32:
1795 case SD_BUS_TYPE_UINT32:
1796 case SD_BUS_TYPE_UNIX_FD: {
1799 /* We assume a boolean is the same as int32_t */
1800 assert_cc(sizeof(int32_t) == sizeof(int));
1802 x = va_arg(ap, uint32_t);
1803 r = sd_bus_message_append_basic(m, *t, &x);
1807 case SD_BUS_TYPE_INT16:
1808 case SD_BUS_TYPE_UINT16: {
1811 x = (uint16_t) va_arg(ap, int);
1812 r = sd_bus_message_append_basic(m, *t, &x);
1816 case SD_BUS_TYPE_INT64:
1817 case SD_BUS_TYPE_UINT64:
1818 case SD_BUS_TYPE_DOUBLE: {
1821 x = va_arg(ap, uint64_t);
1822 r = sd_bus_message_append_basic(m, *t, &x);
1826 case SD_BUS_TYPE_STRING:
1827 case SD_BUS_TYPE_OBJECT_PATH:
1828 case SD_BUS_TYPE_SIGNATURE: {
1831 x = va_arg(ap, const char*);
1832 r = sd_bus_message_append_basic(m, *t, x);
1836 case SD_BUS_TYPE_ARRAY: {
1839 r = signature_element_length(t + 1, &k);
1845 memcpy(s, t + 1, k);
1848 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, s);
1853 if (n_array == (unsigned) -1) {
1858 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
1864 n_array = va_arg(ap, unsigned);
1869 case SD_BUS_TYPE_VARIANT: {
1872 s = va_arg(ap, const char*);
1876 r = sd_bus_message_open_container(m, SD_BUS_TYPE_VARIANT, s);
1880 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
1885 n_struct = strlen(s);
1886 n_array = (unsigned) -1;
1891 case SD_BUS_TYPE_STRUCT_BEGIN:
1892 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
1895 r = signature_element_length(t, &k);
1902 memcpy(s, t + 1, k - 2);
1905 r = sd_bus_message_open_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
1910 if (n_array == (unsigned) -1) {
1915 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
1921 n_array = (unsigned) -1;
1937 _public_ int sd_bus_message_append(sd_bus_message *m, const char *types, ...) {
1941 assert_return(m, -EINVAL);
1942 assert_return(types, -EINVAL);
1943 assert_return(!m->sealed, -EPERM);
1944 assert_return(!m->poisoned, -ESTALE);
1946 va_start(ap, types);
1947 r = bus_message_append_ap(m, types, ap);
1953 _public_ int sd_bus_message_append_array_space(sd_bus_message *m,
1961 assert_return(m, -EINVAL);
1962 assert_return(!m->sealed, -EPERM);
1963 assert_return(bus_type_is_trivial(type), -EINVAL);
1964 assert_return(ptr || size == 0, -EINVAL);
1965 assert_return(!m->poisoned, -ESTALE);
1967 align = bus_type_get_alignment(type);
1968 sz = bus_type_get_size(type);
1970 assert_se(align > 0);
1976 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
1980 a = message_extend_body(m, align, size);
1984 r = sd_bus_message_close_container(m);
1992 _public_ int sd_bus_message_append_array(sd_bus_message *m,
1999 assert_return(m, -EINVAL);
2000 assert_return(!m->sealed, -EPERM);
2001 assert_return(bus_type_is_trivial(type), -EINVAL);
2002 assert_return(ptr || size == 0, -EINVAL);
2003 assert_return(!m->poisoned, -ESTALE);
2005 r = sd_bus_message_append_array_space(m, type, size, &p);
2010 memcpy(p, ptr, size);
2015 _public_ int sd_bus_message_append_array_iovec(
2018 const struct iovec *iov,
2026 assert_return(m, -EINVAL);
2027 assert_return(!m->sealed, -EPERM);
2028 assert_return(bus_type_is_trivial(type), -EINVAL);
2029 assert_return(iov || n == 0, -EINVAL);
2030 assert_return(!m->poisoned, -ESTALE);
2032 size = IOVEC_TOTAL_SIZE(iov, n);
2034 r = sd_bus_message_append_array_space(m, type, size, &p);
2038 for (i = 0; i < n; i++) {
2040 if (iov[i].iov_base)
2041 memcpy(p, iov[i].iov_base, iov[i].iov_len);
2043 memset(p, 0, iov[i].iov_len);
2045 p = (uint8_t*) p + iov[i].iov_len;
2051 _public_ int sd_bus_message_append_array_memfd(sd_bus_message *m,
2054 _cleanup_close_ int copy_fd = -1;
2055 struct bus_body_part *part;
2067 if (!bus_type_is_trivial(type))
2072 r = sd_memfd_set_sealed(memfd, true);
2076 copy_fd = sd_memfd_dup_fd(memfd);
2080 r = sd_memfd_get_size(memfd, &size);
2084 align = bus_type_get_alignment(type);
2085 sz = bus_type_get_size(type);
2087 assert_se(align > 0);
2093 if (size > (uint64_t) (uint32_t) -1)
2096 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
2100 a = message_extend_body(m, align, 0);
2104 part = message_append_part(m);
2108 part->memfd = copy_fd;
2109 part->sealed = true;
2113 message_extend_containers(m, size);
2114 m->header->body_size += size;
2116 return sd_bus_message_close_container(m);
2119 _public_ int sd_bus_message_append_string_memfd(sd_bus_message *m, sd_memfd *memfd) {
2120 _cleanup_close_ int copy_fd = -1;
2121 struct bus_body_part *part;
2122 struct bus_container *c;
2127 assert_return(m, -EINVAL);
2128 assert_return(memfd, -EINVAL);
2129 assert_return(!m->sealed, -EPERM);
2130 assert_return(!m->poisoned, -ESTALE);
2132 r = sd_memfd_set_sealed(memfd, true);
2136 copy_fd = sd_memfd_dup_fd(memfd);
2140 r = sd_memfd_get_size(memfd, &size);
2144 /* We require this to be NUL terminated */
2148 if (size > (uint64_t) (uint32_t) -1)
2151 c = message_get_container(m);
2152 if (c->signature && c->signature[c->index]) {
2153 /* Container signature is already set */
2155 if (c->signature[c->index] != SD_BUS_TYPE_STRING)
2160 /* Maybe we can append to the signature? But only if this is the top-level container*/
2161 if (c->enclosing != 0)
2164 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRING), NULL);
2171 a = message_extend_body(m, 4, 4);
2175 *(uint32_t*) a = size - 1;
2177 part = message_append_part(m);
2181 part->memfd = copy_fd;
2182 part->sealed = true;
2186 message_extend_containers(m, size);
2187 m->header->body_size += size;
2189 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2195 _public_ int sd_bus_message_append_strv(sd_bus_message *m, char **l) {
2199 assert_return(m, -EINVAL);
2200 assert_return(!m->sealed, -EPERM);
2201 assert_return(!m->poisoned, -ESTALE);
2203 r = sd_bus_message_open_container(m, 'a', "s");
2207 STRV_FOREACH(i, l) {
2208 r = sd_bus_message_append_basic(m, 's', *i);
2213 return sd_bus_message_close_container(m);
2216 int bus_body_part_map(struct bus_body_part *part) {
2225 if (part->size <= 0)
2228 /* For smaller zero parts (as used for padding) we don't need to map anything... */
2229 if (part->memfd < 0 && part->is_zero && part->size < 8) {
2230 static const uint8_t zeroes[7] = { };
2231 part->data = (void*) zeroes;
2235 psz = PAGE_ALIGN(part->size);
2237 if (part->memfd >= 0)
2238 p = mmap(NULL, psz, PROT_READ, MAP_SHARED, part->memfd, 0);
2239 else if (part->is_zero)
2240 p = mmap(NULL, psz, PROT_READ, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
2244 if (p == MAP_FAILED)
2249 part->munmap_this = true;
2254 void bus_body_part_unmap(struct bus_body_part *part) {
2258 if (part->memfd < 0)
2264 if (!part->munmap_this)
2267 assert_se(munmap(part->data, part->mapped) == 0);
2271 part->munmap_this = false;
2276 static int buffer_peek(const void *p, uint32_t sz, size_t *rindex, size_t align, size_t nbytes, void **r) {
2277 size_t k, start, end;
2282 start = ALIGN_TO((size_t) *rindex, align);
2283 end = start + nbytes;
2288 /* Verify that padding is 0 */
2289 for (k = *rindex; k < start; k++)
2290 if (((const uint8_t*) p)[k] != 0)
2294 *r = (uint8_t*) p + start;
2301 static bool message_end_of_signature(sd_bus_message *m) {
2302 struct bus_container *c;
2306 c = message_get_container(m);
2307 return !c->signature || c->signature[c->index] == 0;
2310 static bool message_end_of_array(sd_bus_message *m, size_t index) {
2311 struct bus_container *c;
2315 c = message_get_container(m);
2319 return index >= c->begin + BUS_MESSAGE_BSWAP32(m, *c->array_size);
2322 _public_ int sd_bus_message_at_end(sd_bus_message *m, int complete) {
2323 assert_return(m, -EINVAL);
2324 assert_return(m->sealed, -EPERM);
2326 if (complete && m->n_containers > 0)
2329 if (message_end_of_signature(m))
2332 if (message_end_of_array(m, m->rindex))
2338 static struct bus_body_part* find_part(sd_bus_message *m, size_t index, size_t sz, void **p) {
2339 struct bus_body_part *part;
2345 if (m->cached_rindex_part && index >= m->cached_rindex_part_begin) {
2346 part = m->cached_rindex_part;
2347 begin = m->cached_rindex_part_begin;
2357 if (index + sz <= begin + part->size) {
2359 r = bus_body_part_map(part);
2364 *p = (uint8_t*) part->data + index - begin;
2366 m->cached_rindex_part = part;
2367 m->cached_rindex_part_begin = begin;
2372 begin += part->size;
2379 static int message_peek_body(
2386 size_t k, start, end, padding;
2387 struct bus_body_part *part;
2394 if (message_end_of_array(m, *rindex))
2397 start = ALIGN_TO((size_t) *rindex, align);
2398 padding = start - *rindex;
2399 end = start + nbytes;
2401 if (end > BUS_MESSAGE_BODY_SIZE(m))
2404 part = find_part(m, *rindex, padding, (void**) &q);
2409 /* Verify padding */
2410 for (k = 0; k < padding; k++)
2415 part = find_part(m, start, nbytes, (void**) &q);
2427 static bool validate_nul(const char *s, size_t l) {
2429 /* Check for NUL chars in the string */
2430 if (memchr(s, 0, l))
2433 /* Check for NUL termination */
2440 static bool validate_string(const char *s, size_t l) {
2442 if (!validate_nul(s, l))
2445 /* Check if valid UTF8 */
2446 if (!utf8_is_valid(s))
2452 static bool validate_signature(const char *s, size_t l) {
2454 if (!validate_nul(s, l))
2457 /* Check if valid signature */
2458 if (!signature_is_valid(s, true))
2464 static bool validate_object_path(const char *s, size_t l) {
2466 if (!validate_nul(s, l))
2469 if (!object_path_is_valid(s))
2475 _public_ int sd_bus_message_read_basic(sd_bus_message *m, char type, void *p) {
2476 struct bus_container *c;
2480 assert_return(m, -EINVAL);
2481 assert_return(m->sealed, -EPERM);
2482 assert_return(bus_type_is_basic(type), -EINVAL);
2484 if (message_end_of_signature(m))
2487 if (message_end_of_array(m, m->rindex))
2490 c = message_get_container(m);
2491 if (c->signature[c->index] != type)
2496 case SD_BUS_TYPE_STRING:
2497 case SD_BUS_TYPE_OBJECT_PATH: {
2502 r = message_peek_body(m, &rindex, 4, 4, &q);
2506 l = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2507 r = message_peek_body(m, &rindex, 1, l+1, &q);
2513 if (type == SD_BUS_TYPE_OBJECT_PATH) {
2514 if (!validate_object_path(q, l))
2517 if (!validate_string(q, l))
2523 *(const char**) p = q;
2528 case SD_BUS_TYPE_SIGNATURE: {
2533 r = message_peek_body(m, &rindex, 1, 1, &q);
2538 r = message_peek_body(m, &rindex, 1, l+1, &q);
2544 if (!validate_signature(q, l))
2550 *(const char**) p = q;
2558 align = bus_type_get_alignment(type);
2559 sz = bus_type_get_size(type);
2560 assert(align > 0 && sz > 0);
2563 r = message_peek_body(m, &rindex, align, sz, &q);
2569 case SD_BUS_TYPE_BYTE:
2571 *(uint8_t*) p = *(uint8_t*) q;
2574 case SD_BUS_TYPE_BOOLEAN:
2576 *(int*) p = !!*(uint32_t*) q;
2579 case SD_BUS_TYPE_INT16:
2580 case SD_BUS_TYPE_UINT16:
2582 *(uint16_t*) p = BUS_MESSAGE_BSWAP16(m, *(uint16_t*) q);
2585 case SD_BUS_TYPE_INT32:
2586 case SD_BUS_TYPE_UINT32:
2588 *(uint32_t*) p = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2591 case SD_BUS_TYPE_INT64:
2592 case SD_BUS_TYPE_UINT64:
2593 case SD_BUS_TYPE_DOUBLE:
2595 *(uint64_t*) p = BUS_MESSAGE_BSWAP64(m, *(uint64_t*) q);
2598 case SD_BUS_TYPE_UNIX_FD: {
2601 j = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2606 *(int*) p = m->fds[j];
2611 assert_not_reached("Unknown basic type...");
2620 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2626 static int bus_message_enter_array(
2628 struct bus_container *c,
2629 const char *contents,
2630 uint32_t **array_size) {
2641 if (!signature_is_single(contents, true))
2644 alignment = bus_type_get_alignment(contents[0]);
2648 if (!c->signature || c->signature[c->index] == 0)
2651 if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
2654 if (!startswith(c->signature + c->index + 1, contents))
2658 r = message_peek_body(m, &rindex, 4, 4, &q);
2662 if (BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q) > BUS_ARRAY_MAX_SIZE)
2665 r = message_peek_body(m, &rindex, alignment, 0, NULL);
2671 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2672 c->index += 1 + strlen(contents);
2676 *array_size = (uint32_t*) q;
2681 static int bus_message_enter_variant(
2683 struct bus_container *c,
2684 const char *contents) {
2695 if (!signature_is_single(contents, false))
2698 if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
2701 if (!c->signature || c->signature[c->index] == 0)
2704 if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
2708 r = message_peek_body(m, &rindex, 1, 1, &q);
2713 r = message_peek_body(m, &rindex, 1, l+1, &q);
2719 if (!validate_signature(q, l))
2722 if (!streq(q, contents))
2725 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2733 static int bus_message_enter_struct(
2735 struct bus_container *c,
2736 const char *contents) {
2745 if (!signature_is_valid(contents, false))
2748 if (!c->signature || c->signature[c->index] == 0)
2751 l = strlen(contents);
2753 if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
2754 !startswith(c->signature + c->index + 1, contents) ||
2755 c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
2758 r = message_peek_body(m, &m->rindex, 8, 0, NULL);
2762 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2763 c->index += 1 + l + 1;
2768 static int bus_message_enter_dict_entry(
2770 struct bus_container *c,
2771 const char *contents) {
2780 if (!signature_is_pair(contents))
2783 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2786 if (!c->signature || c->signature[c->index] == 0)
2789 l = strlen(contents);
2791 if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
2792 !startswith(c->signature + c->index + 1, contents) ||
2793 c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
2796 r = message_peek_body(m, &m->rindex, 8, 0, NULL);
2800 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2801 c->index += 1 + l + 1;
2806 _public_ int sd_bus_message_enter_container(sd_bus_message *m,
2808 const char *contents) {
2809 struct bus_container *c, *w;
2810 uint32_t *array_size = NULL;
2815 assert_return(m, -EINVAL);
2816 assert_return(m->sealed, -EPERM);
2817 assert_return(type != 0 || !contents, -EINVAL);
2819 if (type == 0 || !contents) {
2823 /* Allow entering into anonymous containers */
2824 r = sd_bus_message_peek_type(m, &tt, &cc);
2828 if (type != 0 && type != tt)
2831 if (contents && !streq(contents, cc))
2839 * We enforce a global limit on container depth, that is much
2840 * higher than the 32 structs and 32 arrays the specification
2841 * mandates. This is simpler to implement for us, and we need
2842 * this only to ensure our container array doesn't grow
2843 * without bounds. We are happy to return any data from a
2844 * message as long as the data itself is valid, even if the
2845 * overall message might be not.
2847 * Note that the message signature is validated when
2848 * parsing the headers, and that validation does check the
2851 * Note that the specification defines no limits on the depth
2852 * of stacked variants, but we do.
2854 if (m->n_containers >= BUS_CONTAINER_DEPTH)
2857 w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
2862 if (message_end_of_signature(m))
2865 if (message_end_of_array(m, m->rindex))
2868 c = message_get_container(m);
2870 signature = strdup(contents);
2874 c->saved_index = c->index;
2877 if (type == SD_BUS_TYPE_ARRAY)
2878 r = bus_message_enter_array(m, c, contents, &array_size);
2879 else if (type == SD_BUS_TYPE_VARIANT)
2880 r = bus_message_enter_variant(m, c, contents);
2881 else if (type == SD_BUS_TYPE_STRUCT)
2882 r = bus_message_enter_struct(m, c, contents);
2883 else if (type == SD_BUS_TYPE_DICT_ENTRY)
2884 r = bus_message_enter_dict_entry(m, c, contents);
2893 /* OK, let's fill it in */
2894 w += m->n_containers++;
2895 w->enclosing = type;
2896 w->signature = signature;
2898 w->array_size = array_size;
2900 w->begin = m->rindex;
2905 _public_ int sd_bus_message_exit_container(sd_bus_message *m) {
2906 struct bus_container *c;
2908 assert_return(m, -EINVAL);
2909 assert_return(m->sealed, -EPERM);
2910 assert_return(m->n_containers > 0, -ENXIO);
2912 c = message_get_container(m);
2913 if (c->enclosing == SD_BUS_TYPE_ARRAY) {
2916 l = BUS_MESSAGE_BSWAP32(m, *c->array_size);
2917 if (c->begin + l != m->rindex)
2921 if (c->signature && c->signature[c->index] != 0)
2931 static void message_quit_container(sd_bus_message *m) {
2932 struct bus_container *c;
2936 assert(m->n_containers > 0);
2938 c = message_get_container(m);
2941 assert(m->rindex >= c->before);
2942 m->rindex = c->before;
2944 /* Free container */
2948 /* Correct index of new top-level container */
2949 c = message_get_container(m);
2950 c->index = c->saved_index;
2953 _public_ int sd_bus_message_peek_type(sd_bus_message *m, char *type, const char **contents) {
2954 struct bus_container *c;
2957 assert_return(m, -EINVAL);
2958 assert_return(m->sealed, -EPERM);
2960 if (message_end_of_signature(m))
2963 if (message_end_of_array(m, m->rindex))
2966 c = message_get_container(m);
2968 if (bus_type_is_basic(c->signature[c->index])) {
2972 *type = c->signature[c->index];
2976 if (c->signature[c->index] == SD_BUS_TYPE_ARRAY) {
2982 r = signature_element_length(c->signature+c->index+1, &l);
2988 sig = strndup(c->signature + c->index + 1, l);
2992 free(m->peeked_signature);
2993 m->peeked_signature = sig;
2999 *type = SD_BUS_TYPE_ARRAY;
3004 if (c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ||
3005 c->signature[c->index] == SD_BUS_TYPE_DICT_ENTRY_BEGIN) {
3011 r = signature_element_length(c->signature+c->index, &l);
3016 sig = strndup(c->signature + c->index + 1, l - 2);
3020 free(m->peeked_signature);
3021 m->peeked_signature = sig;
3027 *type = c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY;
3032 if (c->signature[c->index] == SD_BUS_TYPE_VARIANT) {
3038 r = message_peek_body(m, &rindex, 1, 1, &q);
3045 r = message_peek_body(m, &rindex, 1, l+1, &q);
3051 if (!validate_signature(q, l))
3058 *type = SD_BUS_TYPE_VARIANT;
3073 _public_ int sd_bus_message_rewind(sd_bus_message *m, int complete) {
3074 struct bus_container *c;
3076 assert_return(m, -EINVAL);
3077 assert_return(m->sealed, -EPERM);
3080 message_reset_containers(m);
3082 m->root_container.index = 0;
3084 c = message_get_container(m);
3086 c = message_get_container(m);
3089 m->rindex = c->begin;
3092 return !isempty(c->signature);
3095 static int message_read_ap(
3100 unsigned n_array, n_struct;
3101 TypeStack stack[BUS_CONTAINER_DEPTH];
3102 unsigned stack_ptr = 0;
3103 unsigned n_loop = 0;
3111 /* Ideally, we'd just call ourselves recursively on every
3112 * complex type. However, the state of a va_list that is
3113 * passed to a function is undefined after that function
3114 * returns. This means we need to docode the va_list linearly
3115 * in a single stackframe. We hence implement our own
3116 * home-grown stack in an array. */
3118 n_array = (unsigned) -1; /* lenght of current array entries */
3119 n_struct = strlen(types); /* length of current struct contents signature */
3126 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
3127 r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
3133 r = sd_bus_message_exit_container(m);
3141 if (n_array != (unsigned) -1)
3150 case SD_BUS_TYPE_BYTE:
3151 case SD_BUS_TYPE_BOOLEAN:
3152 case SD_BUS_TYPE_INT16:
3153 case SD_BUS_TYPE_UINT16:
3154 case SD_BUS_TYPE_INT32:
3155 case SD_BUS_TYPE_UINT32:
3156 case SD_BUS_TYPE_INT64:
3157 case SD_BUS_TYPE_UINT64:
3158 case SD_BUS_TYPE_DOUBLE:
3159 case SD_BUS_TYPE_STRING:
3160 case SD_BUS_TYPE_OBJECT_PATH:
3161 case SD_BUS_TYPE_SIGNATURE:
3162 case SD_BUS_TYPE_UNIX_FD: {
3165 p = va_arg(ap, void*);
3166 r = sd_bus_message_read_basic(m, *t, p);
3179 case SD_BUS_TYPE_ARRAY: {
3182 r = signature_element_length(t + 1, &k);
3188 memcpy(s, t + 1, k);
3191 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, s);
3202 if (n_array == (unsigned) -1) {
3207 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
3213 n_array = va_arg(ap, unsigned);
3218 case SD_BUS_TYPE_VARIANT: {
3221 s = va_arg(ap, const char *);
3225 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, s);
3235 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
3240 n_struct = strlen(s);
3241 n_array = (unsigned) -1;
3246 case SD_BUS_TYPE_STRUCT_BEGIN:
3247 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
3250 r = signature_element_length(t, &k);
3256 memcpy(s, t + 1, k - 2);
3259 r = sd_bus_message_enter_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
3269 if (n_array == (unsigned) -1) {
3274 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
3280 n_array = (unsigned) -1;
3293 _public_ int sd_bus_message_read(sd_bus_message *m, const char *types, ...) {
3297 assert_return(m, -EINVAL);
3298 assert_return(m->sealed, -EPERM);
3299 assert_return(types, -EINVAL);
3301 va_start(ap, types);
3302 r = message_read_ap(m, types, ap);
3308 _public_ int sd_bus_message_skip(sd_bus_message *m, const char *types) {
3311 assert_return(m, -EINVAL);
3312 assert_return(m->sealed, -EPERM);
3313 assert_return(types, -EINVAL);
3320 case SD_BUS_TYPE_BYTE:
3321 case SD_BUS_TYPE_BOOLEAN:
3322 case SD_BUS_TYPE_INT16:
3323 case SD_BUS_TYPE_UINT16:
3324 case SD_BUS_TYPE_INT32:
3325 case SD_BUS_TYPE_UINT32:
3326 case SD_BUS_TYPE_INT64:
3327 case SD_BUS_TYPE_UINT64:
3328 case SD_BUS_TYPE_DOUBLE:
3329 case SD_BUS_TYPE_STRING:
3330 case SD_BUS_TYPE_OBJECT_PATH:
3331 case SD_BUS_TYPE_SIGNATURE:
3332 case SD_BUS_TYPE_UNIX_FD:
3334 r = sd_bus_message_read_basic(m, *types, NULL);
3338 r = sd_bus_message_skip(m, types + 1);
3344 case SD_BUS_TYPE_ARRAY: {
3347 r = signature_element_length(types + 1, &k);
3353 memcpy(s, types+1, k);
3356 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, s);
3361 r = sd_bus_message_skip(m, s);
3368 r = sd_bus_message_exit_container(m);
3373 r = sd_bus_message_skip(m, types + 1 + k);
3380 case SD_BUS_TYPE_VARIANT: {
3381 const char *contents;
3384 r = sd_bus_message_peek_type(m, &x, &contents);
3388 if (x != SD_BUS_TYPE_VARIANT)
3391 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, contents);
3395 r = sd_bus_message_skip(m, contents);
3400 r = sd_bus_message_exit_container(m);
3404 r = sd_bus_message_skip(m, types + 1);
3411 case SD_BUS_TYPE_STRUCT_BEGIN:
3412 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
3415 r = signature_element_length(types, &k);
3421 memcpy(s, types+1, k-2);
3424 r = sd_bus_message_enter_container(m, *types == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
3428 r = sd_bus_message_skip(m, s);
3433 r = sd_bus_message_exit_container(m);
3438 r = sd_bus_message_skip(m, types + k);
3450 _public_ int sd_bus_message_read_array(sd_bus_message *m,
3454 struct bus_container *c;
3460 assert_return(m, -EINVAL);
3461 assert_return(m->sealed, -EPERM);
3462 assert_return(bus_type_is_trivial(type), -EINVAL);
3463 assert_return(ptr, -EINVAL);
3464 assert_return(size, -EINVAL);
3465 assert_return(!BUS_MESSAGE_NEED_BSWAP(m), -ENOTSUP);
3467 align = bus_type_get_alignment(type);
3471 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
3475 c = message_get_container(m);
3476 sz = BUS_MESSAGE_BSWAP32(m, *c->array_size);
3479 /* Zero length array, let's return some aligned
3480 * pointer that is not NULL */
3481 p = (uint8_t*) NULL + align;
3483 r = message_peek_body(m, &m->rindex, align, sz, &p);
3492 r = sd_bus_message_exit_container(m);
3496 *ptr = (const void*) p;
3502 message_quit_container(m);
3506 static int message_peek_fields(
3517 return buffer_peek(BUS_MESSAGE_FIELDS(m), BUS_MESSAGE_FIELDS_SIZE(m), rindex, align, nbytes, ret);
3520 static int message_peek_field_uint32(
3531 r = message_peek_fields(m, ri, 4, 4, &q);
3536 *ret = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
3541 static int message_peek_field_string(
3543 bool (*validate)(const char *p),
3554 r = message_peek_field_uint32(m, ri, &l);
3558 r = message_peek_fields(m, ri, 1, l+1, &q);
3563 if (!validate_nul(q, l))
3569 if (!validate_string(q, l))
3579 static int message_peek_field_signature(
3591 r = message_peek_fields(m, ri, 1, 1, &q);
3596 r = message_peek_fields(m, ri, 1, l+1, &q);
3600 if (!validate_signature(q, l))
3609 static int message_skip_fields(
3612 uint32_t array_size,
3613 const char **signature) {
3615 size_t original_index;
3622 original_index = *ri;
3628 if (array_size != (uint32_t) -1 &&
3629 array_size <= *ri - original_index)
3636 if (t == SD_BUS_TYPE_STRING) {
3638 r = message_peek_field_string(m, NULL, ri, NULL);
3644 } else if (t == SD_BUS_TYPE_OBJECT_PATH) {
3646 r = message_peek_field_string(m, object_path_is_valid, ri, NULL);
3652 } else if (t == SD_BUS_TYPE_SIGNATURE) {
3654 r = message_peek_field_signature(m, ri, NULL);
3660 } else if (bus_type_is_basic(t)) {
3663 align = bus_type_get_alignment(t);
3664 k = bus_type_get_size(t);
3665 assert(align > 0 && k > 0);
3667 r = message_peek_fields(m, ri, align, k, NULL);
3673 } else if (t == SD_BUS_TYPE_ARRAY) {
3675 r = signature_element_length(*signature+1, &l);
3685 strncpy(sig, *signature + 1, l-1);
3688 alignment = bus_type_get_alignment(sig[0]);
3692 r = message_peek_field_uint32(m, ri, &nas);
3695 if (nas > BUS_ARRAY_MAX_SIZE)
3698 r = message_peek_fields(m, ri, alignment, 0, NULL);
3702 r = message_skip_fields(m, ri, nas, (const char**) &s);
3707 (*signature) += 1 + l;
3709 } else if (t == SD_BUS_TYPE_VARIANT) {
3712 r = message_peek_field_signature(m, ri, &s);
3716 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
3722 } else if (t == SD_BUS_TYPE_STRUCT ||
3723 t == SD_BUS_TYPE_DICT_ENTRY) {
3725 r = signature_element_length(*signature, &l);
3732 strncpy(sig, *signature + 1, l-1);
3735 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
3746 int bus_message_parse_fields(sd_bus_message *m) {
3749 uint32_t unix_fds = 0;
3753 for (ri = 0; ri < BUS_MESSAGE_FIELDS_SIZE(m); ) {
3754 const char *signature;
3757 r = message_peek_fields(m, &ri, 8, 1, (void**) &header);
3761 r = message_peek_field_signature(m, &ri, &signature);
3766 case _SD_BUS_MESSAGE_HEADER_INVALID:
3769 case SD_BUS_MESSAGE_HEADER_PATH:
3774 if (!streq(signature, "o"))
3777 r = message_peek_field_string(m, object_path_is_valid, &ri, &m->path);
3780 case SD_BUS_MESSAGE_HEADER_INTERFACE:
3785 if (!streq(signature, "s"))
3788 r = message_peek_field_string(m, interface_name_is_valid, &ri, &m->interface);
3791 case SD_BUS_MESSAGE_HEADER_MEMBER:
3796 if (!streq(signature, "s"))
3799 r = message_peek_field_string(m, member_name_is_valid, &ri, &m->member);
3802 case SD_BUS_MESSAGE_HEADER_ERROR_NAME:
3807 if (!streq(signature, "s"))
3810 r = message_peek_field_string(m, error_name_is_valid, &ri, &m->error.name);
3812 m->error._need_free = -1;
3816 case SD_BUS_MESSAGE_HEADER_DESTINATION:
3821 if (!streq(signature, "s"))
3824 r = message_peek_field_string(m, service_name_is_valid, &ri, &m->destination);
3827 case SD_BUS_MESSAGE_HEADER_SENDER:
3832 if (!streq(signature, "s"))
3835 r = message_peek_field_string(m, service_name_is_valid, &ri, &m->sender);
3837 if (r >= 0 && m->sender[0] == ':' && m->bus && m->bus->bus_client && !m->bus->is_kernel) {
3838 m->creds.unique_name = (char*) m->sender;
3839 m->creds.mask |= SD_BUS_CREDS_UNIQUE_NAME & m->bus->creds_mask;
3845 case SD_BUS_MESSAGE_HEADER_SIGNATURE: {
3849 if (m->root_container.signature)
3852 if (!streq(signature, "g"))
3855 r = message_peek_field_signature(m, &ri, &s);
3863 free(m->root_container.signature);
3864 m->root_container.signature = c;
3868 case SD_BUS_MESSAGE_HEADER_REPLY_SERIAL:
3869 if (m->reply_serial != 0)
3872 if (!streq(signature, "u"))
3875 r = message_peek_field_uint32(m, &ri, &m->reply_serial);
3879 if (m->reply_serial == 0)
3884 case SD_BUS_MESSAGE_HEADER_UNIX_FDS:
3888 if (!streq(signature, "u"))
3891 r = message_peek_field_uint32(m, &ri, &unix_fds);
3901 r = message_skip_fields(m, &ri, (uint32_t) -1, (const char **) &signature);
3908 if (m->n_fds != unix_fds)
3911 if (isempty(m->root_container.signature) != (BUS_MESSAGE_BODY_SIZE(m) == 0))
3914 switch (m->header->type) {
3916 case SD_BUS_MESSAGE_SIGNAL:
3917 if (!m->path || !m->interface || !m->member)
3921 case SD_BUS_MESSAGE_METHOD_CALL:
3923 if (!m->path || !m->member)
3928 case SD_BUS_MESSAGE_METHOD_RETURN:
3930 if (m->reply_serial == 0)
3934 case SD_BUS_MESSAGE_METHOD_ERROR:
3936 if (m->reply_serial == 0 || !m->error.name)
3941 /* Try to read the error message, but if we can't it's a non-issue */
3942 if (m->header->type == SD_BUS_MESSAGE_METHOD_ERROR)
3943 sd_bus_message_read(m, "s", &m->error.message);
3948 int bus_message_seal(sd_bus_message *m, uint64_t serial) {
3949 struct bus_body_part *part;
3959 if (m->n_containers > 0)
3965 /* If there's a non-trivial signature set, then add it in here */
3966 if (!isempty(m->root_container.signature)) {
3967 r = message_append_field_signature(m, SD_BUS_MESSAGE_HEADER_SIGNATURE, m->root_container.signature, NULL);
3973 r = message_append_field_uint32(m, SD_BUS_MESSAGE_HEADER_UNIX_FDS, m->n_fds);
3978 /* Add padding at the end of the fields part, since we know
3979 * the body needs to start at an 8 byte alignment. We made
3980 * sure we allocated enough space for this, so all we need to
3981 * do here is to zero it out. */
3982 l = BUS_MESSAGE_FIELDS_SIZE(m);
3985 memset((uint8_t*) BUS_MESSAGE_FIELDS(m) + l, 0, a);
3987 /* If this is something we can send as memfd, then let's seal
3988 the memfd now. Note that we can send memfds as payload only
3989 for directed messages, and not for broadcasts. */
3990 if (m->destination && m->bus && m->bus->use_memfd) {
3991 MESSAGE_FOREACH_PART(part, i, m)
3992 if (part->memfd >= 0 && !part->sealed && (part->size > MEMFD_MIN_SIZE || m->bus->use_memfd < 0)) {
3993 bus_body_part_unmap(part);
3995 if (ioctl(part->memfd, KDBUS_CMD_MEMFD_SEAL_SET, 1) >= 0)
3996 part->sealed = true;
4000 m->header->serial = serial;
4006 _public_ int sd_bus_message_set_destination(sd_bus_message *m, const char *destination) {
4007 assert_return(m, -EINVAL);
4008 assert_return(destination, -EINVAL);
4009 assert_return(!m->sealed, -EPERM);
4010 assert_return(!m->destination, -EEXIST);
4012 return message_append_field_string(m, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &m->destination);
4015 int bus_message_get_blob(sd_bus_message *m, void **buffer, size_t *sz) {
4019 struct bus_body_part *part;
4025 total = BUS_MESSAGE_SIZE(m);
4031 e = mempcpy(p, m->header, BUS_MESSAGE_BODY_BEGIN(m));
4032 MESSAGE_FOREACH_PART(part, i, m)
4033 e = mempcpy(e, part->data, part->size);
4035 assert(total == (size_t) ((uint8_t*) e - (uint8_t*) p));
4043 int bus_message_read_strv_extend(sd_bus_message *m, char ***l) {
4049 r = sd_bus_message_enter_container(m, 'a', "s");
4056 r = sd_bus_message_read_basic(m, 's', &s);
4062 r = strv_extend(l, s);
4067 r = sd_bus_message_exit_container(m);
4074 _public_ int sd_bus_message_read_strv(sd_bus_message *m, char ***l) {
4078 assert_return(m, -EINVAL);
4079 assert_return(m->sealed, -EPERM);
4080 assert_return(l, -EINVAL);
4082 r = bus_message_read_strv_extend(m, &strv);
4092 const char* bus_message_get_arg(sd_bus_message *m, unsigned i) {
4094 const char *t = NULL;
4099 r = sd_bus_message_rewind(m, true);
4103 for (j = 0; j <= i; j++) {
4106 r = sd_bus_message_peek_type(m, &type, NULL);
4110 if (type != SD_BUS_TYPE_STRING &&
4111 type != SD_BUS_TYPE_OBJECT_PATH &&
4112 type != SD_BUS_TYPE_SIGNATURE)
4115 r = sd_bus_message_read_basic(m, type, &t);
4123 bool bus_header_is_complete(struct bus_header *h, size_t size) {
4129 if (size < sizeof(struct bus_header))
4132 full = sizeof(struct bus_header) +
4133 (h->endian == SD_BUS_NATIVE_ENDIAN ? h->fields_size : bswap_32(h->fields_size));
4135 return size >= full;
4138 int bus_header_message_size(struct bus_header *h, size_t *sum) {
4144 if (h->endian == SD_BUS_NATIVE_ENDIAN) {
4145 fs = h->fields_size;
4147 } else if (h->endian == SD_BUS_REVERSE_ENDIAN) {
4148 fs = bswap_32(h->fields_size);
4149 bs = bswap_32(h->body_size);
4153 *sum = sizeof(struct bus_header) + ALIGN8(fs) + bs;
4157 _public_ int sd_bus_message_get_errno(sd_bus_message *m) {
4158 assert_return(m, -EINVAL);
4160 if (m->header->type != SD_BUS_MESSAGE_METHOD_ERROR)
4163 return sd_bus_error_get_errno(&m->error);
4166 _public_ const char* sd_bus_message_get_signature(sd_bus_message *m, int complete) {
4167 struct bus_container *c;
4169 assert_return(m, NULL);
4171 c = complete ? &m->root_container : message_get_container(m);
4172 return c->signature ?: "";
4175 _public_ int sd_bus_message_copy(sd_bus_message *m, sd_bus_message *source, int all) {
4176 bool done_something = false;
4179 assert_return(m, -EINVAL);
4180 assert_return(source, -EINVAL);
4181 assert_return(!m->sealed, -EPERM);
4182 assert_return(source->sealed, -EPERM);
4185 const char *contents;
4200 r = sd_bus_message_peek_type(source, &type, &contents);
4206 done_something = true;
4208 if (bus_type_is_container(type) > 0) {
4210 r = sd_bus_message_enter_container(source, type, contents);
4214 r = sd_bus_message_open_container(m, type, contents);
4218 r = sd_bus_message_copy(m, source, true);
4222 r = sd_bus_message_close_container(m);
4226 r = sd_bus_message_exit_container(source);
4233 r = sd_bus_message_read_basic(source, type, &basic);
4239 if (type == SD_BUS_TYPE_OBJECT_PATH ||
4240 type == SD_BUS_TYPE_SIGNATURE ||
4241 type == SD_BUS_TYPE_STRING)
4242 r = sd_bus_message_append_basic(m, type, basic.string);
4244 r = sd_bus_message_append_basic(m, type, &basic);
4251 return done_something;
4254 _public_ int sd_bus_message_verify_type(sd_bus_message *m, char type, const char *contents) {
4259 assert_return(m, -EINVAL);
4260 assert_return(m->sealed, -EPERM);
4261 assert_return(!type || bus_type_is_valid(type), -EINVAL);
4262 assert_return(!contents || signature_is_valid(contents, true), -EINVAL);
4263 assert_return(type || contents, -EINVAL);
4264 assert_return(!contents || !type || bus_type_is_container(type), -EINVAL);
4266 r = sd_bus_message_peek_type(m, &t, &c);
4270 if (type != 0 && type != t)
4273 if (contents && !streq_ptr(contents, c))
4279 _public_ sd_bus *sd_bus_message_get_bus(sd_bus_message *m) {
4280 assert_return(m, NULL);