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_MSG_RELEASE, &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);
620 _public_ int sd_bus_message_new_method_errorf(
621 sd_bus_message *call,
627 _cleanup_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
630 assert_return(name, -EINVAL);
631 assert_return(m, -EINVAL);
633 va_start(ap, format);
634 bus_error_setfv(&error, name, format, ap);
637 return sd_bus_message_new_method_error(call, &error, m);
640 _public_ int sd_bus_message_new_method_errno(
641 sd_bus_message *call,
643 const sd_bus_error *p,
644 sd_bus_message **m) {
646 _cleanup_free_ sd_bus_error berror = SD_BUS_ERROR_NULL;
648 if (sd_bus_error_is_set(p))
649 return sd_bus_message_new_method_error(call, p, m);
651 sd_bus_error_set_errno(&berror, error);
653 return sd_bus_message_new_method_error(call, &berror, m);
656 _public_ int sd_bus_message_new_method_errnof(
657 sd_bus_message *call,
663 _cleanup_free_ sd_bus_error berror = SD_BUS_ERROR_NULL;
666 va_start(ap, format);
667 bus_error_set_errnofv(&berror, error, format, ap);
670 return sd_bus_message_new_method_error(call, &berror, m);
673 int bus_message_new_synthetic_error(
676 const sd_bus_error *e,
677 sd_bus_message **m) {
682 assert(sd_bus_error_is_set(e));
685 t = message_new(bus, SD_BUS_MESSAGE_METHOD_ERROR);
689 t->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
690 t->reply_serial = serial;
692 r = message_append_field_uint32(t, SD_BUS_MESSAGE_HEADER_REPLY_SERIAL, t->reply_serial);
696 if (bus && bus->unique_name) {
697 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, bus->unique_name, &t->destination);
702 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_ERROR_NAME, SD_BUS_TYPE_STRING, e->name, &t->error.name);
707 r = message_append_basic(t, SD_BUS_TYPE_STRING, e->message, (const void**) &t->error.message);
720 _public_ sd_bus_message* sd_bus_message_ref(sd_bus_message *m) {
721 assert_return(m, NULL);
723 assert(m->n_ref > 0);
729 _public_ sd_bus_message* sd_bus_message_unref(sd_bus_message *m) {
730 assert_return(m, NULL);
732 assert(m->n_ref > 0);
741 _public_ int sd_bus_message_get_type(sd_bus_message *m, uint8_t *type) {
742 assert_return(m, -EINVAL);
743 assert_return(type, -EINVAL);
745 *type = m->header->type;
749 _public_ int sd_bus_message_get_serial(sd_bus_message *m, uint64_t *serial) {
750 assert_return(m, -EINVAL);
751 assert_return(serial, -EINVAL);
752 assert_return(m->header->serial != 0, -ENOENT);
754 *serial = BUS_MESSAGE_SERIAL(m);
758 _public_ int sd_bus_message_get_reply_serial(sd_bus_message *m, uint64_t *serial) {
759 assert_return(m, -EINVAL);
760 assert_return(serial, -EINVAL);
761 assert_return(m->reply_serial != 0, -ENOENT);
763 *serial = m->reply_serial;
767 _public_ int sd_bus_message_get_no_reply(sd_bus_message *m) {
768 assert_return(m, -EINVAL);
770 return m->header->type == SD_BUS_MESSAGE_METHOD_CALL ? !!(m->header->flags & SD_BUS_MESSAGE_NO_REPLY_EXPECTED) : 0;
773 _public_ int sd_bus_message_get_no_auto_start(sd_bus_message *m) {
774 assert_return(m, -EINVAL);
776 return !!(m->header->flags & SD_BUS_MESSAGE_NO_AUTO_START);
779 _public_ const char *sd_bus_message_get_path(sd_bus_message *m) {
780 assert_return(m, NULL);
785 _public_ const char *sd_bus_message_get_interface(sd_bus_message *m) {
786 assert_return(m, NULL);
791 _public_ const char *sd_bus_message_get_member(sd_bus_message *m) {
792 assert_return(m, NULL);
797 _public_ const char *sd_bus_message_get_destination(sd_bus_message *m) {
798 assert_return(m, NULL);
800 return m->destination;
803 _public_ const char *sd_bus_message_get_sender(sd_bus_message *m) {
804 assert_return(m, NULL);
809 _public_ const sd_bus_error *sd_bus_message_get_error(sd_bus_message *m) {
810 assert_return(m, NULL);
811 assert_return(sd_bus_error_is_set(&m->error), NULL);
816 _public_ int sd_bus_message_get_monotonic_timestamp(sd_bus_message *m, uint64_t *usec) {
817 assert_return(m, -EINVAL);
818 assert_return(usec, -EINVAL);
819 assert_return(m->monotonic > 0, -ENODATA);
821 *usec = m->monotonic;
825 _public_ int sd_bus_message_get_realtime_timestamp(sd_bus_message *m, uint64_t *usec) {
826 assert_return(m, -EINVAL);
827 assert_return(usec, -EINVAL);
828 assert_return(m->realtime > 0, -ENODATA);
834 _public_ sd_bus_creds *sd_bus_message_get_creds(sd_bus_message *m) {
835 assert_return(m, NULL);
837 if (m->creds.mask == 0)
843 _public_ int sd_bus_message_is_signal(sd_bus_message *m,
844 const char *interface,
845 const char *member) {
846 assert_return(m, -EINVAL);
848 if (m->header->type != SD_BUS_MESSAGE_SIGNAL)
851 if (interface && (!m->interface || !streq(m->interface, interface)))
854 if (member && (!m->member || !streq(m->member, member)))
860 _public_ int sd_bus_message_is_method_call(sd_bus_message *m,
861 const char *interface,
862 const char *member) {
863 assert_return(m, -EINVAL);
865 if (m->header->type != SD_BUS_MESSAGE_METHOD_CALL)
868 if (interface && (!m->interface || !streq(m->interface, interface)))
871 if (member && (!m->member || !streq(m->member, member)))
877 _public_ int sd_bus_message_is_method_error(sd_bus_message *m, const char *name) {
878 assert_return(m, -EINVAL);
880 if (m->header->type != SD_BUS_MESSAGE_METHOD_ERROR)
883 if (name && (!m->error.name || !streq(m->error.name, name)))
889 _public_ int sd_bus_message_set_no_reply(sd_bus_message *m, int b) {
890 assert_return(m, -EINVAL);
891 assert_return(!m->sealed, -EPERM);
892 assert_return(m->header->type == SD_BUS_MESSAGE_METHOD_CALL, -EPERM);
895 m->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
897 m->header->flags &= ~SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
902 _public_ int sd_bus_message_set_no_auto_start(sd_bus_message *m, int b) {
903 assert_return(m, -EINVAL);
904 assert_return(!m->sealed, -EPERM);
907 m->header->flags |= SD_BUS_MESSAGE_NO_AUTO_START;
909 m->header->flags &= ~SD_BUS_MESSAGE_NO_AUTO_START;
914 static struct bus_container *message_get_container(sd_bus_message *m) {
917 if (m->n_containers == 0)
918 return &m->root_container;
920 assert(m->containers);
921 return m->containers + m->n_containers - 1;
924 struct bus_body_part *message_append_part(sd_bus_message *m) {
925 struct bus_body_part *part;
932 if (m->n_body_parts <= 0) {
938 part = new0(struct bus_body_part, 1);
944 m->body_end->next = part;
954 static void part_zero(struct bus_body_part *part, size_t sz) {
959 /* All other fields can be left in their defaults */
961 assert(part->memfd < 0);
964 part->is_zero = true;
968 static int part_make_space(
969 struct sd_bus_message *m,
970 struct bus_body_part *part,
979 assert(!part->sealed);
984 if (!part->data && part->memfd < 0)
985 part->memfd = bus_kernel_pop_memfd(m->bus, &part->data, &part->mapped);
987 if (part->memfd >= 0) {
990 r = ioctl(part->memfd, KDBUS_CMD_MEMFD_SIZE_SET, &u);
996 if (!part->data || sz > part->mapped) {
997 size_t psz = PAGE_ALIGN(sz > 0 ? sz : 1);
999 if (part->mapped <= 0)
1000 n = mmap(NULL, psz, PROT_READ|PROT_WRITE, MAP_SHARED, part->memfd, 0);
1002 n = mremap(part->data, part->mapped, psz, MREMAP_MAYMOVE);
1004 if (n == MAP_FAILED) {
1013 part->munmap_this = true;
1015 n = realloc(part->data, MAX(sz, 1u));
1022 part->free_this = true;
1026 *q = part->data ? (uint8_t*) part->data + part->size : NULL;
1032 static void message_extend_containers(sd_bus_message *m, size_t expand) {
1033 struct bus_container *c;
1040 /* Update counters */
1041 for (c = m->containers; c < m->containers + m->n_containers; c++)
1043 *c->array_size += expand;
1046 static void *message_extend_body(sd_bus_message *m, size_t align, size_t sz) {
1047 struct bus_body_part *part = NULL;
1048 size_t start_body, end_body, padding, start_part, end_part, added;
1060 start_body = ALIGN_TO((size_t) m->header->body_size, align);
1061 end_body = start_body + sz;
1063 padding = start_body - m->header->body_size;
1064 added = padding + sz;
1066 /* Check for 32bit overflows */
1067 if (end_body > (size_t) ((uint32_t) -1)) {
1073 m->n_body_parts <= 0 ||
1074 m->body_end->sealed ||
1075 padding != ALIGN_TO(m->body_end->size, align) - m->body_end->size;
1079 part = message_append_part(m);
1083 part_zero(part, padding);
1086 part = message_append_part(m);
1090 r = part_make_space(m, part, sz, &p);
1094 struct bus_container *c;
1102 start_part = ALIGN_TO(part->size, align);
1103 end_part = start_part + sz;
1105 r = part_make_space(m, part, end_part, &p);
1110 memset(p, 0, padding);
1111 p = (uint8_t*) p + padding;
1114 /* Readjust pointers */
1115 for (c = m->containers; c < m->containers + m->n_containers; c++)
1116 c->array_size = adjust_pointer(c->array_size, op, os, part->data);
1118 m->error.message = (const char*) adjust_pointer(m->error.message, op, os, part->data);
1121 m->header->body_size = end_body;
1122 message_extend_containers(m, added);
1127 int message_append_basic(sd_bus_message *m, char type, const void *p, const void **stored) {
1128 struct bus_container *c;
1136 assert_return(m, -EINVAL);
1137 assert_return(!m->sealed, -EPERM);
1138 assert_return(bus_type_is_basic(type), -EINVAL);
1139 assert_return(!m->poisoned, -ESTALE);
1141 c = message_get_container(m);
1143 if (c->signature && c->signature[c->index]) {
1144 /* Container signature is already set */
1146 if (c->signature[c->index] != type)
1151 /* Maybe we can append to the signature? But only if this is the top-level container*/
1152 if (c->enclosing != 0)
1155 e = strextend(&c->signature, CHAR_TO_STR(type), NULL);
1164 case SD_BUS_TYPE_STRING:
1165 /* To make things easy we'll serialize a NULL string
1166 * into the empty string */
1169 /* Fall through... */
1170 case SD_BUS_TYPE_OBJECT_PATH:
1178 sz = 4 + strlen(p) + 1;
1181 case SD_BUS_TYPE_SIGNATURE:
1189 sz = 1 + strlen(p) + 1;
1192 case SD_BUS_TYPE_BOOLEAN:
1201 assert_cc(sizeof(int) == sizeof(uint32_t));
1207 case SD_BUS_TYPE_UNIX_FD: {
1215 if (!m->allow_fds) {
1228 fd = fcntl(z, F_DUPFD_CLOEXEC, 3);
1234 f = realloc(m->fds, sizeof(int) * (m->n_fds + 1));
1254 align = bus_type_get_alignment(type);
1255 sz = bus_type_get_size(type);
1262 a = message_extend_body(m, align, sz);
1268 if (type == SD_BUS_TYPE_STRING || type == SD_BUS_TYPE_OBJECT_PATH) {
1269 *(uint32_t*) a = sz - 5;
1270 memcpy((uint8_t*) a + 4, p, sz - 4);
1273 *stored = (const uint8_t*) a + 4;
1275 } else if (type == SD_BUS_TYPE_SIGNATURE) {
1276 *(uint8_t*) a = sz - 1;
1277 memcpy((uint8_t*) a + 1, p, sz - 1);
1280 *stored = (const uint8_t*) a + 1;
1281 } else if (type == SD_BUS_TYPE_UNIX_FD) {
1282 *(uint32_t*) a = fdi;
1296 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1303 close_nointr_nofail(fd);
1308 _public_ int sd_bus_message_append_basic(sd_bus_message *m, char type, const void *p) {
1309 return message_append_basic(m, type, p, NULL);
1312 _public_ int sd_bus_message_append_string_space(
1317 struct bus_container *c;
1320 assert_return(m, -EINVAL);
1321 assert_return(s, -EINVAL);
1322 assert_return(!m->sealed, -EPERM);
1323 assert_return(!m->poisoned, -ESTALE);
1325 c = message_get_container(m);
1327 if (c->signature && c->signature[c->index]) {
1328 /* Container signature is already set */
1330 if (c->signature[c->index] != SD_BUS_TYPE_STRING)
1335 /* Maybe we can append to the signature? But only if this is the top-level container*/
1336 if (c->enclosing != 0)
1339 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRING), NULL);
1346 a = message_extend_body(m, 4, 4 + size + 1);
1350 *(uint32_t*) a = size;
1355 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1361 _public_ int sd_bus_message_append_string_iovec(
1363 const struct iovec *iov,
1371 assert_return(m, -EINVAL);
1372 assert_return(!m->sealed, -EPERM);
1373 assert_return(iov || n == 0, -EINVAL);
1374 assert_return(!m->poisoned, -ESTALE);
1376 size = IOVEC_TOTAL_SIZE(iov, n);
1378 r = sd_bus_message_append_string_space(m, size, &p);
1382 for (i = 0; i < n; i++) {
1384 if (iov[i].iov_base)
1385 memcpy(p, iov[i].iov_base, iov[i].iov_len);
1387 memset(p, ' ', iov[i].iov_len);
1389 p += iov[i].iov_len;
1395 static int bus_message_open_array(
1397 struct bus_container *c,
1398 const char *contents,
1399 uint32_t **array_size) {
1405 struct bus_body_part *o;
1412 if (!signature_is_single(contents, true))
1415 alignment = bus_type_get_alignment(contents[0]);
1419 if (c->signature && c->signature[c->index]) {
1421 /* Verify the existing signature */
1423 if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
1426 if (!startswith(c->signature + c->index + 1, contents))
1429 nindex = c->index + 1 + strlen(contents);
1433 if (c->enclosing != 0)
1436 /* Extend the existing signature */
1438 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_ARRAY), contents, NULL);
1444 nindex = e - c->signature;
1447 a = message_extend_body(m, 4, 4);
1452 op = m->body_end->data;
1453 os = m->body_end->size;
1455 /* Add alignment between size and first element */
1456 if (!message_extend_body(m, alignment, 0))
1459 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1462 /* location of array size might have changed so let's readjust a */
1463 if (o == m->body_end)
1464 a = adjust_pointer(a, op, os, m->body_end->data);
1471 static int bus_message_open_variant(
1473 struct bus_container *c,
1474 const char *contents) {
1483 if (!signature_is_single(contents, false))
1486 if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
1489 if (c->signature && c->signature[c->index]) {
1491 if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
1497 if (c->enclosing != 0)
1500 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_VARIANT), NULL);
1507 l = strlen(contents);
1508 a = message_extend_body(m, 1, 1 + l + 1);
1513 memcpy((uint8_t*) a + 1, contents, l + 1);
1515 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1521 static int bus_message_open_struct(
1523 struct bus_container *c,
1524 const char *contents) {
1532 if (!signature_is_valid(contents, false))
1535 if (c->signature && c->signature[c->index]) {
1538 l = strlen(contents);
1540 if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
1541 !startswith(c->signature + c->index + 1, contents) ||
1542 c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
1545 nindex = c->index + 1 + l + 1;
1549 if (c->enclosing != 0)
1552 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_BEGIN), contents, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_END), NULL);
1558 nindex = e - c->signature;
1561 /* Align contents to 8 byte boundary */
1562 if (!message_extend_body(m, 8, 0))
1565 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1571 static int bus_message_open_dict_entry(
1573 struct bus_container *c,
1574 const char *contents) {
1582 if (!signature_is_pair(contents))
1585 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1588 if (c->signature && c->signature[c->index]) {
1591 l = strlen(contents);
1593 if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
1594 !startswith(c->signature + c->index + 1, contents) ||
1595 c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
1598 nindex = c->index + 1 + l + 1;
1602 /* Align contents to 8 byte boundary */
1603 if (!message_extend_body(m, 8, 0))
1606 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1612 _public_ int sd_bus_message_open_container(
1615 const char *contents) {
1617 struct bus_container *c, *w;
1618 uint32_t *array_size = NULL;
1623 assert_return(m, -EINVAL);
1624 assert_return(!m->sealed, -EPERM);
1625 assert_return(contents, -EINVAL);
1626 assert_return(!m->poisoned, -ESTALE);
1628 /* Make sure we have space for one more container */
1629 w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
1637 c = message_get_container(m);
1639 signature = strdup(contents);
1645 /* Save old index in the parent container, in case we have to
1646 * abort this container */
1647 c->saved_index = c->index;
1648 before = m->header->body_size;
1650 if (type == SD_BUS_TYPE_ARRAY)
1651 r = bus_message_open_array(m, c, contents, &array_size);
1652 else if (type == SD_BUS_TYPE_VARIANT)
1653 r = bus_message_open_variant(m, c, contents);
1654 else if (type == SD_BUS_TYPE_STRUCT)
1655 r = bus_message_open_struct(m, c, contents);
1656 else if (type == SD_BUS_TYPE_DICT_ENTRY)
1657 r = bus_message_open_dict_entry(m, c, contents);
1666 /* OK, let's fill it in */
1667 w += m->n_containers++;
1668 w->enclosing = type;
1669 w->signature = signature;
1671 w->array_size = array_size;
1673 w->begin = m->rindex;
1678 _public_ int sd_bus_message_close_container(sd_bus_message *m) {
1679 struct bus_container *c;
1681 assert_return(m, -EINVAL);
1682 assert_return(!m->sealed, -EPERM);
1683 assert_return(m->n_containers > 0, -EINVAL);
1684 assert_return(!m->poisoned, -ESTALE);
1686 c = message_get_container(m);
1687 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1688 if (c->signature && c->signature[c->index] != 0)
1703 static int type_stack_push(TypeStack *stack, unsigned max, unsigned *i, const char *types, unsigned n_struct, unsigned n_array) {
1710 stack[*i].types = types;
1711 stack[*i].n_struct = n_struct;
1712 stack[*i].n_array = n_array;
1718 static int type_stack_pop(TypeStack *stack, unsigned max, unsigned *i, const char **types, unsigned *n_struct, unsigned *n_array) {
1729 *types = stack[*i].types;
1730 *n_struct = stack[*i].n_struct;
1731 *n_array = stack[*i].n_array;
1736 int bus_message_append_ap(
1741 unsigned n_array, n_struct;
1742 TypeStack stack[BUS_CONTAINER_DEPTH];
1743 unsigned stack_ptr = 0;
1751 n_array = (unsigned) -1;
1752 n_struct = strlen(types);
1757 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
1758 r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
1764 r = sd_bus_message_close_container(m);
1772 if (n_array != (unsigned) -1)
1781 case SD_BUS_TYPE_BYTE: {
1784 x = (uint8_t) va_arg(ap, int);
1785 r = sd_bus_message_append_basic(m, *t, &x);
1789 case SD_BUS_TYPE_BOOLEAN:
1790 case SD_BUS_TYPE_INT32:
1791 case SD_BUS_TYPE_UINT32:
1792 case SD_BUS_TYPE_UNIX_FD: {
1795 /* We assume a boolean is the same as int32_t */
1796 assert_cc(sizeof(int32_t) == sizeof(int));
1798 x = va_arg(ap, uint32_t);
1799 r = sd_bus_message_append_basic(m, *t, &x);
1803 case SD_BUS_TYPE_INT16:
1804 case SD_BUS_TYPE_UINT16: {
1807 x = (uint16_t) va_arg(ap, int);
1808 r = sd_bus_message_append_basic(m, *t, &x);
1812 case SD_BUS_TYPE_INT64:
1813 case SD_BUS_TYPE_UINT64:
1814 case SD_BUS_TYPE_DOUBLE: {
1817 x = va_arg(ap, uint64_t);
1818 r = sd_bus_message_append_basic(m, *t, &x);
1822 case SD_BUS_TYPE_STRING:
1823 case SD_BUS_TYPE_OBJECT_PATH:
1824 case SD_BUS_TYPE_SIGNATURE: {
1827 x = va_arg(ap, const char*);
1828 r = sd_bus_message_append_basic(m, *t, x);
1832 case SD_BUS_TYPE_ARRAY: {
1835 r = signature_element_length(t + 1, &k);
1841 memcpy(s, t + 1, k);
1844 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, s);
1849 if (n_array == (unsigned) -1) {
1854 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
1860 n_array = va_arg(ap, unsigned);
1865 case SD_BUS_TYPE_VARIANT: {
1868 s = va_arg(ap, const char*);
1872 r = sd_bus_message_open_container(m, SD_BUS_TYPE_VARIANT, s);
1876 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
1881 n_struct = strlen(s);
1882 n_array = (unsigned) -1;
1887 case SD_BUS_TYPE_STRUCT_BEGIN:
1888 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
1891 r = signature_element_length(t, &k);
1898 memcpy(s, t + 1, k - 2);
1901 r = sd_bus_message_open_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
1906 if (n_array == (unsigned) -1) {
1911 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
1917 n_array = (unsigned) -1;
1933 _public_ int sd_bus_message_append(sd_bus_message *m, const char *types, ...) {
1937 assert_return(m, -EINVAL);
1938 assert_return(types, -EINVAL);
1939 assert_return(!m->sealed, -EPERM);
1940 assert_return(!m->poisoned, -ESTALE);
1942 va_start(ap, types);
1943 r = bus_message_append_ap(m, types, ap);
1949 _public_ int sd_bus_message_append_array_space(sd_bus_message *m,
1957 assert_return(m, -EINVAL);
1958 assert_return(!m->sealed, -EPERM);
1959 assert_return(bus_type_is_trivial(type), -EINVAL);
1960 assert_return(ptr || size == 0, -EINVAL);
1961 assert_return(!m->poisoned, -ESTALE);
1963 align = bus_type_get_alignment(type);
1964 sz = bus_type_get_size(type);
1966 assert_se(align > 0);
1972 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
1976 a = message_extend_body(m, align, size);
1980 r = sd_bus_message_close_container(m);
1988 _public_ int sd_bus_message_append_array(sd_bus_message *m,
1995 assert_return(m, -EINVAL);
1996 assert_return(!m->sealed, -EPERM);
1997 assert_return(bus_type_is_trivial(type), -EINVAL);
1998 assert_return(ptr || size == 0, -EINVAL);
1999 assert_return(!m->poisoned, -ESTALE);
2001 r = sd_bus_message_append_array_space(m, type, size, &p);
2006 memcpy(p, ptr, size);
2011 _public_ int sd_bus_message_append_array_iovec(
2014 const struct iovec *iov,
2022 assert_return(m, -EINVAL);
2023 assert_return(!m->sealed, -EPERM);
2024 assert_return(bus_type_is_trivial(type), -EINVAL);
2025 assert_return(iov || n == 0, -EINVAL);
2026 assert_return(!m->poisoned, -ESTALE);
2028 size = IOVEC_TOTAL_SIZE(iov, n);
2030 r = sd_bus_message_append_array_space(m, type, size, &p);
2034 for (i = 0; i < n; i++) {
2036 if (iov[i].iov_base)
2037 memcpy(p, iov[i].iov_base, iov[i].iov_len);
2039 memset(p, 0, iov[i].iov_len);
2041 p = (uint8_t*) p + iov[i].iov_len;
2047 _public_ int sd_bus_message_append_array_memfd(sd_bus_message *m,
2050 _cleanup_close_ int copy_fd = -1;
2051 struct bus_body_part *part;
2063 if (!bus_type_is_trivial(type))
2068 r = sd_memfd_set_sealed(memfd, true);
2072 copy_fd = sd_memfd_dup_fd(memfd);
2076 r = sd_memfd_get_size(memfd, &size);
2080 align = bus_type_get_alignment(type);
2081 sz = bus_type_get_size(type);
2083 assert_se(align > 0);
2089 if (size > (uint64_t) (uint32_t) -1)
2092 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
2096 a = message_extend_body(m, align, 0);
2100 part = message_append_part(m);
2104 part->memfd = copy_fd;
2105 part->sealed = true;
2109 message_extend_containers(m, size);
2110 m->header->body_size += size;
2112 return sd_bus_message_close_container(m);
2115 _public_ int sd_bus_message_append_string_memfd(sd_bus_message *m, sd_memfd *memfd) {
2116 _cleanup_close_ int copy_fd = -1;
2117 struct bus_body_part *part;
2118 struct bus_container *c;
2123 assert_return(m, -EINVAL);
2124 assert_return(memfd, -EINVAL);
2125 assert_return(!m->sealed, -EPERM);
2126 assert_return(!m->poisoned, -ESTALE);
2128 r = sd_memfd_set_sealed(memfd, true);
2132 copy_fd = sd_memfd_dup_fd(memfd);
2136 r = sd_memfd_get_size(memfd, &size);
2140 /* We require this to be NUL terminated */
2144 if (size > (uint64_t) (uint32_t) -1)
2147 c = message_get_container(m);
2148 if (c->signature && c->signature[c->index]) {
2149 /* Container signature is already set */
2151 if (c->signature[c->index] != SD_BUS_TYPE_STRING)
2156 /* Maybe we can append to the signature? But only if this is the top-level container*/
2157 if (c->enclosing != 0)
2160 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRING), NULL);
2167 a = message_extend_body(m, 4, 4);
2171 *(uint32_t*) a = size - 1;
2173 part = message_append_part(m);
2177 part->memfd = copy_fd;
2178 part->sealed = true;
2182 message_extend_containers(m, size);
2183 m->header->body_size += size;
2185 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2191 _public_ int sd_bus_message_append_strv(sd_bus_message *m, char **l) {
2195 assert_return(m, -EINVAL);
2196 assert_return(!m->sealed, -EPERM);
2197 assert_return(!m->poisoned, -ESTALE);
2199 r = sd_bus_message_open_container(m, 'a', "s");
2203 STRV_FOREACH(i, l) {
2204 r = sd_bus_message_append_basic(m, 's', *i);
2209 return sd_bus_message_close_container(m);
2212 int bus_body_part_map(struct bus_body_part *part) {
2221 if (part->size <= 0)
2224 /* For smaller zero parts (as used for padding) we don't need to map anything... */
2225 if (part->memfd < 0 && part->is_zero && part->size < 8) {
2226 static const uint8_t zeroes[7] = { };
2227 part->data = (void*) zeroes;
2231 psz = PAGE_ALIGN(part->size);
2233 if (part->memfd >= 0)
2234 p = mmap(NULL, psz, PROT_READ, MAP_SHARED, part->memfd, 0);
2235 else if (part->is_zero)
2236 p = mmap(NULL, psz, PROT_READ, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
2240 if (p == MAP_FAILED)
2245 part->munmap_this = true;
2250 void bus_body_part_unmap(struct bus_body_part *part) {
2254 if (part->memfd < 0)
2260 if (!part->munmap_this)
2263 assert_se(munmap(part->data, part->mapped) == 0);
2267 part->munmap_this = false;
2272 static int buffer_peek(const void *p, uint32_t sz, size_t *rindex, size_t align, size_t nbytes, void **r) {
2273 size_t k, start, end;
2278 start = ALIGN_TO((size_t) *rindex, align);
2279 end = start + nbytes;
2284 /* Verify that padding is 0 */
2285 for (k = *rindex; k < start; k++)
2286 if (((const uint8_t*) p)[k] != 0)
2290 *r = (uint8_t*) p + start;
2297 static bool message_end_of_signature(sd_bus_message *m) {
2298 struct bus_container *c;
2302 c = message_get_container(m);
2303 return !c->signature || c->signature[c->index] == 0;
2306 static bool message_end_of_array(sd_bus_message *m, size_t index) {
2307 struct bus_container *c;
2311 c = message_get_container(m);
2315 return index >= c->begin + BUS_MESSAGE_BSWAP32(m, *c->array_size);
2318 _public_ int sd_bus_message_at_end(sd_bus_message *m, int complete) {
2319 assert_return(m, -EINVAL);
2320 assert_return(m->sealed, -EPERM);
2322 if (complete && m->n_containers > 0)
2325 if (message_end_of_signature(m))
2328 if (message_end_of_array(m, m->rindex))
2334 static struct bus_body_part* find_part(sd_bus_message *m, size_t index, size_t sz, void **p) {
2335 struct bus_body_part *part;
2341 if (m->cached_rindex_part && index >= m->cached_rindex_part_begin) {
2342 part = m->cached_rindex_part;
2343 begin = m->cached_rindex_part_begin;
2353 if (index + sz <= begin + part->size) {
2355 r = bus_body_part_map(part);
2360 *p = (uint8_t*) part->data + index - begin;
2362 m->cached_rindex_part = part;
2363 m->cached_rindex_part_begin = begin;
2368 begin += part->size;
2375 static int message_peek_body(
2382 size_t k, start, end, padding;
2383 struct bus_body_part *part;
2390 if (message_end_of_array(m, *rindex))
2393 start = ALIGN_TO((size_t) *rindex, align);
2394 padding = start - *rindex;
2395 end = start + nbytes;
2397 if (end > BUS_MESSAGE_BODY_SIZE(m))
2400 part = find_part(m, *rindex, padding, (void**) &q);
2405 /* Verify padding */
2406 for (k = 0; k < padding; k++)
2411 part = find_part(m, start, nbytes, (void**) &q);
2423 static bool validate_nul(const char *s, size_t l) {
2425 /* Check for NUL chars in the string */
2426 if (memchr(s, 0, l))
2429 /* Check for NUL termination */
2436 static bool validate_string(const char *s, size_t l) {
2438 if (!validate_nul(s, l))
2441 /* Check if valid UTF8 */
2442 if (!utf8_is_valid(s))
2448 static bool validate_signature(const char *s, size_t l) {
2450 if (!validate_nul(s, l))
2453 /* Check if valid signature */
2454 if (!signature_is_valid(s, true))
2460 static bool validate_object_path(const char *s, size_t l) {
2462 if (!validate_nul(s, l))
2465 if (!object_path_is_valid(s))
2471 _public_ int sd_bus_message_read_basic(sd_bus_message *m, char type, void *p) {
2472 struct bus_container *c;
2476 assert_return(m, -EINVAL);
2477 assert_return(m->sealed, -EPERM);
2478 assert_return(bus_type_is_basic(type), -EINVAL);
2480 if (message_end_of_signature(m))
2483 if (message_end_of_array(m, m->rindex))
2486 c = message_get_container(m);
2487 if (c->signature[c->index] != type)
2492 case SD_BUS_TYPE_STRING:
2493 case SD_BUS_TYPE_OBJECT_PATH: {
2498 r = message_peek_body(m, &rindex, 4, 4, &q);
2502 l = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2503 r = message_peek_body(m, &rindex, 1, l+1, &q);
2509 if (type == SD_BUS_TYPE_OBJECT_PATH) {
2510 if (!validate_object_path(q, l))
2513 if (!validate_string(q, l))
2519 *(const char**) p = q;
2524 case SD_BUS_TYPE_SIGNATURE: {
2529 r = message_peek_body(m, &rindex, 1, 1, &q);
2534 r = message_peek_body(m, &rindex, 1, l+1, &q);
2540 if (!validate_signature(q, l))
2546 *(const char**) p = q;
2554 align = bus_type_get_alignment(type);
2555 sz = bus_type_get_size(type);
2556 assert(align > 0 && sz > 0);
2559 r = message_peek_body(m, &rindex, align, sz, &q);
2565 case SD_BUS_TYPE_BYTE:
2567 *(uint8_t*) p = *(uint8_t*) q;
2570 case SD_BUS_TYPE_BOOLEAN:
2572 *(int*) p = !!*(uint32_t*) q;
2575 case SD_BUS_TYPE_INT16:
2576 case SD_BUS_TYPE_UINT16:
2578 *(uint16_t*) p = BUS_MESSAGE_BSWAP16(m, *(uint16_t*) q);
2581 case SD_BUS_TYPE_INT32:
2582 case SD_BUS_TYPE_UINT32:
2584 *(uint32_t*) p = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2587 case SD_BUS_TYPE_INT64:
2588 case SD_BUS_TYPE_UINT64:
2589 case SD_BUS_TYPE_DOUBLE:
2591 *(uint64_t*) p = BUS_MESSAGE_BSWAP64(m, *(uint64_t*) q);
2594 case SD_BUS_TYPE_UNIX_FD: {
2597 j = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2602 *(int*) p = m->fds[j];
2607 assert_not_reached("Unknown basic type...");
2616 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2622 static int bus_message_enter_array(
2624 struct bus_container *c,
2625 const char *contents,
2626 uint32_t **array_size) {
2637 if (!signature_is_single(contents, true))
2640 alignment = bus_type_get_alignment(contents[0]);
2644 if (!c->signature || c->signature[c->index] == 0)
2647 if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
2650 if (!startswith(c->signature + c->index + 1, contents))
2654 r = message_peek_body(m, &rindex, 4, 4, &q);
2658 if (BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q) > BUS_ARRAY_MAX_SIZE)
2661 r = message_peek_body(m, &rindex, alignment, 0, NULL);
2667 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2668 c->index += 1 + strlen(contents);
2672 *array_size = (uint32_t*) q;
2677 static int bus_message_enter_variant(
2679 struct bus_container *c,
2680 const char *contents) {
2691 if (!signature_is_single(contents, false))
2694 if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
2697 if (!c->signature || c->signature[c->index] == 0)
2700 if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
2704 r = message_peek_body(m, &rindex, 1, 1, &q);
2709 r = message_peek_body(m, &rindex, 1, l+1, &q);
2715 if (!validate_signature(q, l))
2718 if (!streq(q, contents))
2721 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2729 static int bus_message_enter_struct(
2731 struct bus_container *c,
2732 const char *contents) {
2741 if (!signature_is_valid(contents, false))
2744 if (!c->signature || c->signature[c->index] == 0)
2747 l = strlen(contents);
2749 if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
2750 !startswith(c->signature + c->index + 1, contents) ||
2751 c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
2754 r = message_peek_body(m, &m->rindex, 8, 0, NULL);
2758 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2759 c->index += 1 + l + 1;
2764 static int bus_message_enter_dict_entry(
2766 struct bus_container *c,
2767 const char *contents) {
2776 if (!signature_is_pair(contents))
2779 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2782 if (!c->signature || c->signature[c->index] == 0)
2785 l = strlen(contents);
2787 if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
2788 !startswith(c->signature + c->index + 1, contents) ||
2789 c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
2792 r = message_peek_body(m, &m->rindex, 8, 0, NULL);
2796 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2797 c->index += 1 + l + 1;
2802 _public_ int sd_bus_message_enter_container(sd_bus_message *m,
2804 const char *contents) {
2805 struct bus_container *c, *w;
2806 uint32_t *array_size = NULL;
2811 assert_return(m, -EINVAL);
2812 assert_return(m->sealed, -EPERM);
2813 assert_return(type != 0 || !contents, -EINVAL);
2815 if (type == 0 || !contents) {
2819 /* Allow entering into anonymous containers */
2820 r = sd_bus_message_peek_type(m, &tt, &cc);
2824 if (type != 0 && type != tt)
2827 if (contents && !streq(contents, cc))
2835 * We enforce a global limit on container depth, that is much
2836 * higher than the 32 structs and 32 arrays the specification
2837 * mandates. This is simpler to implement for us, and we need
2838 * this only to ensure our container array doesn't grow
2839 * without bounds. We are happy to return any data from a
2840 * message as long as the data itself is valid, even if the
2841 * overall message might be not.
2843 * Note that the message signature is validated when
2844 * parsing the headers, and that validation does check the
2847 * Note that the specification defines no limits on the depth
2848 * of stacked variants, but we do.
2850 if (m->n_containers >= BUS_CONTAINER_DEPTH)
2853 w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
2858 if (message_end_of_signature(m))
2861 if (message_end_of_array(m, m->rindex))
2864 c = message_get_container(m);
2866 signature = strdup(contents);
2870 c->saved_index = c->index;
2873 if (type == SD_BUS_TYPE_ARRAY)
2874 r = bus_message_enter_array(m, c, contents, &array_size);
2875 else if (type == SD_BUS_TYPE_VARIANT)
2876 r = bus_message_enter_variant(m, c, contents);
2877 else if (type == SD_BUS_TYPE_STRUCT)
2878 r = bus_message_enter_struct(m, c, contents);
2879 else if (type == SD_BUS_TYPE_DICT_ENTRY)
2880 r = bus_message_enter_dict_entry(m, c, contents);
2889 /* OK, let's fill it in */
2890 w += m->n_containers++;
2891 w->enclosing = type;
2892 w->signature = signature;
2894 w->array_size = array_size;
2896 w->begin = m->rindex;
2901 _public_ int sd_bus_message_exit_container(sd_bus_message *m) {
2902 struct bus_container *c;
2904 assert_return(m, -EINVAL);
2905 assert_return(m->sealed, -EPERM);
2906 assert_return(m->n_containers > 0, -ENXIO);
2908 c = message_get_container(m);
2909 if (c->enclosing == SD_BUS_TYPE_ARRAY) {
2912 l = BUS_MESSAGE_BSWAP32(m, *c->array_size);
2913 if (c->begin + l != m->rindex)
2917 if (c->signature && c->signature[c->index] != 0)
2927 static void message_quit_container(sd_bus_message *m) {
2928 struct bus_container *c;
2932 assert(m->n_containers > 0);
2934 c = message_get_container(m);
2937 assert(m->rindex >= c->before);
2938 m->rindex = c->before;
2940 /* Free container */
2944 /* Correct index of new top-level container */
2945 c = message_get_container(m);
2946 c->index = c->saved_index;
2949 _public_ int sd_bus_message_peek_type(sd_bus_message *m, char *type, const char **contents) {
2950 struct bus_container *c;
2953 assert_return(m, -EINVAL);
2954 assert_return(m->sealed, -EPERM);
2956 if (message_end_of_signature(m))
2959 if (message_end_of_array(m, m->rindex))
2962 c = message_get_container(m);
2964 if (bus_type_is_basic(c->signature[c->index])) {
2968 *type = c->signature[c->index];
2972 if (c->signature[c->index] == SD_BUS_TYPE_ARRAY) {
2978 r = signature_element_length(c->signature+c->index+1, &l);
2984 sig = strndup(c->signature + c->index + 1, l);
2988 free(m->peeked_signature);
2989 m->peeked_signature = sig;
2995 *type = SD_BUS_TYPE_ARRAY;
3000 if (c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ||
3001 c->signature[c->index] == SD_BUS_TYPE_DICT_ENTRY_BEGIN) {
3007 r = signature_element_length(c->signature+c->index, &l);
3012 sig = strndup(c->signature + c->index + 1, l - 2);
3016 free(m->peeked_signature);
3017 m->peeked_signature = sig;
3023 *type = c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY;
3028 if (c->signature[c->index] == SD_BUS_TYPE_VARIANT) {
3034 r = message_peek_body(m, &rindex, 1, 1, &q);
3041 r = message_peek_body(m, &rindex, 1, l+1, &q);
3047 if (!validate_signature(q, l))
3054 *type = SD_BUS_TYPE_VARIANT;
3069 _public_ int sd_bus_message_rewind(sd_bus_message *m, int complete) {
3070 struct bus_container *c;
3072 assert_return(m, -EINVAL);
3073 assert_return(m->sealed, -EPERM);
3076 message_reset_containers(m);
3078 m->root_container.index = 0;
3080 c = message_get_container(m);
3082 c = message_get_container(m);
3085 m->rindex = c->begin;
3088 return !isempty(c->signature);
3091 static int message_read_ap(
3096 unsigned n_array, n_struct;
3097 TypeStack stack[BUS_CONTAINER_DEPTH];
3098 unsigned stack_ptr = 0;
3099 unsigned n_loop = 0;
3107 /* Ideally, we'd just call ourselves recursively on every
3108 * complex type. However, the state of a va_list that is
3109 * passed to a function is undefined after that function
3110 * returns. This means we need to docode the va_list linearly
3111 * in a single stackframe. We hence implement our own
3112 * home-grown stack in an array. */
3114 n_array = (unsigned) -1; /* lenght of current array entries */
3115 n_struct = strlen(types); /* length of current struct contents signature */
3122 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
3123 r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
3129 r = sd_bus_message_exit_container(m);
3137 if (n_array != (unsigned) -1)
3146 case SD_BUS_TYPE_BYTE:
3147 case SD_BUS_TYPE_BOOLEAN:
3148 case SD_BUS_TYPE_INT16:
3149 case SD_BUS_TYPE_UINT16:
3150 case SD_BUS_TYPE_INT32:
3151 case SD_BUS_TYPE_UINT32:
3152 case SD_BUS_TYPE_INT64:
3153 case SD_BUS_TYPE_UINT64:
3154 case SD_BUS_TYPE_DOUBLE:
3155 case SD_BUS_TYPE_STRING:
3156 case SD_BUS_TYPE_OBJECT_PATH:
3157 case SD_BUS_TYPE_SIGNATURE:
3158 case SD_BUS_TYPE_UNIX_FD: {
3161 p = va_arg(ap, void*);
3162 r = sd_bus_message_read_basic(m, *t, p);
3175 case SD_BUS_TYPE_ARRAY: {
3178 r = signature_element_length(t + 1, &k);
3184 memcpy(s, t + 1, k);
3187 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, s);
3198 if (n_array == (unsigned) -1) {
3203 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
3209 n_array = va_arg(ap, unsigned);
3214 case SD_BUS_TYPE_VARIANT: {
3217 s = va_arg(ap, const char *);
3221 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, s);
3231 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
3236 n_struct = strlen(s);
3237 n_array = (unsigned) -1;
3242 case SD_BUS_TYPE_STRUCT_BEGIN:
3243 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
3246 r = signature_element_length(t, &k);
3252 memcpy(s, t + 1, k - 2);
3255 r = sd_bus_message_enter_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
3265 if (n_array == (unsigned) -1) {
3270 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
3276 n_array = (unsigned) -1;
3289 _public_ int sd_bus_message_read(sd_bus_message *m, const char *types, ...) {
3293 assert_return(m, -EINVAL);
3294 assert_return(m->sealed, -EPERM);
3295 assert_return(types, -EINVAL);
3297 va_start(ap, types);
3298 r = message_read_ap(m, types, ap);
3304 _public_ int sd_bus_message_skip(sd_bus_message *m, const char *types) {
3307 assert_return(m, -EINVAL);
3308 assert_return(m->sealed, -EPERM);
3309 assert_return(types, -EINVAL);
3316 case SD_BUS_TYPE_BYTE:
3317 case SD_BUS_TYPE_BOOLEAN:
3318 case SD_BUS_TYPE_INT16:
3319 case SD_BUS_TYPE_UINT16:
3320 case SD_BUS_TYPE_INT32:
3321 case SD_BUS_TYPE_UINT32:
3322 case SD_BUS_TYPE_INT64:
3323 case SD_BUS_TYPE_UINT64:
3324 case SD_BUS_TYPE_DOUBLE:
3325 case SD_BUS_TYPE_STRING:
3326 case SD_BUS_TYPE_OBJECT_PATH:
3327 case SD_BUS_TYPE_SIGNATURE:
3328 case SD_BUS_TYPE_UNIX_FD:
3330 r = sd_bus_message_read_basic(m, *types, NULL);
3334 r = sd_bus_message_skip(m, types + 1);
3340 case SD_BUS_TYPE_ARRAY: {
3343 r = signature_element_length(types + 1, &k);
3349 memcpy(s, types+1, k);
3352 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, s);
3357 r = sd_bus_message_skip(m, s);
3364 r = sd_bus_message_exit_container(m);
3369 r = sd_bus_message_skip(m, types + 1 + k);
3376 case SD_BUS_TYPE_VARIANT: {
3377 const char *contents;
3380 r = sd_bus_message_peek_type(m, &x, &contents);
3384 if (x != SD_BUS_TYPE_VARIANT)
3387 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, contents);
3391 r = sd_bus_message_skip(m, contents);
3396 r = sd_bus_message_exit_container(m);
3400 r = sd_bus_message_skip(m, types + 1);
3407 case SD_BUS_TYPE_STRUCT_BEGIN:
3408 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
3411 r = signature_element_length(types, &k);
3417 memcpy(s, types+1, k-2);
3420 r = sd_bus_message_enter_container(m, *types == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
3424 r = sd_bus_message_skip(m, s);
3429 r = sd_bus_message_exit_container(m);
3434 r = sd_bus_message_skip(m, types + k);
3446 _public_ int sd_bus_message_read_array(sd_bus_message *m,
3450 struct bus_container *c;
3456 assert_return(m, -EINVAL);
3457 assert_return(m->sealed, -EPERM);
3458 assert_return(bus_type_is_trivial(type), -EINVAL);
3459 assert_return(ptr, -EINVAL);
3460 assert_return(size, -EINVAL);
3461 assert_return(!BUS_MESSAGE_NEED_BSWAP(m), -ENOTSUP);
3463 align = bus_type_get_alignment(type);
3467 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
3471 c = message_get_container(m);
3472 sz = BUS_MESSAGE_BSWAP32(m, *c->array_size);
3475 /* Zero length array, let's return some aligned
3476 * pointer that is not NULL */
3477 p = (uint8_t*) NULL + align;
3479 r = message_peek_body(m, &m->rindex, align, sz, &p);
3488 r = sd_bus_message_exit_container(m);
3492 *ptr = (const void*) p;
3498 message_quit_container(m);
3502 static int message_peek_fields(
3513 return buffer_peek(BUS_MESSAGE_FIELDS(m), BUS_MESSAGE_FIELDS_SIZE(m), rindex, align, nbytes, ret);
3516 static int message_peek_field_uint32(
3527 r = message_peek_fields(m, ri, 4, 4, &q);
3532 *ret = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
3537 static int message_peek_field_string(
3539 bool (*validate)(const char *p),
3550 r = message_peek_field_uint32(m, ri, &l);
3554 r = message_peek_fields(m, ri, 1, l+1, &q);
3559 if (!validate_nul(q, l))
3565 if (!validate_string(q, l))
3575 static int message_peek_field_signature(
3587 r = message_peek_fields(m, ri, 1, 1, &q);
3592 r = message_peek_fields(m, ri, 1, l+1, &q);
3596 if (!validate_signature(q, l))
3605 static int message_skip_fields(
3608 uint32_t array_size,
3609 const char **signature) {
3611 size_t original_index;
3618 original_index = *ri;
3624 if (array_size != (uint32_t) -1 &&
3625 array_size <= *ri - original_index)
3632 if (t == SD_BUS_TYPE_STRING) {
3634 r = message_peek_field_string(m, NULL, ri, NULL);
3640 } else if (t == SD_BUS_TYPE_OBJECT_PATH) {
3642 r = message_peek_field_string(m, object_path_is_valid, ri, NULL);
3648 } else if (t == SD_BUS_TYPE_SIGNATURE) {
3650 r = message_peek_field_signature(m, ri, NULL);
3656 } else if (bus_type_is_basic(t)) {
3659 align = bus_type_get_alignment(t);
3660 k = bus_type_get_size(t);
3661 assert(align > 0 && k > 0);
3663 r = message_peek_fields(m, ri, align, k, NULL);
3669 } else if (t == SD_BUS_TYPE_ARRAY) {
3671 r = signature_element_length(*signature+1, &l);
3681 strncpy(sig, *signature + 1, l-1);
3684 alignment = bus_type_get_alignment(sig[0]);
3688 r = message_peek_field_uint32(m, ri, &nas);
3691 if (nas > BUS_ARRAY_MAX_SIZE)
3694 r = message_peek_fields(m, ri, alignment, 0, NULL);
3698 r = message_skip_fields(m, ri, nas, (const char**) &s);
3703 (*signature) += 1 + l;
3705 } else if (t == SD_BUS_TYPE_VARIANT) {
3708 r = message_peek_field_signature(m, ri, &s);
3712 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
3718 } else if (t == SD_BUS_TYPE_STRUCT ||
3719 t == SD_BUS_TYPE_DICT_ENTRY) {
3721 r = signature_element_length(*signature, &l);
3728 strncpy(sig, *signature + 1, l-1);
3731 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
3742 int bus_message_parse_fields(sd_bus_message *m) {
3745 uint32_t unix_fds = 0;
3749 for (ri = 0; ri < BUS_MESSAGE_FIELDS_SIZE(m); ) {
3750 const char *signature;
3753 r = message_peek_fields(m, &ri, 8, 1, (void**) &header);
3757 r = message_peek_field_signature(m, &ri, &signature);
3762 case _SD_BUS_MESSAGE_HEADER_INVALID:
3765 case SD_BUS_MESSAGE_HEADER_PATH:
3770 if (!streq(signature, "o"))
3773 r = message_peek_field_string(m, object_path_is_valid, &ri, &m->path);
3776 case SD_BUS_MESSAGE_HEADER_INTERFACE:
3781 if (!streq(signature, "s"))
3784 r = message_peek_field_string(m, interface_name_is_valid, &ri, &m->interface);
3787 case SD_BUS_MESSAGE_HEADER_MEMBER:
3792 if (!streq(signature, "s"))
3795 r = message_peek_field_string(m, member_name_is_valid, &ri, &m->member);
3798 case SD_BUS_MESSAGE_HEADER_ERROR_NAME:
3803 if (!streq(signature, "s"))
3806 r = message_peek_field_string(m, error_name_is_valid, &ri, &m->error.name);
3809 case SD_BUS_MESSAGE_HEADER_DESTINATION:
3814 if (!streq(signature, "s"))
3817 r = message_peek_field_string(m, service_name_is_valid, &ri, &m->destination);
3820 case SD_BUS_MESSAGE_HEADER_SENDER:
3825 if (!streq(signature, "s"))
3828 r = message_peek_field_string(m, service_name_is_valid, &ri, &m->sender);
3832 case SD_BUS_MESSAGE_HEADER_SIGNATURE: {
3836 if (m->root_container.signature)
3839 if (!streq(signature, "g"))
3842 r = message_peek_field_signature(m, &ri, &s);
3850 free(m->root_container.signature);
3851 m->root_container.signature = c;
3855 case SD_BUS_MESSAGE_HEADER_REPLY_SERIAL:
3856 if (m->reply_serial != 0)
3859 if (!streq(signature, "u"))
3862 r = message_peek_field_uint32(m, &ri, &m->reply_serial);
3866 if (m->reply_serial == 0)
3871 case SD_BUS_MESSAGE_HEADER_UNIX_FDS:
3875 if (!streq(signature, "u"))
3878 r = message_peek_field_uint32(m, &ri, &unix_fds);
3888 r = message_skip_fields(m, &ri, (uint32_t) -1, (const char **) &signature);
3895 if (m->n_fds != unix_fds)
3898 if (isempty(m->root_container.signature) != (BUS_MESSAGE_BODY_SIZE(m) == 0))
3901 switch (m->header->type) {
3903 case SD_BUS_MESSAGE_SIGNAL:
3904 if (!m->path || !m->interface || !m->member)
3908 case SD_BUS_MESSAGE_METHOD_CALL:
3910 if (!m->path || !m->member)
3915 case SD_BUS_MESSAGE_METHOD_RETURN:
3917 if (m->reply_serial == 0)
3921 case SD_BUS_MESSAGE_METHOD_ERROR:
3923 if (m->reply_serial == 0 || !m->error.name)
3928 /* Try to read the error message, but if we can't it's a non-issue */
3929 if (m->header->type == SD_BUS_MESSAGE_METHOD_ERROR)
3930 sd_bus_message_read(m, "s", &m->error.message);
3935 int bus_message_seal(sd_bus_message *m, uint64_t serial) {
3936 struct bus_body_part *part;
3946 if (m->n_containers > 0)
3952 /* If there's a non-trivial signature set, then add it in here */
3953 if (!isempty(m->root_container.signature)) {
3954 r = message_append_field_signature(m, SD_BUS_MESSAGE_HEADER_SIGNATURE, m->root_container.signature, NULL);
3960 r = message_append_field_uint32(m, SD_BUS_MESSAGE_HEADER_UNIX_FDS, m->n_fds);
3965 /* Add padding at the end of the fields part, since we know
3966 * the body needs to start at an 8 byte alignment. We made
3967 * sure we allocated enough space for this, so all we need to
3968 * do here is to zero it out. */
3969 l = BUS_MESSAGE_FIELDS_SIZE(m);
3972 memset((uint8_t*) BUS_MESSAGE_FIELDS(m) + l, 0, a);
3974 /* If this is something we can send as memfd, then let's seal
3975 the memfd now. Note that we can send memfds as payload only
3976 for directed messages, and not for broadcasts. */
3977 if (m->destination && m->bus && m->bus->use_memfd) {
3978 MESSAGE_FOREACH_PART(part, i, m)
3979 if (part->memfd >= 0 && !part->sealed && (part->size > MEMFD_MIN_SIZE || m->bus->use_memfd < 0)) {
3980 bus_body_part_unmap(part);
3982 if (ioctl(part->memfd, KDBUS_CMD_MEMFD_SEAL_SET, 1) >= 0)
3983 part->sealed = true;
3987 m->header->serial = serial;
3993 _public_ int sd_bus_message_set_destination(sd_bus_message *m, const char *destination) {
3994 assert_return(m, -EINVAL);
3995 assert_return(destination, -EINVAL);
3996 assert_return(!m->sealed, -EPERM);
3997 assert_return(!m->destination, -EEXIST);
3999 return message_append_field_string(m, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &m->destination);
4002 int bus_message_get_blob(sd_bus_message *m, void **buffer, size_t *sz) {
4006 struct bus_body_part *part;
4012 total = BUS_MESSAGE_SIZE(m);
4018 e = mempcpy(p, m->header, BUS_MESSAGE_BODY_BEGIN(m));
4019 MESSAGE_FOREACH_PART(part, i, m)
4020 e = mempcpy(e, part->data, part->size);
4022 assert(total == (size_t) ((uint8_t*) e - (uint8_t*) p));
4030 int bus_message_read_strv_extend(sd_bus_message *m, char ***l) {
4036 r = sd_bus_message_enter_container(m, 'a', "s");
4043 r = sd_bus_message_read_basic(m, 's', &s);
4049 r = strv_extend(l, s);
4054 r = sd_bus_message_exit_container(m);
4061 _public_ int sd_bus_message_read_strv(sd_bus_message *m, char ***l) {
4065 assert_return(m, -EINVAL);
4066 assert_return(m->sealed, -EPERM);
4067 assert_return(l, -EINVAL);
4069 r = bus_message_read_strv_extend(m, &strv);
4079 const char* bus_message_get_arg(sd_bus_message *m, unsigned i) {
4081 const char *t = NULL;
4086 r = sd_bus_message_rewind(m, true);
4090 for (j = 0; j <= i; j++) {
4093 r = sd_bus_message_peek_type(m, &type, NULL);
4097 if (type != SD_BUS_TYPE_STRING &&
4098 type != SD_BUS_TYPE_OBJECT_PATH &&
4099 type != SD_BUS_TYPE_SIGNATURE)
4102 r = sd_bus_message_read_basic(m, type, &t);
4110 bool bus_header_is_complete(struct bus_header *h, size_t size) {
4116 if (size < sizeof(struct bus_header))
4119 full = sizeof(struct bus_header) +
4120 (h->endian == SD_BUS_NATIVE_ENDIAN ? h->fields_size : bswap_32(h->fields_size));
4122 return size >= full;
4125 int bus_header_message_size(struct bus_header *h, size_t *sum) {
4131 if (h->endian == SD_BUS_NATIVE_ENDIAN) {
4132 fs = h->fields_size;
4134 } else if (h->endian == SD_BUS_REVERSE_ENDIAN) {
4135 fs = bswap_32(h->fields_size);
4136 bs = bswap_32(h->body_size);
4140 *sum = sizeof(struct bus_header) + ALIGN8(fs) + bs;
4144 _public_ int sd_bus_message_get_errno(sd_bus_message *m) {
4145 assert_return(m, -EINVAL);
4147 if (m->header->type != SD_BUS_MESSAGE_METHOD_ERROR)
4150 return sd_bus_error_get_errno(&m->error);
4153 _public_ const char* sd_bus_message_get_signature(sd_bus_message *m, int complete) {
4154 struct bus_container *c;
4156 assert_return(m, NULL);
4158 c = complete ? &m->root_container : message_get_container(m);
4159 return c->signature ?: "";
4162 _public_ int sd_bus_message_copy(sd_bus_message *m, sd_bus_message *source, int all) {
4163 bool done_something = false;
4166 assert_return(m, -EINVAL);
4167 assert_return(source, -EINVAL);
4168 assert_return(!m->sealed, -EPERM);
4169 assert_return(source->sealed, -EPERM);
4172 const char *contents;
4187 r = sd_bus_message_peek_type(source, &type, &contents);
4193 done_something = true;
4195 if (bus_type_is_container(type) > 0) {
4197 r = sd_bus_message_enter_container(source, type, contents);
4201 r = sd_bus_message_open_container(m, type, contents);
4205 r = sd_bus_message_copy(m, source, true);
4209 r = sd_bus_message_close_container(m);
4213 r = sd_bus_message_exit_container(source);
4220 r = sd_bus_message_read_basic(source, type, &basic);
4226 if (type == SD_BUS_TYPE_OBJECT_PATH ||
4227 type == SD_BUS_TYPE_SIGNATURE ||
4228 type == SD_BUS_TYPE_STRING)
4229 r = sd_bus_message_append_basic(m, type, basic.string);
4231 r = sd_bus_message_append_basic(m, type, &basic);
4238 return done_something;
4241 _public_ int sd_bus_message_verify_type(sd_bus_message *m, char type, const char *contents) {
4246 assert_return(m, -EINVAL);
4247 assert_return(m->sealed, -EPERM);
4248 assert_return(!type || bus_type_is_valid(type), -EINVAL);
4249 assert_return(!contents || signature_is_valid(contents, true), -EINVAL);
4250 assert_return(type || contents, -EINVAL);
4251 assert_return(!contents || !type || bus_type_is_container(type), -EINVAL);
4253 r = sd_bus_message_peek_type(m, &t, &c);
4257 if (type != 0 && type != t)
4260 if (contents && !streq_ptr(contents, c))
4266 _public_ sd_bus *sd_bus_message_get_bus(sd_bus_message *m) {
4267 assert_return(m, NULL);