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) {
390 r = bus_message_from_header(bus, buffer, length, fds, n_fds, ucred, label, 0, &m);
394 if (length != BUS_MESSAGE_SIZE(m)) {
400 m->body.data = (uint8_t*) buffer + sizeof(struct bus_header) + ALIGN8(BUS_MESSAGE_FIELDS_SIZE(m));
401 m->body.size = length - sizeof(struct bus_header) - ALIGN8(BUS_MESSAGE_FIELDS_SIZE(m));
402 m->body.sealed = true;
406 m->iovec = m->iovec_fixed;
407 m->iovec[0].iov_base = buffer;
408 m->iovec[0].iov_len = length;
410 r = bus_message_parse_fields(m);
414 /* We take possession of the memory and fds now */
415 m->free_header = true;
426 static sd_bus_message *message_new(sd_bus *bus, uint8_t type) {
429 m = malloc0(ALIGN(sizeof(sd_bus_message)) + sizeof(struct bus_header));
434 m->header = (struct bus_header*) ((uint8_t*) m + ALIGN(sizeof(struct sd_bus_message)));
435 m->header->endian = SD_BUS_NATIVE_ENDIAN;
436 m->header->type = type;
437 m->header->version = bus ? bus->message_version : 1;
438 m->allow_fds = !bus || bus->can_fds || (bus->state != BUS_HELLO && bus->state != BUS_RUNNING);
441 m->bus = sd_bus_ref(bus);
446 _public_ int sd_bus_message_new_signal(
449 const char *interface,
451 sd_bus_message **m) {
456 assert_return(!bus || bus->state != BUS_UNSET, -ENOTCONN);
457 assert_return(object_path_is_valid(path), -EINVAL);
458 assert_return(interface_name_is_valid(interface), -EINVAL);
459 assert_return(member_name_is_valid(member), -EINVAL);
460 assert_return(m, -EINVAL);
462 t = message_new(bus, SD_BUS_MESSAGE_SIGNAL);
466 t->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
468 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_PATH, SD_BUS_TYPE_OBJECT_PATH, path, &t->path);
471 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_INTERFACE, SD_BUS_TYPE_STRING, interface, &t->interface);
474 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_MEMBER, SD_BUS_TYPE_STRING, member, &t->member);
482 sd_bus_message_unref(t);
486 _public_ int sd_bus_message_new_method_call(
488 const char *destination,
490 const char *interface,
492 sd_bus_message **m) {
497 assert_return(!bus || bus->state != BUS_UNSET, -ENOTCONN);
498 assert_return(!destination || service_name_is_valid(destination), -EINVAL);
499 assert_return(object_path_is_valid(path), -EINVAL);
500 assert_return(!interface || interface_name_is_valid(interface), -EINVAL);
501 assert_return(member_name_is_valid(member), -EINVAL);
502 assert_return(m, -EINVAL);
504 t = message_new(bus, SD_BUS_MESSAGE_METHOD_CALL);
508 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_PATH, SD_BUS_TYPE_OBJECT_PATH, path, &t->path);
511 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_MEMBER, SD_BUS_TYPE_STRING, member, &t->member);
516 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_INTERFACE, SD_BUS_TYPE_STRING, interface, &t->interface);
522 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &t->destination);
535 static int message_new_reply(
536 sd_bus_message *call,
538 sd_bus_message **m) {
543 assert_return(call, -EINVAL);
544 assert_return(call->sealed, -EPERM);
545 assert_return(call->header->type == SD_BUS_MESSAGE_METHOD_CALL, -EINVAL);
546 assert_return(!call->bus || call->bus->state != BUS_UNSET, -ENOTCONN);
547 assert_return(m, -EINVAL);
549 t = message_new(call->bus, type);
553 t->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
554 t->reply_serial = BUS_MESSAGE_SERIAL(call);
556 r = message_append_field_uint32(t, SD_BUS_MESSAGE_HEADER_REPLY_SERIAL, t->reply_serial);
561 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, call->sender, &t->destination);
566 t->dont_send = !!(call->header->flags & SD_BUS_MESSAGE_NO_REPLY_EXPECTED);
576 _public_ int sd_bus_message_new_method_return(
577 sd_bus_message *call,
578 sd_bus_message **m) {
580 return message_new_reply(call, SD_BUS_MESSAGE_METHOD_RETURN, m);
583 _public_ int sd_bus_message_new_method_error(
584 sd_bus_message *call,
585 const sd_bus_error *e,
586 sd_bus_message **m) {
591 assert_return(sd_bus_error_is_set(e), -EINVAL);
592 assert_return(m, -EINVAL);
594 r = message_new_reply(call, SD_BUS_MESSAGE_METHOD_ERROR, &t);
598 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_ERROR_NAME, SD_BUS_TYPE_STRING, e->name, &t->error.name);
603 r = message_append_basic(t, SD_BUS_TYPE_STRING, e->message, (const void**) &t->error.message);
616 _public_ int sd_bus_message_new_method_errorf(
617 sd_bus_message *call,
623 _cleanup_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
626 assert_return(name, -EINVAL);
627 assert_return(m, -EINVAL);
629 va_start(ap, format);
630 bus_error_setfv(&error, name, format, ap);
633 return sd_bus_message_new_method_error(call, &error, m);
636 _public_ int sd_bus_message_new_method_errno(
637 sd_bus_message *call,
639 const sd_bus_error *p,
640 sd_bus_message **m) {
642 _cleanup_free_ sd_bus_error berror = SD_BUS_ERROR_NULL;
644 if (sd_bus_error_is_set(p))
645 return sd_bus_message_new_method_error(call, p, m);
647 sd_bus_error_set_errno(&berror, error);
649 return sd_bus_message_new_method_error(call, &berror, m);
652 _public_ int sd_bus_message_new_method_errnof(
653 sd_bus_message *call,
659 _cleanup_free_ sd_bus_error berror = SD_BUS_ERROR_NULL;
662 va_start(ap, format);
663 bus_error_set_errnofv(&berror, error, format, ap);
666 return sd_bus_message_new_method_error(call, &berror, m);
669 int bus_message_new_synthetic_error(
672 const sd_bus_error *e,
673 sd_bus_message **m) {
678 assert(sd_bus_error_is_set(e));
681 t = message_new(bus, SD_BUS_MESSAGE_METHOD_ERROR);
685 t->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
686 t->reply_serial = serial;
688 r = message_append_field_uint32(t, SD_BUS_MESSAGE_HEADER_REPLY_SERIAL, t->reply_serial);
692 if (bus && bus->unique_name) {
693 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, bus->unique_name, &t->destination);
698 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_ERROR_NAME, SD_BUS_TYPE_STRING, e->name, &t->error.name);
703 r = message_append_basic(t, SD_BUS_TYPE_STRING, e->message, (const void**) &t->error.message);
716 _public_ sd_bus_message* sd_bus_message_ref(sd_bus_message *m) {
717 assert_return(m, NULL);
719 assert(m->n_ref > 0);
725 _public_ sd_bus_message* sd_bus_message_unref(sd_bus_message *m) {
726 assert_return(m, NULL);
728 assert(m->n_ref > 0);
737 _public_ int sd_bus_message_get_type(sd_bus_message *m, uint8_t *type) {
738 assert_return(m, -EINVAL);
739 assert_return(type, -EINVAL);
741 *type = m->header->type;
745 _public_ int sd_bus_message_get_serial(sd_bus_message *m, uint64_t *serial) {
746 assert_return(m, -EINVAL);
747 assert_return(serial, -EINVAL);
748 assert_return(m->header->serial != 0, -ENOENT);
750 *serial = BUS_MESSAGE_SERIAL(m);
754 _public_ int sd_bus_message_get_reply_serial(sd_bus_message *m, uint64_t *serial) {
755 assert_return(m, -EINVAL);
756 assert_return(serial, -EINVAL);
757 assert_return(m->reply_serial != 0, -ENOENT);
759 *serial = m->reply_serial;
763 _public_ int sd_bus_message_get_no_reply(sd_bus_message *m) {
764 assert_return(m, -EINVAL);
766 return m->header->type == SD_BUS_MESSAGE_METHOD_CALL ? !!(m->header->flags & SD_BUS_MESSAGE_NO_REPLY_EXPECTED) : 0;
769 _public_ int sd_bus_message_get_no_auto_start(sd_bus_message *m) {
770 assert_return(m, -EINVAL);
772 return !!(m->header->flags & SD_BUS_MESSAGE_NO_AUTO_START);
775 _public_ const char *sd_bus_message_get_path(sd_bus_message *m) {
776 assert_return(m, NULL);
781 _public_ const char *sd_bus_message_get_interface(sd_bus_message *m) {
782 assert_return(m, NULL);
787 _public_ const char *sd_bus_message_get_member(sd_bus_message *m) {
788 assert_return(m, NULL);
793 _public_ const char *sd_bus_message_get_destination(sd_bus_message *m) {
794 assert_return(m, NULL);
796 return m->destination;
799 _public_ const char *sd_bus_message_get_sender(sd_bus_message *m) {
800 assert_return(m, NULL);
805 _public_ const sd_bus_error *sd_bus_message_get_error(sd_bus_message *m) {
806 assert_return(m, NULL);
807 assert_return(sd_bus_error_is_set(&m->error), NULL);
812 _public_ int sd_bus_message_get_monotonic_timestamp(sd_bus_message *m, uint64_t *usec) {
813 assert_return(m, -EINVAL);
814 assert_return(usec, -EINVAL);
815 assert_return(m->monotonic > 0, -ENODATA);
817 *usec = m->monotonic;
821 _public_ int sd_bus_message_get_realtime_timestamp(sd_bus_message *m, uint64_t *usec) {
822 assert_return(m, -EINVAL);
823 assert_return(usec, -EINVAL);
824 assert_return(m->realtime > 0, -ENODATA);
830 _public_ sd_bus_creds *sd_bus_message_get_creds(sd_bus_message *m) {
831 assert_return(m, NULL);
833 if (m->creds.mask == 0)
839 _public_ int sd_bus_message_is_signal(sd_bus_message *m,
840 const char *interface,
841 const char *member) {
842 assert_return(m, -EINVAL);
844 if (m->header->type != SD_BUS_MESSAGE_SIGNAL)
847 if (interface && (!m->interface || !streq(m->interface, interface)))
850 if (member && (!m->member || !streq(m->member, member)))
856 _public_ int sd_bus_message_is_method_call(sd_bus_message *m,
857 const char *interface,
858 const char *member) {
859 assert_return(m, -EINVAL);
861 if (m->header->type != SD_BUS_MESSAGE_METHOD_CALL)
864 if (interface && (!m->interface || !streq(m->interface, interface)))
867 if (member && (!m->member || !streq(m->member, member)))
873 _public_ int sd_bus_message_is_method_error(sd_bus_message *m, const char *name) {
874 assert_return(m, -EINVAL);
876 if (m->header->type != SD_BUS_MESSAGE_METHOD_ERROR)
879 if (name && (!m->error.name || !streq(m->error.name, name)))
885 _public_ int sd_bus_message_set_no_reply(sd_bus_message *m, int b) {
886 assert_return(m, -EINVAL);
887 assert_return(!m->sealed, -EPERM);
888 assert_return(m->header->type == SD_BUS_MESSAGE_METHOD_CALL, -EPERM);
891 m->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
893 m->header->flags &= ~SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
898 _public_ int sd_bus_message_set_no_auto_start(sd_bus_message *m, int b) {
899 assert_return(m, -EINVAL);
900 assert_return(!m->sealed, -EPERM);
903 m->header->flags |= SD_BUS_MESSAGE_NO_AUTO_START;
905 m->header->flags &= ~SD_BUS_MESSAGE_NO_AUTO_START;
910 static struct bus_container *message_get_container(sd_bus_message *m) {
913 if (m->n_containers == 0)
914 return &m->root_container;
916 assert(m->containers);
917 return m->containers + m->n_containers - 1;
920 struct bus_body_part *message_append_part(sd_bus_message *m) {
921 struct bus_body_part *part;
928 if (m->n_body_parts <= 0) {
934 part = new0(struct bus_body_part, 1);
940 m->body_end->next = part;
950 static void part_zero(struct bus_body_part *part, size_t sz) {
955 /* All other fields can be left in their defaults */
957 assert(part->memfd < 0);
960 part->is_zero = true;
964 static int part_make_space(
965 struct sd_bus_message *m,
966 struct bus_body_part *part,
975 assert(!part->sealed);
980 if (!part->data && part->memfd < 0)
981 part->memfd = bus_kernel_pop_memfd(m->bus, &part->data, &part->mapped);
983 if (part->memfd >= 0) {
986 r = ioctl(part->memfd, KDBUS_CMD_MEMFD_SIZE_SET, &u);
992 if (!part->data || sz > part->mapped) {
993 size_t psz = PAGE_ALIGN(sz > 0 ? sz : 1);
995 if (part->mapped <= 0)
996 n = mmap(NULL, psz, PROT_READ|PROT_WRITE, MAP_SHARED, part->memfd, 0);
998 n = mremap(part->data, part->mapped, psz, MREMAP_MAYMOVE);
1000 if (n == MAP_FAILED) {
1009 part->munmap_this = true;
1011 n = realloc(part->data, MAX(sz, 1u));
1018 part->free_this = true;
1022 *q = part->data ? (uint8_t*) part->data + part->size : NULL;
1028 static void message_extend_containers(sd_bus_message *m, size_t expand) {
1029 struct bus_container *c;
1036 /* Update counters */
1037 for (c = m->containers; c < m->containers + m->n_containers; c++)
1039 *c->array_size += expand;
1042 static void *message_extend_body(sd_bus_message *m, size_t align, size_t sz) {
1043 struct bus_body_part *part = NULL;
1044 size_t start_body, end_body, padding, start_part, end_part, added;
1056 start_body = ALIGN_TO((size_t) m->header->body_size, align);
1057 end_body = start_body + sz;
1059 padding = start_body - m->header->body_size;
1060 added = padding + sz;
1062 /* Check for 32bit overflows */
1063 if (end_body > (size_t) ((uint32_t) -1)) {
1069 m->n_body_parts <= 0 ||
1070 m->body_end->sealed ||
1071 padding != ALIGN_TO(m->body_end->size, align) - m->body_end->size;
1075 part = message_append_part(m);
1079 part_zero(part, padding);
1082 part = message_append_part(m);
1086 r = part_make_space(m, part, sz, &p);
1090 struct bus_container *c;
1098 start_part = ALIGN_TO(part->size, align);
1099 end_part = start_part + sz;
1101 r = part_make_space(m, part, end_part, &p);
1106 memset(p, 0, padding);
1107 p = (uint8_t*) p + padding;
1110 /* Readjust pointers */
1111 for (c = m->containers; c < m->containers + m->n_containers; c++)
1112 c->array_size = adjust_pointer(c->array_size, op, os, part->data);
1114 m->error.message = (const char*) adjust_pointer(m->error.message, op, os, part->data);
1117 m->header->body_size = end_body;
1118 message_extend_containers(m, added);
1123 int message_append_basic(sd_bus_message *m, char type, const void *p, const void **stored) {
1124 struct bus_container *c;
1132 assert_return(m, -EINVAL);
1133 assert_return(!m->sealed, -EPERM);
1134 assert_return(bus_type_is_basic(type), -EINVAL);
1135 assert_return(!m->poisoned, -ESTALE);
1137 c = message_get_container(m);
1139 if (c->signature && c->signature[c->index]) {
1140 /* Container signature is already set */
1142 if (c->signature[c->index] != type)
1147 /* Maybe we can append to the signature? But only if this is the top-level container*/
1148 if (c->enclosing != 0)
1151 e = strextend(&c->signature, CHAR_TO_STR(type), NULL);
1160 case SD_BUS_TYPE_STRING:
1161 /* To make things easy we'll serialize a NULL string
1162 * into the empty string */
1165 /* Fall through... */
1166 case SD_BUS_TYPE_OBJECT_PATH:
1174 sz = 4 + strlen(p) + 1;
1177 case SD_BUS_TYPE_SIGNATURE:
1185 sz = 1 + strlen(p) + 1;
1188 case SD_BUS_TYPE_BOOLEAN:
1197 assert_cc(sizeof(int) == sizeof(uint32_t));
1203 case SD_BUS_TYPE_UNIX_FD: {
1211 if (!m->allow_fds) {
1224 fd = fcntl(z, F_DUPFD_CLOEXEC, 3);
1230 f = realloc(m->fds, sizeof(int) * (m->n_fds + 1));
1250 align = bus_type_get_alignment(type);
1251 sz = bus_type_get_size(type);
1258 a = message_extend_body(m, align, sz);
1264 if (type == SD_BUS_TYPE_STRING || type == SD_BUS_TYPE_OBJECT_PATH) {
1265 *(uint32_t*) a = sz - 5;
1266 memcpy((uint8_t*) a + 4, p, sz - 4);
1269 *stored = (const uint8_t*) a + 4;
1271 } else if (type == SD_BUS_TYPE_SIGNATURE) {
1272 *(uint8_t*) a = sz - 1;
1273 memcpy((uint8_t*) a + 1, p, sz - 1);
1276 *stored = (const uint8_t*) a + 1;
1277 } else if (type == SD_BUS_TYPE_UNIX_FD) {
1278 *(uint32_t*) a = fdi;
1292 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1299 close_nointr_nofail(fd);
1304 _public_ int sd_bus_message_append_basic(sd_bus_message *m, char type, const void *p) {
1305 return message_append_basic(m, type, p, NULL);
1308 _public_ int sd_bus_message_append_string_space(
1313 struct bus_container *c;
1316 assert_return(m, -EINVAL);
1317 assert_return(s, -EINVAL);
1318 assert_return(!m->sealed, -EPERM);
1319 assert_return(!m->poisoned, -ESTALE);
1321 c = message_get_container(m);
1323 if (c->signature && c->signature[c->index]) {
1324 /* Container signature is already set */
1326 if (c->signature[c->index] != SD_BUS_TYPE_STRING)
1331 /* Maybe we can append to the signature? But only if this is the top-level container*/
1332 if (c->enclosing != 0)
1335 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRING), NULL);
1342 a = message_extend_body(m, 4, 4 + size + 1);
1346 *(uint32_t*) a = size;
1351 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1357 _public_ int sd_bus_message_append_string_iovec(
1359 const struct iovec *iov,
1367 assert_return(m, -EINVAL);
1368 assert_return(!m->sealed, -EPERM);
1369 assert_return(iov || n == 0, -EINVAL);
1370 assert_return(!m->poisoned, -ESTALE);
1372 size = IOVEC_TOTAL_SIZE(iov, n);
1374 r = sd_bus_message_append_string_space(m, size, &p);
1378 for (i = 0; i < n; i++) {
1380 if (iov[i].iov_base)
1381 memcpy(p, iov[i].iov_base, iov[i].iov_len);
1383 memset(p, ' ', iov[i].iov_len);
1385 p += iov[i].iov_len;
1391 static int bus_message_open_array(
1393 struct bus_container *c,
1394 const char *contents,
1395 uint32_t **array_size) {
1401 struct bus_body_part *o;
1408 if (!signature_is_single(contents, true))
1411 alignment = bus_type_get_alignment(contents[0]);
1415 if (c->signature && c->signature[c->index]) {
1417 /* Verify the existing signature */
1419 if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
1422 if (!startswith(c->signature + c->index + 1, contents))
1425 nindex = c->index + 1 + strlen(contents);
1429 if (c->enclosing != 0)
1432 /* Extend the existing signature */
1434 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_ARRAY), contents, NULL);
1440 nindex = e - c->signature;
1443 a = message_extend_body(m, 4, 4);
1448 op = m->body_end->data;
1449 os = m->body_end->size;
1451 /* Add alignment between size and first element */
1452 if (!message_extend_body(m, alignment, 0))
1455 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1458 /* location of array size might have changed so let's readjust a */
1459 if (o == m->body_end)
1460 a = adjust_pointer(a, op, os, m->body_end->data);
1467 static int bus_message_open_variant(
1469 struct bus_container *c,
1470 const char *contents) {
1479 if (!signature_is_single(contents, false))
1482 if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
1485 if (c->signature && c->signature[c->index]) {
1487 if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
1493 if (c->enclosing != 0)
1496 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_VARIANT), NULL);
1503 l = strlen(contents);
1504 a = message_extend_body(m, 1, 1 + l + 1);
1509 memcpy((uint8_t*) a + 1, contents, l + 1);
1511 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1517 static int bus_message_open_struct(
1519 struct bus_container *c,
1520 const char *contents) {
1528 if (!signature_is_valid(contents, false))
1531 if (c->signature && c->signature[c->index]) {
1534 l = strlen(contents);
1536 if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
1537 !startswith(c->signature + c->index + 1, contents) ||
1538 c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
1541 nindex = c->index + 1 + l + 1;
1545 if (c->enclosing != 0)
1548 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_BEGIN), contents, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_END), NULL);
1554 nindex = e - c->signature;
1557 /* Align contents to 8 byte boundary */
1558 if (!message_extend_body(m, 8, 0))
1561 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1567 static int bus_message_open_dict_entry(
1569 struct bus_container *c,
1570 const char *contents) {
1578 if (!signature_is_pair(contents))
1581 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1584 if (c->signature && c->signature[c->index]) {
1587 l = strlen(contents);
1589 if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
1590 !startswith(c->signature + c->index + 1, contents) ||
1591 c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
1594 nindex = c->index + 1 + l + 1;
1598 /* Align contents to 8 byte boundary */
1599 if (!message_extend_body(m, 8, 0))
1602 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1608 _public_ int sd_bus_message_open_container(
1611 const char *contents) {
1613 struct bus_container *c, *w;
1614 uint32_t *array_size = NULL;
1619 assert_return(m, -EINVAL);
1620 assert_return(!m->sealed, -EPERM);
1621 assert_return(contents, -EINVAL);
1622 assert_return(!m->poisoned, -ESTALE);
1624 /* Make sure we have space for one more container */
1625 w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
1633 c = message_get_container(m);
1635 signature = strdup(contents);
1641 /* Save old index in the parent container, in case we have to
1642 * abort this container */
1643 c->saved_index = c->index;
1644 before = m->header->body_size;
1646 if (type == SD_BUS_TYPE_ARRAY)
1647 r = bus_message_open_array(m, c, contents, &array_size);
1648 else if (type == SD_BUS_TYPE_VARIANT)
1649 r = bus_message_open_variant(m, c, contents);
1650 else if (type == SD_BUS_TYPE_STRUCT)
1651 r = bus_message_open_struct(m, c, contents);
1652 else if (type == SD_BUS_TYPE_DICT_ENTRY)
1653 r = bus_message_open_dict_entry(m, c, contents);
1662 /* OK, let's fill it in */
1663 w += m->n_containers++;
1664 w->enclosing = type;
1665 w->signature = signature;
1667 w->array_size = array_size;
1669 w->begin = m->rindex;
1674 _public_ int sd_bus_message_close_container(sd_bus_message *m) {
1675 struct bus_container *c;
1677 assert_return(m, -EINVAL);
1678 assert_return(!m->sealed, -EPERM);
1679 assert_return(m->n_containers > 0, -EINVAL);
1680 assert_return(!m->poisoned, -ESTALE);
1682 c = message_get_container(m);
1683 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1684 if (c->signature && c->signature[c->index] != 0)
1699 static int type_stack_push(TypeStack *stack, unsigned max, unsigned *i, const char *types, unsigned n_struct, unsigned n_array) {
1706 stack[*i].types = types;
1707 stack[*i].n_struct = n_struct;
1708 stack[*i].n_array = n_array;
1714 static int type_stack_pop(TypeStack *stack, unsigned max, unsigned *i, const char **types, unsigned *n_struct, unsigned *n_array) {
1725 *types = stack[*i].types;
1726 *n_struct = stack[*i].n_struct;
1727 *n_array = stack[*i].n_array;
1732 int bus_message_append_ap(
1737 unsigned n_array, n_struct;
1738 TypeStack stack[BUS_CONTAINER_DEPTH];
1739 unsigned stack_ptr = 0;
1747 n_array = (unsigned) -1;
1748 n_struct = strlen(types);
1753 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
1754 r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
1760 r = sd_bus_message_close_container(m);
1768 if (n_array != (unsigned) -1)
1777 case SD_BUS_TYPE_BYTE: {
1780 x = (uint8_t) va_arg(ap, int);
1781 r = sd_bus_message_append_basic(m, *t, &x);
1785 case SD_BUS_TYPE_BOOLEAN:
1786 case SD_BUS_TYPE_INT32:
1787 case SD_BUS_TYPE_UINT32:
1788 case SD_BUS_TYPE_UNIX_FD: {
1791 /* We assume a boolean is the same as int32_t */
1792 assert_cc(sizeof(int32_t) == sizeof(int));
1794 x = va_arg(ap, uint32_t);
1795 r = sd_bus_message_append_basic(m, *t, &x);
1799 case SD_BUS_TYPE_INT16:
1800 case SD_BUS_TYPE_UINT16: {
1803 x = (uint16_t) va_arg(ap, int);
1804 r = sd_bus_message_append_basic(m, *t, &x);
1808 case SD_BUS_TYPE_INT64:
1809 case SD_BUS_TYPE_UINT64:
1810 case SD_BUS_TYPE_DOUBLE: {
1813 x = va_arg(ap, uint64_t);
1814 r = sd_bus_message_append_basic(m, *t, &x);
1818 case SD_BUS_TYPE_STRING:
1819 case SD_BUS_TYPE_OBJECT_PATH:
1820 case SD_BUS_TYPE_SIGNATURE: {
1823 x = va_arg(ap, const char*);
1824 r = sd_bus_message_append_basic(m, *t, x);
1828 case SD_BUS_TYPE_ARRAY: {
1831 r = signature_element_length(t + 1, &k);
1837 memcpy(s, t + 1, k);
1840 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, s);
1845 if (n_array == (unsigned) -1) {
1850 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
1856 n_array = va_arg(ap, unsigned);
1861 case SD_BUS_TYPE_VARIANT: {
1864 s = va_arg(ap, const char*);
1868 r = sd_bus_message_open_container(m, SD_BUS_TYPE_VARIANT, s);
1872 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
1877 n_struct = strlen(s);
1878 n_array = (unsigned) -1;
1883 case SD_BUS_TYPE_STRUCT_BEGIN:
1884 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
1887 r = signature_element_length(t, &k);
1894 memcpy(s, t + 1, k - 2);
1897 r = sd_bus_message_open_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
1902 if (n_array == (unsigned) -1) {
1907 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
1913 n_array = (unsigned) -1;
1929 _public_ int sd_bus_message_append(sd_bus_message *m, const char *types, ...) {
1933 assert_return(m, -EINVAL);
1934 assert_return(types, -EINVAL);
1935 assert_return(!m->sealed, -EPERM);
1936 assert_return(!m->poisoned, -ESTALE);
1938 va_start(ap, types);
1939 r = bus_message_append_ap(m, types, ap);
1945 _public_ int sd_bus_message_append_array_space(sd_bus_message *m,
1953 assert_return(m, -EINVAL);
1954 assert_return(!m->sealed, -EPERM);
1955 assert_return(bus_type_is_trivial(type), -EINVAL);
1956 assert_return(ptr || size == 0, -EINVAL);
1957 assert_return(!m->poisoned, -ESTALE);
1959 align = bus_type_get_alignment(type);
1960 sz = bus_type_get_size(type);
1962 assert_se(align > 0);
1968 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
1972 a = message_extend_body(m, align, size);
1976 r = sd_bus_message_close_container(m);
1984 _public_ int sd_bus_message_append_array(sd_bus_message *m,
1991 assert_return(m, -EINVAL);
1992 assert_return(!m->sealed, -EPERM);
1993 assert_return(bus_type_is_trivial(type), -EINVAL);
1994 assert_return(ptr || size == 0, -EINVAL);
1995 assert_return(!m->poisoned, -ESTALE);
1997 r = sd_bus_message_append_array_space(m, type, size, &p);
2002 memcpy(p, ptr, size);
2007 _public_ int sd_bus_message_append_array_iovec(
2010 const struct iovec *iov,
2018 assert_return(m, -EINVAL);
2019 assert_return(!m->sealed, -EPERM);
2020 assert_return(bus_type_is_trivial(type), -EINVAL);
2021 assert_return(iov || n == 0, -EINVAL);
2022 assert_return(!m->poisoned, -ESTALE);
2024 size = IOVEC_TOTAL_SIZE(iov, n);
2026 r = sd_bus_message_append_array_space(m, type, size, &p);
2030 for (i = 0; i < n; i++) {
2032 if (iov[i].iov_base)
2033 memcpy(p, iov[i].iov_base, iov[i].iov_len);
2035 memset(p, 0, iov[i].iov_len);
2037 p = (uint8_t*) p + iov[i].iov_len;
2043 _public_ int sd_bus_message_append_array_memfd(sd_bus_message *m,
2046 _cleanup_close_ int copy_fd = -1;
2047 struct bus_body_part *part;
2059 if (!bus_type_is_trivial(type))
2064 r = sd_memfd_set_sealed(memfd, true);
2068 copy_fd = sd_memfd_dup_fd(memfd);
2072 r = sd_memfd_get_size(memfd, &size);
2076 align = bus_type_get_alignment(type);
2077 sz = bus_type_get_size(type);
2079 assert_se(align > 0);
2085 if (size > (uint64_t) (uint32_t) -1)
2088 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
2092 a = message_extend_body(m, align, 0);
2096 part = message_append_part(m);
2100 part->memfd = copy_fd;
2101 part->sealed = true;
2105 message_extend_containers(m, size);
2106 m->header->body_size += size;
2108 return sd_bus_message_close_container(m);
2111 _public_ int sd_bus_message_append_string_memfd(sd_bus_message *m, sd_memfd *memfd) {
2112 _cleanup_close_ int copy_fd = -1;
2113 struct bus_body_part *part;
2114 struct bus_container *c;
2119 assert_return(m, -EINVAL);
2120 assert_return(memfd, -EINVAL);
2121 assert_return(!m->sealed, -EPERM);
2122 assert_return(!m->poisoned, -ESTALE);
2124 r = sd_memfd_set_sealed(memfd, true);
2128 copy_fd = sd_memfd_dup_fd(memfd);
2132 r = sd_memfd_get_size(memfd, &size);
2136 /* We require this to be NUL terminated */
2140 if (size > (uint64_t) (uint32_t) -1)
2143 c = message_get_container(m);
2144 if (c->signature && c->signature[c->index]) {
2145 /* Container signature is already set */
2147 if (c->signature[c->index] != SD_BUS_TYPE_STRING)
2152 /* Maybe we can append to the signature? But only if this is the top-level container*/
2153 if (c->enclosing != 0)
2156 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRING), NULL);
2163 a = message_extend_body(m, 4, 4);
2167 *(uint32_t*) a = size - 1;
2169 part = message_append_part(m);
2173 part->memfd = copy_fd;
2174 part->sealed = true;
2178 message_extend_containers(m, size);
2179 m->header->body_size += size;
2181 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2187 _public_ int sd_bus_message_append_strv(sd_bus_message *m, char **l) {
2191 assert_return(m, -EINVAL);
2192 assert_return(!m->sealed, -EPERM);
2193 assert_return(!m->poisoned, -ESTALE);
2195 r = sd_bus_message_open_container(m, 'a', "s");
2199 STRV_FOREACH(i, l) {
2200 r = sd_bus_message_append_basic(m, 's', *i);
2205 return sd_bus_message_close_container(m);
2208 int bus_body_part_map(struct bus_body_part *part) {
2217 if (part->size <= 0)
2220 /* For smaller zero parts (as used for padding) we don't need to map anything... */
2221 if (part->memfd < 0 && part->is_zero && part->size < 8) {
2222 static const uint8_t zeroes[7] = { };
2223 part->data = (void*) zeroes;
2227 psz = PAGE_ALIGN(part->size);
2229 if (part->memfd >= 0)
2230 p = mmap(NULL, psz, PROT_READ, MAP_SHARED, part->memfd, 0);
2231 else if (part->is_zero)
2232 p = mmap(NULL, psz, PROT_READ, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
2236 if (p == MAP_FAILED)
2241 part->munmap_this = true;
2246 void bus_body_part_unmap(struct bus_body_part *part) {
2250 if (part->memfd < 0)
2256 if (!part->munmap_this)
2259 assert_se(munmap(part->data, part->mapped) == 0);
2263 part->munmap_this = false;
2268 static int buffer_peek(const void *p, uint32_t sz, size_t *rindex, size_t align, size_t nbytes, void **r) {
2269 size_t k, start, end;
2274 start = ALIGN_TO((size_t) *rindex, align);
2275 end = start + nbytes;
2280 /* Verify that padding is 0 */
2281 for (k = *rindex; k < start; k++)
2282 if (((const uint8_t*) p)[k] != 0)
2286 *r = (uint8_t*) p + start;
2293 static bool message_end_of_signature(sd_bus_message *m) {
2294 struct bus_container *c;
2298 c = message_get_container(m);
2299 return !c->signature || c->signature[c->index] == 0;
2302 static bool message_end_of_array(sd_bus_message *m, size_t index) {
2303 struct bus_container *c;
2307 c = message_get_container(m);
2311 return index >= c->begin + BUS_MESSAGE_BSWAP32(m, *c->array_size);
2314 _public_ int sd_bus_message_at_end(sd_bus_message *m, int complete) {
2315 assert_return(m, -EINVAL);
2316 assert_return(m->sealed, -EPERM);
2318 if (complete && m->n_containers > 0)
2321 if (message_end_of_signature(m))
2324 if (message_end_of_array(m, m->rindex))
2330 static struct bus_body_part* find_part(sd_bus_message *m, size_t index, size_t sz, void **p) {
2331 struct bus_body_part *part;
2337 if (m->cached_rindex_part && index >= m->cached_rindex_part_begin) {
2338 part = m->cached_rindex_part;
2339 begin = m->cached_rindex_part_begin;
2349 if (index + sz <= begin + part->size) {
2351 r = bus_body_part_map(part);
2356 *p = (uint8_t*) part->data + index - begin;
2358 m->cached_rindex_part = part;
2359 m->cached_rindex_part_begin = begin;
2364 begin += part->size;
2371 static int message_peek_body(
2378 size_t k, start, end, padding;
2379 struct bus_body_part *part;
2386 if (message_end_of_array(m, *rindex))
2389 start = ALIGN_TO((size_t) *rindex, align);
2390 padding = start - *rindex;
2391 end = start + nbytes;
2393 if (end > BUS_MESSAGE_BODY_SIZE(m))
2396 part = find_part(m, *rindex, padding, (void**) &q);
2401 /* Verify padding */
2402 for (k = 0; k < padding; k++)
2407 part = find_part(m, start, nbytes, (void**) &q);
2419 static bool validate_nul(const char *s, size_t l) {
2421 /* Check for NUL chars in the string */
2422 if (memchr(s, 0, l))
2425 /* Check for NUL termination */
2432 static bool validate_string(const char *s, size_t l) {
2434 if (!validate_nul(s, l))
2437 /* Check if valid UTF8 */
2438 if (!utf8_is_valid(s))
2444 static bool validate_signature(const char *s, size_t l) {
2446 if (!validate_nul(s, l))
2449 /* Check if valid signature */
2450 if (!signature_is_valid(s, true))
2456 static bool validate_object_path(const char *s, size_t l) {
2458 if (!validate_nul(s, l))
2461 if (!object_path_is_valid(s))
2467 _public_ int sd_bus_message_read_basic(sd_bus_message *m, char type, void *p) {
2468 struct bus_container *c;
2472 assert_return(m, -EINVAL);
2473 assert_return(m->sealed, -EPERM);
2474 assert_return(bus_type_is_basic(type), -EINVAL);
2476 if (message_end_of_signature(m))
2479 if (message_end_of_array(m, m->rindex))
2482 c = message_get_container(m);
2483 if (c->signature[c->index] != type)
2488 case SD_BUS_TYPE_STRING:
2489 case SD_BUS_TYPE_OBJECT_PATH: {
2494 r = message_peek_body(m, &rindex, 4, 4, &q);
2498 l = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2499 r = message_peek_body(m, &rindex, 1, l+1, &q);
2505 if (type == SD_BUS_TYPE_OBJECT_PATH) {
2506 if (!validate_object_path(q, l))
2509 if (!validate_string(q, l))
2515 *(const char**) p = q;
2520 case SD_BUS_TYPE_SIGNATURE: {
2525 r = message_peek_body(m, &rindex, 1, 1, &q);
2530 r = message_peek_body(m, &rindex, 1, l+1, &q);
2536 if (!validate_signature(q, l))
2542 *(const char**) p = q;
2550 align = bus_type_get_alignment(type);
2551 sz = bus_type_get_size(type);
2552 assert(align > 0 && sz > 0);
2555 r = message_peek_body(m, &rindex, align, sz, &q);
2561 case SD_BUS_TYPE_BYTE:
2563 *(uint8_t*) p = *(uint8_t*) q;
2566 case SD_BUS_TYPE_BOOLEAN:
2568 *(int*) p = !!*(uint32_t*) q;
2571 case SD_BUS_TYPE_INT16:
2572 case SD_BUS_TYPE_UINT16:
2574 *(uint16_t*) p = BUS_MESSAGE_BSWAP16(m, *(uint16_t*) q);
2577 case SD_BUS_TYPE_INT32:
2578 case SD_BUS_TYPE_UINT32:
2580 *(uint32_t*) p = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2583 case SD_BUS_TYPE_INT64:
2584 case SD_BUS_TYPE_UINT64:
2585 case SD_BUS_TYPE_DOUBLE:
2587 *(uint64_t*) p = BUS_MESSAGE_BSWAP64(m, *(uint64_t*) q);
2590 case SD_BUS_TYPE_UNIX_FD: {
2593 j = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2598 *(int*) p = m->fds[j];
2603 assert_not_reached("Unknown basic type...");
2612 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2618 static int bus_message_enter_array(
2620 struct bus_container *c,
2621 const char *contents,
2622 uint32_t **array_size) {
2633 if (!signature_is_single(contents, true))
2636 alignment = bus_type_get_alignment(contents[0]);
2640 if (!c->signature || c->signature[c->index] == 0)
2643 if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
2646 if (!startswith(c->signature + c->index + 1, contents))
2650 r = message_peek_body(m, &rindex, 4, 4, &q);
2654 if (BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q) > BUS_ARRAY_MAX_SIZE)
2657 r = message_peek_body(m, &rindex, alignment, 0, NULL);
2663 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2664 c->index += 1 + strlen(contents);
2668 *array_size = (uint32_t*) q;
2673 static int bus_message_enter_variant(
2675 struct bus_container *c,
2676 const char *contents) {
2687 if (!signature_is_single(contents, false))
2690 if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
2693 if (!c->signature || c->signature[c->index] == 0)
2696 if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
2700 r = message_peek_body(m, &rindex, 1, 1, &q);
2705 r = message_peek_body(m, &rindex, 1, l+1, &q);
2711 if (!validate_signature(q, l))
2714 if (!streq(q, contents))
2717 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2725 static int bus_message_enter_struct(
2727 struct bus_container *c,
2728 const char *contents) {
2737 if (!signature_is_valid(contents, false))
2740 if (!c->signature || c->signature[c->index] == 0)
2743 l = strlen(contents);
2745 if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
2746 !startswith(c->signature + c->index + 1, contents) ||
2747 c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
2750 r = message_peek_body(m, &m->rindex, 8, 0, NULL);
2754 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2755 c->index += 1 + l + 1;
2760 static int bus_message_enter_dict_entry(
2762 struct bus_container *c,
2763 const char *contents) {
2772 if (!signature_is_pair(contents))
2775 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2778 if (!c->signature || c->signature[c->index] == 0)
2781 l = strlen(contents);
2783 if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
2784 !startswith(c->signature + c->index + 1, contents) ||
2785 c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
2788 r = message_peek_body(m, &m->rindex, 8, 0, NULL);
2792 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2793 c->index += 1 + l + 1;
2798 _public_ int sd_bus_message_enter_container(sd_bus_message *m,
2800 const char *contents) {
2801 struct bus_container *c, *w;
2802 uint32_t *array_size = NULL;
2807 assert_return(m, -EINVAL);
2808 assert_return(m->sealed, -EPERM);
2809 assert_return(type != 0 || !contents, -EINVAL);
2811 if (type == 0 || !contents) {
2815 /* Allow entering into anonymous containers */
2816 r = sd_bus_message_peek_type(m, &tt, &cc);
2820 if (type != 0 && type != tt)
2823 if (contents && !streq(contents, cc))
2831 * We enforce a global limit on container depth, that is much
2832 * higher than the 32 structs and 32 arrays the specification
2833 * mandates. This is simpler to implement for us, and we need
2834 * this only to ensure our container array doesn't grow
2835 * without bounds. We are happy to return any data from a
2836 * message as long as the data itself is valid, even if the
2837 * overall message might be not.
2839 * Note that the message signature is validated when
2840 * parsing the headers, and that validation does check the
2843 * Note that the specification defines no limits on the depth
2844 * of stacked variants, but we do.
2846 if (m->n_containers >= BUS_CONTAINER_DEPTH)
2849 w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
2854 if (message_end_of_signature(m))
2857 if (message_end_of_array(m, m->rindex))
2860 c = message_get_container(m);
2862 signature = strdup(contents);
2866 c->saved_index = c->index;
2869 if (type == SD_BUS_TYPE_ARRAY)
2870 r = bus_message_enter_array(m, c, contents, &array_size);
2871 else if (type == SD_BUS_TYPE_VARIANT)
2872 r = bus_message_enter_variant(m, c, contents);
2873 else if (type == SD_BUS_TYPE_STRUCT)
2874 r = bus_message_enter_struct(m, c, contents);
2875 else if (type == SD_BUS_TYPE_DICT_ENTRY)
2876 r = bus_message_enter_dict_entry(m, c, contents);
2885 /* OK, let's fill it in */
2886 w += m->n_containers++;
2887 w->enclosing = type;
2888 w->signature = signature;
2890 w->array_size = array_size;
2892 w->begin = m->rindex;
2897 _public_ int sd_bus_message_exit_container(sd_bus_message *m) {
2898 struct bus_container *c;
2900 assert_return(m, -EINVAL);
2901 assert_return(m->sealed, -EPERM);
2902 assert_return(m->n_containers > 0, -ENXIO);
2904 c = message_get_container(m);
2905 if (c->enclosing == SD_BUS_TYPE_ARRAY) {
2908 l = BUS_MESSAGE_BSWAP32(m, *c->array_size);
2909 if (c->begin + l != m->rindex)
2913 if (c->signature && c->signature[c->index] != 0)
2923 static void message_quit_container(sd_bus_message *m) {
2924 struct bus_container *c;
2928 assert(m->n_containers > 0);
2930 c = message_get_container(m);
2933 assert(m->rindex >= c->before);
2934 m->rindex = c->before;
2936 /* Free container */
2940 /* Correct index of new top-level container */
2941 c = message_get_container(m);
2942 c->index = c->saved_index;
2945 _public_ int sd_bus_message_peek_type(sd_bus_message *m, char *type, const char **contents) {
2946 struct bus_container *c;
2949 assert_return(m, -EINVAL);
2950 assert_return(m->sealed, -EPERM);
2952 if (message_end_of_signature(m))
2955 if (message_end_of_array(m, m->rindex))
2958 c = message_get_container(m);
2960 if (bus_type_is_basic(c->signature[c->index])) {
2964 *type = c->signature[c->index];
2968 if (c->signature[c->index] == SD_BUS_TYPE_ARRAY) {
2974 r = signature_element_length(c->signature+c->index+1, &l);
2980 sig = strndup(c->signature + c->index + 1, l);
2984 free(m->peeked_signature);
2985 m->peeked_signature = sig;
2991 *type = SD_BUS_TYPE_ARRAY;
2996 if (c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ||
2997 c->signature[c->index] == SD_BUS_TYPE_DICT_ENTRY_BEGIN) {
3003 r = signature_element_length(c->signature+c->index, &l);
3008 sig = strndup(c->signature + c->index + 1, l - 2);
3012 free(m->peeked_signature);
3013 m->peeked_signature = sig;
3019 *type = c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY;
3024 if (c->signature[c->index] == SD_BUS_TYPE_VARIANT) {
3030 r = message_peek_body(m, &rindex, 1, 1, &q);
3037 r = message_peek_body(m, &rindex, 1, l+1, &q);
3043 if (!validate_signature(q, l))
3050 *type = SD_BUS_TYPE_VARIANT;
3065 _public_ int sd_bus_message_rewind(sd_bus_message *m, int complete) {
3066 struct bus_container *c;
3068 assert_return(m, -EINVAL);
3069 assert_return(m->sealed, -EPERM);
3072 message_reset_containers(m);
3074 m->root_container.index = 0;
3076 c = message_get_container(m);
3078 c = message_get_container(m);
3081 m->rindex = c->begin;
3084 return !isempty(c->signature);
3087 static int message_read_ap(
3092 unsigned n_array, n_struct;
3093 TypeStack stack[BUS_CONTAINER_DEPTH];
3094 unsigned stack_ptr = 0;
3095 unsigned n_loop = 0;
3103 /* Ideally, we'd just call ourselves recursively on every
3104 * complex type. However, the state of a va_list that is
3105 * passed to a function is undefined after that function
3106 * returns. This means we need to docode the va_list linearly
3107 * in a single stackframe. We hence implement our own
3108 * home-grown stack in an array. */
3110 n_array = (unsigned) -1; /* lenght of current array entries */
3111 n_struct = strlen(types); /* length of current struct contents signature */
3118 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
3119 r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
3125 r = sd_bus_message_exit_container(m);
3133 if (n_array != (unsigned) -1)
3142 case SD_BUS_TYPE_BYTE:
3143 case SD_BUS_TYPE_BOOLEAN:
3144 case SD_BUS_TYPE_INT16:
3145 case SD_BUS_TYPE_UINT16:
3146 case SD_BUS_TYPE_INT32:
3147 case SD_BUS_TYPE_UINT32:
3148 case SD_BUS_TYPE_INT64:
3149 case SD_BUS_TYPE_UINT64:
3150 case SD_BUS_TYPE_DOUBLE:
3151 case SD_BUS_TYPE_STRING:
3152 case SD_BUS_TYPE_OBJECT_PATH:
3153 case SD_BUS_TYPE_SIGNATURE:
3154 case SD_BUS_TYPE_UNIX_FD: {
3157 p = va_arg(ap, void*);
3158 r = sd_bus_message_read_basic(m, *t, p);
3171 case SD_BUS_TYPE_ARRAY: {
3174 r = signature_element_length(t + 1, &k);
3180 memcpy(s, t + 1, k);
3183 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, s);
3194 if (n_array == (unsigned) -1) {
3199 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
3205 n_array = va_arg(ap, unsigned);
3210 case SD_BUS_TYPE_VARIANT: {
3213 s = va_arg(ap, const char *);
3217 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, s);
3227 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
3232 n_struct = strlen(s);
3233 n_array = (unsigned) -1;
3238 case SD_BUS_TYPE_STRUCT_BEGIN:
3239 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
3242 r = signature_element_length(t, &k);
3248 memcpy(s, t + 1, k - 2);
3251 r = sd_bus_message_enter_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
3261 if (n_array == (unsigned) -1) {
3266 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
3272 n_array = (unsigned) -1;
3285 _public_ int sd_bus_message_read(sd_bus_message *m, const char *types, ...) {
3289 assert_return(m, -EINVAL);
3290 assert_return(m->sealed, -EPERM);
3291 assert_return(types, -EINVAL);
3293 va_start(ap, types);
3294 r = message_read_ap(m, types, ap);
3300 _public_ int sd_bus_message_skip(sd_bus_message *m, const char *types) {
3303 assert_return(m, -EINVAL);
3304 assert_return(m->sealed, -EPERM);
3305 assert_return(types, -EINVAL);
3312 case SD_BUS_TYPE_BYTE:
3313 case SD_BUS_TYPE_BOOLEAN:
3314 case SD_BUS_TYPE_INT16:
3315 case SD_BUS_TYPE_UINT16:
3316 case SD_BUS_TYPE_INT32:
3317 case SD_BUS_TYPE_UINT32:
3318 case SD_BUS_TYPE_INT64:
3319 case SD_BUS_TYPE_UINT64:
3320 case SD_BUS_TYPE_DOUBLE:
3321 case SD_BUS_TYPE_STRING:
3322 case SD_BUS_TYPE_OBJECT_PATH:
3323 case SD_BUS_TYPE_SIGNATURE:
3324 case SD_BUS_TYPE_UNIX_FD:
3326 r = sd_bus_message_read_basic(m, *types, NULL);
3330 r = sd_bus_message_skip(m, types + 1);
3336 case SD_BUS_TYPE_ARRAY: {
3339 r = signature_element_length(types + 1, &k);
3345 memcpy(s, types+1, k);
3348 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, s);
3353 r = sd_bus_message_skip(m, s);
3360 r = sd_bus_message_exit_container(m);
3365 r = sd_bus_message_skip(m, types + 1 + k);
3372 case SD_BUS_TYPE_VARIANT: {
3373 const char *contents;
3376 r = sd_bus_message_peek_type(m, &x, &contents);
3380 if (x != SD_BUS_TYPE_VARIANT)
3383 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, contents);
3387 r = sd_bus_message_skip(m, contents);
3392 r = sd_bus_message_exit_container(m);
3396 r = sd_bus_message_skip(m, types + 1);
3403 case SD_BUS_TYPE_STRUCT_BEGIN:
3404 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
3407 r = signature_element_length(types, &k);
3413 memcpy(s, types+1, k-2);
3416 r = sd_bus_message_enter_container(m, *types == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
3420 r = sd_bus_message_skip(m, s);
3425 r = sd_bus_message_exit_container(m);
3430 r = sd_bus_message_skip(m, types + k);
3442 _public_ int sd_bus_message_read_array(sd_bus_message *m,
3446 struct bus_container *c;
3452 assert_return(m, -EINVAL);
3453 assert_return(m->sealed, -EPERM);
3454 assert_return(bus_type_is_trivial(type), -EINVAL);
3455 assert_return(ptr, -EINVAL);
3456 assert_return(size, -EINVAL);
3457 assert_return(!BUS_MESSAGE_NEED_BSWAP(m), -ENOTSUP);
3459 align = bus_type_get_alignment(type);
3463 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
3467 c = message_get_container(m);
3468 sz = BUS_MESSAGE_BSWAP32(m, *c->array_size);
3471 /* Zero length array, let's return some aligned
3472 * pointer that is not NULL */
3473 p = (uint8_t*) NULL + align;
3475 r = message_peek_body(m, &m->rindex, align, sz, &p);
3484 r = sd_bus_message_exit_container(m);
3488 *ptr = (const void*) p;
3494 message_quit_container(m);
3498 static int message_peek_fields(
3509 return buffer_peek(BUS_MESSAGE_FIELDS(m), BUS_MESSAGE_FIELDS_SIZE(m), rindex, align, nbytes, ret);
3512 static int message_peek_field_uint32(
3523 r = message_peek_fields(m, ri, 4, 4, &q);
3528 *ret = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
3533 static int message_peek_field_string(
3535 bool (*validate)(const char *p),
3546 r = message_peek_field_uint32(m, ri, &l);
3550 r = message_peek_fields(m, ri, 1, l+1, &q);
3555 if (!validate_nul(q, l))
3561 if (!validate_string(q, l))
3571 static int message_peek_field_signature(
3583 r = message_peek_fields(m, ri, 1, 1, &q);
3588 r = message_peek_fields(m, ri, 1, l+1, &q);
3592 if (!validate_signature(q, l))
3601 static int message_skip_fields(
3604 uint32_t array_size,
3605 const char **signature) {
3607 size_t original_index;
3614 original_index = *ri;
3620 if (array_size != (uint32_t) -1 &&
3621 array_size <= *ri - original_index)
3628 if (t == SD_BUS_TYPE_STRING) {
3630 r = message_peek_field_string(m, NULL, ri, NULL);
3636 } else if (t == SD_BUS_TYPE_OBJECT_PATH) {
3638 r = message_peek_field_string(m, object_path_is_valid, ri, NULL);
3644 } else if (t == SD_BUS_TYPE_SIGNATURE) {
3646 r = message_peek_field_signature(m, ri, NULL);
3652 } else if (bus_type_is_basic(t)) {
3655 align = bus_type_get_alignment(t);
3656 k = bus_type_get_size(t);
3657 assert(align > 0 && k > 0);
3659 r = message_peek_fields(m, ri, align, k, NULL);
3665 } else if (t == SD_BUS_TYPE_ARRAY) {
3667 r = signature_element_length(*signature+1, &l);
3677 strncpy(sig, *signature + 1, l-1);
3680 alignment = bus_type_get_alignment(sig[0]);
3684 r = message_peek_field_uint32(m, ri, &nas);
3687 if (nas > BUS_ARRAY_MAX_SIZE)
3690 r = message_peek_fields(m, ri, alignment, 0, NULL);
3694 r = message_skip_fields(m, ri, nas, (const char**) &s);
3699 (*signature) += 1 + l;
3701 } else if (t == SD_BUS_TYPE_VARIANT) {
3704 r = message_peek_field_signature(m, ri, &s);
3708 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
3714 } else if (t == SD_BUS_TYPE_STRUCT ||
3715 t == SD_BUS_TYPE_DICT_ENTRY) {
3717 r = signature_element_length(*signature, &l);
3724 strncpy(sig, *signature + 1, l-1);
3727 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
3738 int bus_message_parse_fields(sd_bus_message *m) {
3741 uint32_t unix_fds = 0;
3745 for (ri = 0; ri < BUS_MESSAGE_FIELDS_SIZE(m); ) {
3746 const char *signature;
3749 r = message_peek_fields(m, &ri, 8, 1, (void**) &header);
3753 r = message_peek_field_signature(m, &ri, &signature);
3758 case _SD_BUS_MESSAGE_HEADER_INVALID:
3761 case SD_BUS_MESSAGE_HEADER_PATH:
3766 if (!streq(signature, "o"))
3769 r = message_peek_field_string(m, object_path_is_valid, &ri, &m->path);
3772 case SD_BUS_MESSAGE_HEADER_INTERFACE:
3777 if (!streq(signature, "s"))
3780 r = message_peek_field_string(m, interface_name_is_valid, &ri, &m->interface);
3783 case SD_BUS_MESSAGE_HEADER_MEMBER:
3788 if (!streq(signature, "s"))
3791 r = message_peek_field_string(m, member_name_is_valid, &ri, &m->member);
3794 case SD_BUS_MESSAGE_HEADER_ERROR_NAME:
3799 if (!streq(signature, "s"))
3802 r = message_peek_field_string(m, error_name_is_valid, &ri, &m->error.name);
3805 case SD_BUS_MESSAGE_HEADER_DESTINATION:
3810 if (!streq(signature, "s"))
3813 r = message_peek_field_string(m, service_name_is_valid, &ri, &m->destination);
3816 case SD_BUS_MESSAGE_HEADER_SENDER:
3821 if (!streq(signature, "s"))
3824 r = message_peek_field_string(m, service_name_is_valid, &ri, &m->sender);
3828 case SD_BUS_MESSAGE_HEADER_SIGNATURE: {
3832 if (m->root_container.signature)
3835 if (!streq(signature, "g"))
3838 r = message_peek_field_signature(m, &ri, &s);
3846 free(m->root_container.signature);
3847 m->root_container.signature = c;
3851 case SD_BUS_MESSAGE_HEADER_REPLY_SERIAL:
3852 if (m->reply_serial != 0)
3855 if (!streq(signature, "u"))
3858 r = message_peek_field_uint32(m, &ri, &m->reply_serial);
3862 if (m->reply_serial == 0)
3867 case SD_BUS_MESSAGE_HEADER_UNIX_FDS:
3871 if (!streq(signature, "u"))
3874 r = message_peek_field_uint32(m, &ri, &unix_fds);
3884 r = message_skip_fields(m, &ri, (uint32_t) -1, (const char **) &signature);
3891 if (m->n_fds != unix_fds)
3894 if (isempty(m->root_container.signature) != (BUS_MESSAGE_BODY_SIZE(m) == 0))
3897 switch (m->header->type) {
3899 case SD_BUS_MESSAGE_SIGNAL:
3900 if (!m->path || !m->interface || !m->member)
3904 case SD_BUS_MESSAGE_METHOD_CALL:
3906 if (!m->path || !m->member)
3911 case SD_BUS_MESSAGE_METHOD_RETURN:
3913 if (m->reply_serial == 0)
3917 case SD_BUS_MESSAGE_METHOD_ERROR:
3919 if (m->reply_serial == 0 || !m->error.name)
3924 /* Try to read the error message, but if we can't it's a non-issue */
3925 if (m->header->type == SD_BUS_MESSAGE_METHOD_ERROR)
3926 sd_bus_message_read(m, "s", &m->error.message);
3931 int bus_message_seal(sd_bus_message *m, uint64_t serial) {
3932 struct bus_body_part *part;
3942 if (m->n_containers > 0)
3948 /* If there's a non-trivial signature set, then add it in here */
3949 if (!isempty(m->root_container.signature)) {
3950 r = message_append_field_signature(m, SD_BUS_MESSAGE_HEADER_SIGNATURE, m->root_container.signature, NULL);
3956 r = message_append_field_uint32(m, SD_BUS_MESSAGE_HEADER_UNIX_FDS, m->n_fds);
3961 /* Add padding at the end of the fields part, since we know
3962 * the body needs to start at an 8 byte alignment. We made
3963 * sure we allocated enough space for this, so all we need to
3964 * do here is to zero it out. */
3965 l = BUS_MESSAGE_FIELDS_SIZE(m);
3968 memset((uint8_t*) BUS_MESSAGE_FIELDS(m) + l, 0, a);
3970 /* If this is something we can send as memfd, then let's seal
3971 the memfd now. Note that we can send memfds as payload only
3972 for directed messages, and not for broadcasts. */
3973 if (m->destination && m->bus && m->bus->use_memfd) {
3974 MESSAGE_FOREACH_PART(part, i, m)
3975 if (part->memfd >= 0 && !part->sealed && (part->size > MEMFD_MIN_SIZE || m->bus->use_memfd < 0)) {
3976 bus_body_part_unmap(part);
3978 if (ioctl(part->memfd, KDBUS_CMD_MEMFD_SEAL_SET, 1) >= 0)
3979 part->sealed = true;
3983 m->header->serial = serial;
3989 _public_ int sd_bus_message_set_destination(sd_bus_message *m, const char *destination) {
3990 assert_return(m, -EINVAL);
3991 assert_return(destination, -EINVAL);
3992 assert_return(!m->sealed, -EPERM);
3993 assert_return(!m->destination, -EEXIST);
3995 return message_append_field_string(m, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &m->destination);
3998 int bus_message_get_blob(sd_bus_message *m, void **buffer, size_t *sz) {
4002 struct bus_body_part *part;
4008 total = BUS_MESSAGE_SIZE(m);
4014 e = mempcpy(p, m->header, BUS_MESSAGE_BODY_BEGIN(m));
4015 MESSAGE_FOREACH_PART(part, i, m)
4016 e = mempcpy(e, part->data, part->size);
4018 assert(total == (size_t) ((uint8_t*) e - (uint8_t*) p));
4026 int bus_message_read_strv_extend(sd_bus_message *m, char ***l) {
4032 r = sd_bus_message_enter_container(m, 'a', "s");
4039 r = sd_bus_message_read_basic(m, 's', &s);
4045 r = strv_extend(l, s);
4050 r = sd_bus_message_exit_container(m);
4057 _public_ int sd_bus_message_read_strv(sd_bus_message *m, char ***l) {
4061 assert_return(m, -EINVAL);
4062 assert_return(m->sealed, -EPERM);
4063 assert_return(l, -EINVAL);
4065 r = bus_message_read_strv_extend(m, &strv);
4075 const char* bus_message_get_arg(sd_bus_message *m, unsigned i) {
4077 const char *t = NULL;
4082 r = sd_bus_message_rewind(m, true);
4086 for (j = 0; j <= i; j++) {
4089 r = sd_bus_message_peek_type(m, &type, NULL);
4093 if (type != SD_BUS_TYPE_STRING &&
4094 type != SD_BUS_TYPE_OBJECT_PATH &&
4095 type != SD_BUS_TYPE_SIGNATURE)
4098 r = sd_bus_message_read_basic(m, type, &t);
4106 bool bus_header_is_complete(struct bus_header *h, size_t size) {
4112 if (size < sizeof(struct bus_header))
4115 full = sizeof(struct bus_header) +
4116 (h->endian == SD_BUS_NATIVE_ENDIAN ? h->fields_size : bswap_32(h->fields_size));
4118 return size >= full;
4121 int bus_header_message_size(struct bus_header *h, size_t *sum) {
4127 if (h->endian == SD_BUS_NATIVE_ENDIAN) {
4128 fs = h->fields_size;
4130 } else if (h->endian == SD_BUS_REVERSE_ENDIAN) {
4131 fs = bswap_32(h->fields_size);
4132 bs = bswap_32(h->body_size);
4136 *sum = sizeof(struct bus_header) + ALIGN8(fs) + bs;
4140 _public_ int sd_bus_message_get_errno(sd_bus_message *m) {
4141 assert_return(m, -EINVAL);
4143 if (m->header->type != SD_BUS_MESSAGE_METHOD_ERROR)
4146 return sd_bus_error_get_errno(&m->error);
4149 _public_ const char* sd_bus_message_get_signature(sd_bus_message *m, int complete) {
4150 struct bus_container *c;
4152 assert_return(m, NULL);
4154 c = complete ? &m->root_container : message_get_container(m);
4155 return c->signature ?: "";
4158 _public_ int sd_bus_message_copy(sd_bus_message *m, sd_bus_message *source, int all) {
4159 bool done_something = false;
4162 assert_return(m, -EINVAL);
4163 assert_return(source, -EINVAL);
4164 assert_return(!m->sealed, -EPERM);
4165 assert_return(source->sealed, -EPERM);
4168 const char *contents;
4183 r = sd_bus_message_peek_type(source, &type, &contents);
4189 done_something = true;
4191 if (bus_type_is_container(type) > 0) {
4193 r = sd_bus_message_enter_container(source, type, contents);
4197 r = sd_bus_message_open_container(m, type, contents);
4201 r = sd_bus_message_copy(m, source, true);
4205 r = sd_bus_message_close_container(m);
4209 r = sd_bus_message_exit_container(source);
4216 r = sd_bus_message_read_basic(source, type, &basic);
4222 if (type == SD_BUS_TYPE_OBJECT_PATH ||
4223 type == SD_BUS_TYPE_SIGNATURE ||
4224 type == SD_BUS_TYPE_STRING)
4225 r = sd_bus_message_append_basic(m, type, basic.string);
4227 r = sd_bus_message_append_basic(m, type, &basic);
4234 return done_something;
4237 _public_ int sd_bus_message_verify_type(sd_bus_message *m, char type, const char *contents) {
4242 assert_return(m, -EINVAL);
4243 assert_return(m->sealed, -EPERM);
4244 assert_return(!type || bus_type_is_valid(type), -EINVAL);
4245 assert_return(!contents || signature_is_valid(contents, true), -EINVAL);
4246 assert_return(type || contents, -EINVAL);
4247 assert_return(!contents || !type || bus_type_is_container(type), -EINVAL);
4249 r = sd_bus_message_peek_type(m, &t, &c);
4253 if (type != 0 && type != t)
4256 if (contents && !streq_ptr(contents, c))
4262 _public_ sd_bus *sd_bus_message_get_bus(sd_bus_message *m) {
4263 assert_return(m, NULL);