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 free(m->cmdline_array);
148 message_reset_containers(m);
149 free(m->root_container.signature);
151 free(m->peeked_signature);
159 static void *message_extend_fields(sd_bus_message *m, size_t align, size_t sz) {
161 size_t old_size, new_size, start;
168 old_size = sizeof(struct bus_header) + m->header->fields_size;
169 start = ALIGN_TO(old_size, align);
170 new_size = start + sz;
172 if (old_size == new_size)
173 return (uint8_t*) m->header + old_size;
175 if (new_size > (size_t) ((uint32_t) -1))
178 if (m->free_header) {
179 np = realloc(m->header, ALIGN8(new_size));
183 /* Initially, the header is allocated as part of of
184 * the sd_bus_message itself, let's replace it by
187 np = malloc(ALIGN8(new_size));
191 memcpy(np, m->header, sizeof(struct bus_header));
194 /* Zero out padding */
195 if (start > old_size)
196 memset((uint8_t*) np + old_size, 0, start - old_size);
200 m->header->fields_size = new_size - sizeof(struct bus_header);
202 /* Adjust quick access pointers */
203 m->path = adjust_pointer(m->path, op, old_size, m->header);
204 m->interface = adjust_pointer(m->interface, op, old_size, m->header);
205 m->member = adjust_pointer(m->member, op, old_size, m->header);
206 m->destination = adjust_pointer(m->destination, op, old_size, m->header);
207 m->sender = adjust_pointer(m->sender, op, old_size, m->header);
208 m->error.name = adjust_pointer(m->error.name, op, old_size, m->header);
210 m->free_header = true;
212 return (uint8_t*) np + start;
219 static int message_append_field_string(
232 if (l > (size_t) (uint32_t) -1)
235 /* field id byte + signature length + signature 's' + NUL + string length + string + NUL */
236 p = message_extend_fields(m, 8, 4 + 4 + l + 1);
245 ((uint32_t*) p)[1] = l;
246 memcpy(p + 8, s, l + 1);
249 *ret = (char*) p + 8;
254 static int message_append_field_signature(
269 /* field id byte + signature length + signature 'g' + NUL + string length + string + NUL */
270 p = message_extend_fields(m, 8, 4 + 1 + l + 1);
276 p[2] = SD_BUS_TYPE_SIGNATURE;
279 memcpy(p + 5, s, l + 1);
282 *ret = (const char*) p + 5;
287 static int message_append_field_uint32(sd_bus_message *m, uint8_t h, uint32_t x) {
292 /* field id byte + signature length + signature 'u' + NUL + value */
293 p = message_extend_fields(m, 8, 4 + 4);
299 p[2] = SD_BUS_TYPE_UINT32;
302 ((uint32_t*) p)[1] = x;
307 int bus_message_from_header(
313 const struct ucred *ucred,
316 sd_bus_message **ret) {
319 struct bus_header *h;
322 assert(buffer || length <= 0);
323 assert(fds || n_fds <= 0);
326 if (length < sizeof(struct bus_header))
336 if (h->type == _SD_BUS_MESSAGE_TYPE_INVALID)
339 if (h->endian != SD_BUS_LITTLE_ENDIAN &&
340 h->endian != SD_BUS_BIG_ENDIAN)
343 a = ALIGN(sizeof(sd_bus_message)) + ALIGN(extra);
346 label_sz = strlen(label);
364 m->uid_valid = m->gid_valid = true;
368 m->label = (char*) m + ALIGN(sizeof(sd_bus_message)) + ALIGN(extra);
369 memcpy(m->label, label, label_sz + 1);
373 m->bus = sd_bus_ref(bus);
379 int bus_message_from_malloc(
385 const struct ucred *ucred,
387 sd_bus_message **ret) {
392 r = bus_message_from_header(bus, buffer, length, fds, n_fds, ucred, label, 0, &m);
396 if (length != BUS_MESSAGE_SIZE(m)) {
402 m->body.data = (uint8_t*) buffer + sizeof(struct bus_header) + ALIGN8(BUS_MESSAGE_FIELDS_SIZE(m));
403 m->body.size = length - sizeof(struct bus_header) - ALIGN8(BUS_MESSAGE_FIELDS_SIZE(m));
404 m->body.sealed = true;
408 m->iovec = m->iovec_fixed;
409 m->iovec[0].iov_base = buffer;
410 m->iovec[0].iov_len = length;
412 r = bus_message_parse_fields(m);
416 /* We take possession of the memory and fds now */
417 m->free_header = true;
428 static sd_bus_message *message_new(sd_bus *bus, uint8_t type) {
431 m = malloc0(ALIGN(sizeof(sd_bus_message)) + sizeof(struct bus_header));
436 m->header = (struct bus_header*) ((uint8_t*) m + ALIGN(sizeof(struct sd_bus_message)));
437 m->header->endian = SD_BUS_NATIVE_ENDIAN;
438 m->header->type = type;
439 m->header->version = bus ? bus->message_version : 1;
440 m->allow_fds = !bus || bus->can_fds || (bus->state != BUS_HELLO && bus->state != BUS_RUNNING);
443 m->bus = sd_bus_ref(bus);
448 _public_ int sd_bus_message_new_signal(
451 const char *interface,
453 sd_bus_message **m) {
458 assert_return(!bus || bus->state != BUS_UNSET, -ENOTCONN);
459 assert_return(object_path_is_valid(path), -EINVAL);
460 assert_return(interface_name_is_valid(interface), -EINVAL);
461 assert_return(member_name_is_valid(member), -EINVAL);
462 assert_return(m, -EINVAL);
464 t = message_new(bus, SD_BUS_MESSAGE_SIGNAL);
468 t->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
470 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_PATH, SD_BUS_TYPE_OBJECT_PATH, path, &t->path);
473 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_INTERFACE, SD_BUS_TYPE_STRING, interface, &t->interface);
476 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_MEMBER, SD_BUS_TYPE_STRING, member, &t->member);
484 sd_bus_message_unref(t);
488 _public_ int sd_bus_message_new_method_call(
490 const char *destination,
492 const char *interface,
494 sd_bus_message **m) {
499 assert_return(!bus || bus->state != BUS_UNSET, -ENOTCONN);
500 assert_return(!destination || service_name_is_valid(destination), -EINVAL);
501 assert_return(object_path_is_valid(path), -EINVAL);
502 assert_return(!interface || interface_name_is_valid(interface), -EINVAL);
503 assert_return(member_name_is_valid(member), -EINVAL);
504 assert_return(m, -EINVAL);
506 t = message_new(bus, SD_BUS_MESSAGE_METHOD_CALL);
510 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_PATH, SD_BUS_TYPE_OBJECT_PATH, path, &t->path);
513 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_MEMBER, SD_BUS_TYPE_STRING, member, &t->member);
518 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_INTERFACE, SD_BUS_TYPE_STRING, interface, &t->interface);
524 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &t->destination);
537 static int message_new_reply(
538 sd_bus_message *call,
540 sd_bus_message **m) {
545 assert_return(call, -EINVAL);
546 assert_return(call->sealed, -EPERM);
547 assert_return(call->header->type == SD_BUS_MESSAGE_METHOD_CALL, -EINVAL);
548 assert_return(!call->bus || call->bus->state != BUS_UNSET, -ENOTCONN);
549 assert_return(m, -EINVAL);
551 t = message_new(call->bus, type);
555 t->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
556 t->reply_serial = BUS_MESSAGE_SERIAL(call);
558 r = message_append_field_uint32(t, SD_BUS_MESSAGE_HEADER_REPLY_SERIAL, t->reply_serial);
563 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, call->sender, &t->destination);
568 t->dont_send = !!(call->header->flags & SD_BUS_MESSAGE_NO_REPLY_EXPECTED);
578 _public_ int sd_bus_message_new_method_return(
579 sd_bus_message *call,
580 sd_bus_message **m) {
582 return message_new_reply(call, SD_BUS_MESSAGE_METHOD_RETURN, m);
585 _public_ int sd_bus_message_new_method_error(
586 sd_bus_message *call,
587 const sd_bus_error *e,
588 sd_bus_message **m) {
593 assert_return(sd_bus_error_is_set(e), -EINVAL);
594 assert_return(m, -EINVAL);
596 r = message_new_reply(call, SD_BUS_MESSAGE_METHOD_ERROR, &t);
600 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_ERROR_NAME, SD_BUS_TYPE_STRING, e->name, &t->error.name);
605 r = message_append_basic(t, SD_BUS_TYPE_STRING, e->message, (const void**) &t->error.message);
618 _public_ int sd_bus_message_new_method_errorf(
619 sd_bus_message *call,
625 _cleanup_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
628 assert_return(name, -EINVAL);
629 assert_return(m, -EINVAL);
631 va_start(ap, format);
632 bus_error_setfv(&error, name, format, ap);
635 return sd_bus_message_new_method_error(call, &error, m);
638 _public_ int sd_bus_message_new_method_errno(
639 sd_bus_message *call,
641 const sd_bus_error *p,
642 sd_bus_message **m) {
644 _cleanup_free_ sd_bus_error berror = SD_BUS_ERROR_NULL;
646 if (sd_bus_error_is_set(p))
647 return sd_bus_message_new_method_error(call, p, m);
649 sd_bus_error_set_errno(&berror, error);
651 return sd_bus_message_new_method_error(call, &berror, m);
654 _public_ int sd_bus_message_new_method_errnof(
655 sd_bus_message *call,
661 _cleanup_free_ sd_bus_error berror = SD_BUS_ERROR_NULL;
664 va_start(ap, format);
665 bus_error_set_errnofv(&berror, error, format, ap);
668 return sd_bus_message_new_method_error(call, &berror, m);
671 int bus_message_new_synthetic_error(
674 const sd_bus_error *e,
675 sd_bus_message **m) {
680 assert(sd_bus_error_is_set(e));
683 t = message_new(bus, SD_BUS_MESSAGE_METHOD_ERROR);
687 t->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
688 t->reply_serial = serial;
690 r = message_append_field_uint32(t, SD_BUS_MESSAGE_HEADER_REPLY_SERIAL, t->reply_serial);
694 if (bus && bus->unique_name) {
695 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, bus->unique_name, &t->destination);
700 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_ERROR_NAME, SD_BUS_TYPE_STRING, e->name, &t->error.name);
705 r = message_append_basic(t, SD_BUS_TYPE_STRING, e->message, (const void**) &t->error.message);
718 _public_ sd_bus_message* sd_bus_message_ref(sd_bus_message *m) {
719 assert_return(m, NULL);
721 assert(m->n_ref > 0);
727 _public_ sd_bus_message* sd_bus_message_unref(sd_bus_message *m) {
728 assert_return(m, NULL);
730 assert(m->n_ref > 0);
739 _public_ int sd_bus_message_get_type(sd_bus_message *m, uint8_t *type) {
740 assert_return(m, -EINVAL);
741 assert_return(type, -EINVAL);
743 *type = m->header->type;
747 _public_ int sd_bus_message_get_serial(sd_bus_message *m, uint64_t *serial) {
748 assert_return(m, -EINVAL);
749 assert_return(serial, -EINVAL);
750 assert_return(m->header->serial != 0, -ENOENT);
752 *serial = BUS_MESSAGE_SERIAL(m);
756 _public_ int sd_bus_message_get_reply_serial(sd_bus_message *m, uint64_t *serial) {
757 assert_return(m, -EINVAL);
758 assert_return(serial, -EINVAL);
759 assert_return(m->reply_serial != 0, -ENOENT);
761 *serial = m->reply_serial;
765 _public_ int sd_bus_message_get_no_reply(sd_bus_message *m) {
766 assert_return(m, -EINVAL);
768 return m->header->type == SD_BUS_MESSAGE_METHOD_CALL ? !!(m->header->flags & SD_BUS_MESSAGE_NO_REPLY_EXPECTED) : 0;
771 _public_ int sd_bus_message_get_no_auto_start(sd_bus_message *m) {
772 assert_return(m, -EINVAL);
774 return !!(m->header->flags & SD_BUS_MESSAGE_NO_AUTO_START);
777 _public_ const char *sd_bus_message_get_path(sd_bus_message *m) {
778 assert_return(m, NULL);
783 _public_ const char *sd_bus_message_get_interface(sd_bus_message *m) {
784 assert_return(m, NULL);
789 _public_ const char *sd_bus_message_get_member(sd_bus_message *m) {
790 assert_return(m, NULL);
795 _public_ const char *sd_bus_message_get_destination(sd_bus_message *m) {
796 assert_return(m, NULL);
798 return m->destination;
801 _public_ const char *sd_bus_message_get_sender(sd_bus_message *m) {
802 assert_return(m, NULL);
807 _public_ const sd_bus_error *sd_bus_message_get_error(sd_bus_message *m) {
808 assert_return(m, NULL);
809 assert_return(sd_bus_error_is_set(&m->error), NULL);
814 _public_ int sd_bus_message_get_uid(sd_bus_message *m, uid_t *uid) {
815 assert_return(m, -EINVAL);
816 assert_return(uid, -EINVAL);
817 assert_return(m->uid_valid, -ESRCH);
823 _public_ int sd_bus_message_get_gid(sd_bus_message *m, gid_t *gid) {
824 assert_return(m, -EINVAL);
825 assert_return(gid, -EINVAL);
826 assert_return(m->gid_valid, -ESRCH);
832 _public_ int sd_bus_message_get_pid(sd_bus_message *m, pid_t *pid) {
833 assert_return(m, -EINVAL);
834 assert_return(pid, -EINVAL);
835 assert_return(m->pid > 0, -ESRCH);
841 _public_ int sd_bus_message_get_tid(sd_bus_message *m, pid_t *tid) {
842 assert_return(m, -EINVAL);
843 assert_return(tid, -EINVAL);
844 assert_return(m->tid > 0, -ESRCH);
850 _public_ int sd_bus_message_get_pid_starttime(sd_bus_message *m, uint64_t *usec) {
851 assert_return(m, -EINVAL);
852 assert_return(usec, -EINVAL);
853 assert_return(m->pid_starttime > 0, -ESRCH);
855 *usec = m->pid_starttime;
859 _public_ int sd_bus_message_get_selinux_context(sd_bus_message *m, const char **ret) {
860 assert_return(m, -EINVAL);
861 assert_return(m->label, -ESRCH);
867 _public_ int sd_bus_message_get_monotonic_timestamp(sd_bus_message *m, uint64_t *usec) {
868 assert_return(m, -EINVAL);
869 assert_return(usec, -EINVAL);
870 assert_return(m->monotonic > 0, -ESRCH);
872 *usec = m->monotonic;
876 _public_ int sd_bus_message_get_realtime_timestamp(sd_bus_message *m, uint64_t *usec) {
877 assert_return(m, -EINVAL);
878 assert_return(usec, -EINVAL);
879 assert_return(m->realtime > 0, -ESRCH);
885 _public_ int sd_bus_message_get_comm(sd_bus_message *m, const char **ret) {
886 assert_return(m, -EINVAL);
887 assert_return(ret, -EINVAL);
888 assert_return(m->comm, -ESRCH);
894 _public_ int sd_bus_message_get_tid_comm(sd_bus_message *m, const char **ret) {
895 assert_return(m, -EINVAL);
896 assert_return(ret, -EINVAL);
897 assert_return(m->tid_comm, -ESRCH);
903 _public_ int sd_bus_message_get_exe(sd_bus_message *m, const char **ret) {
904 assert_return(m, -EINVAL);
905 assert_return(ret, -EINVAL);
906 assert_return(m->exe, -ESRCH);
912 _public_ int sd_bus_message_get_cgroup(sd_bus_message *m, const char **ret) {
913 assert_return(m, -EINVAL);
914 assert_return(ret, -EINVAL);
915 assert_return(m->cgroup, -ESRCH);
921 _public_ int sd_bus_message_get_unit(sd_bus_message *m, const char **ret) {
924 assert_return(m, -EINVAL);
925 assert_return(ret, -EINVAL);
926 assert_return(m->cgroup, -ESRCH);
929 r = cg_path_get_unit(m->cgroup, &m->unit);
938 _public_ int sd_bus_message_get_user_unit(sd_bus_message *m, const char **ret) {
941 assert_return(m, -EINVAL);
942 assert_return(ret, -EINVAL);
943 assert_return(m->cgroup, -ESRCH);
946 r = cg_path_get_user_unit(m->cgroup, &m->user_unit);
955 _public_ int sd_bus_message_get_session(sd_bus_message *m, const char **ret) {
958 assert_return(m, -EINVAL);
959 assert_return(ret, -EINVAL);
960 assert_return(m->cgroup, -ESRCH);
963 r = cg_path_get_session(m->cgroup, &m->session);
972 _public_ int sd_bus_message_get_owner_uid(sd_bus_message *m, uid_t *uid) {
973 assert_return(m, -EINVAL);
974 assert_return(uid, -EINVAL);
975 assert_return(m->cgroup, -ESRCH);
977 return cg_path_get_owner_uid(m->cgroup, uid);
980 _public_ int sd_bus_message_get_cmdline(sd_bus_message *m, char ***cmdline) {
985 assert_return(m, -EINVAL);
986 assert_return(m->cmdline, -ESRCH);
988 for (p = m->cmdline, n = 0; p < m->cmdline + m->cmdline_length; p++)
992 m->cmdline_array = new(char*, n + 1);
993 if (!m->cmdline_array)
996 for (p = m->cmdline, i = 0, first = true; p < m->cmdline + m->cmdline_length; p++) {
998 m->cmdline_array[i++] = (char*) p;
1003 m->cmdline_array[i] = NULL;
1004 *cmdline = m->cmdline_array;
1009 _public_ int sd_bus_message_get_audit_sessionid(sd_bus_message *m, uint32_t *sessionid) {
1010 assert_return(m, -EINVAL);
1011 assert_return(sessionid, -EINVAL);
1012 assert_return(m->audit, -ESRCH);
1014 *sessionid = m->audit->sessionid;
1018 _public_ int sd_bus_message_get_audit_loginuid(sd_bus_message *m, uid_t *uid) {
1019 assert_return(m, -EINVAL);
1020 assert_return(uid, -EINVAL);
1021 assert_return(m->audit, -ESRCH);
1023 *uid = m->audit->loginuid;
1027 _public_ int sd_bus_message_has_effective_cap(sd_bus_message *m, int capability) {
1030 assert_return(m, -EINVAL);
1031 assert_return(capability < 0, -EINVAL);
1032 assert_return(!m->capability, -ESRCH);
1034 sz = m->capability_size / 4;
1035 if ((unsigned) capability >= sz*8)
1038 return !!(m->capability[2 * sz + (capability / 8)] & (1 << (capability % 8)));
1041 _public_ int sd_bus_message_is_signal(sd_bus_message *m,
1042 const char *interface,
1043 const char *member) {
1044 assert_return(m, -EINVAL);
1046 if (m->header->type != SD_BUS_MESSAGE_SIGNAL)
1049 if (interface && (!m->interface || !streq(m->interface, interface)))
1052 if (member && (!m->member || !streq(m->member, member)))
1058 _public_ int sd_bus_message_is_method_call(sd_bus_message *m,
1059 const char *interface,
1060 const char *member) {
1061 assert_return(m, -EINVAL);
1063 if (m->header->type != SD_BUS_MESSAGE_METHOD_CALL)
1066 if (interface && (!m->interface || !streq(m->interface, interface)))
1069 if (member && (!m->member || !streq(m->member, member)))
1075 _public_ int sd_bus_message_is_method_error(sd_bus_message *m, const char *name) {
1076 assert_return(m, -EINVAL);
1078 if (m->header->type != SD_BUS_MESSAGE_METHOD_ERROR)
1081 if (name && (!m->error.name || !streq(m->error.name, name)))
1087 _public_ int sd_bus_message_set_no_reply(sd_bus_message *m, int b) {
1088 assert_return(m, -EINVAL);
1089 assert_return(!m->sealed, -EPERM);
1090 assert_return(m->header->type == SD_BUS_MESSAGE_METHOD_CALL, -EPERM);
1093 m->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
1095 m->header->flags &= ~SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
1100 _public_ int sd_bus_message_set_no_auto_start(sd_bus_message *m, int b) {
1101 assert_return(m, -EINVAL);
1102 assert_return(!m->sealed, -EPERM);
1105 m->header->flags |= SD_BUS_MESSAGE_NO_AUTO_START;
1107 m->header->flags &= ~SD_BUS_MESSAGE_NO_AUTO_START;
1112 static struct bus_container *message_get_container(sd_bus_message *m) {
1115 if (m->n_containers == 0)
1116 return &m->root_container;
1118 assert(m->containers);
1119 return m->containers + m->n_containers - 1;
1122 struct bus_body_part *message_append_part(sd_bus_message *m) {
1123 struct bus_body_part *part;
1130 if (m->n_body_parts <= 0) {
1134 assert(m->body_end);
1136 part = new0(struct bus_body_part, 1);
1142 m->body_end->next = part;
1152 static void part_zero(struct bus_body_part *part, size_t sz) {
1157 /* All other fields can be left in their defaults */
1158 assert(!part->data);
1159 assert(part->memfd < 0);
1162 part->is_zero = true;
1163 part->sealed = true;
1166 static int part_make_space(
1167 struct sd_bus_message *m,
1168 struct bus_body_part *part,
1177 assert(!part->sealed);
1182 if (!part->data && part->memfd < 0)
1183 part->memfd = bus_kernel_pop_memfd(m->bus, &part->data, &part->mapped);
1185 if (part->memfd >= 0) {
1188 r = ioctl(part->memfd, KDBUS_CMD_MEMFD_SIZE_SET, &u);
1194 if (!part->data || sz > part->mapped) {
1195 size_t psz = PAGE_ALIGN(sz > 0 ? sz : 1);
1197 if (part->mapped <= 0)
1198 n = mmap(NULL, psz, PROT_READ|PROT_WRITE, MAP_SHARED, part->memfd, 0);
1200 n = mremap(part->data, part->mapped, psz, MREMAP_MAYMOVE);
1202 if (n == MAP_FAILED) {
1211 part->munmap_this = true;
1213 n = realloc(part->data, MAX(sz, 1u));
1220 part->free_this = true;
1224 *q = part->data ? (uint8_t*) part->data + part->size : NULL;
1230 static void message_extend_containers(sd_bus_message *m, size_t expand) {
1231 struct bus_container *c;
1238 /* Update counters */
1239 for (c = m->containers; c < m->containers + m->n_containers; c++)
1241 *c->array_size += expand;
1244 static void *message_extend_body(sd_bus_message *m, size_t align, size_t sz) {
1245 struct bus_body_part *part = NULL;
1246 size_t start_body, end_body, padding, start_part, end_part, added;
1258 start_body = ALIGN_TO((size_t) m->header->body_size, align);
1259 end_body = start_body + sz;
1261 padding = start_body - m->header->body_size;
1262 added = padding + sz;
1264 /* Check for 32bit overflows */
1265 if (end_body > (size_t) ((uint32_t) -1)) {
1271 m->n_body_parts <= 0 ||
1272 m->body_end->sealed ||
1273 padding != ALIGN_TO(m->body_end->size, align) - m->body_end->size;
1277 part = message_append_part(m);
1281 part_zero(part, padding);
1284 part = message_append_part(m);
1288 r = part_make_space(m, part, sz, &p);
1292 struct bus_container *c;
1300 start_part = ALIGN_TO(part->size, align);
1301 end_part = start_part + sz;
1303 r = part_make_space(m, part, end_part, &p);
1308 memset(p, 0, padding);
1309 p = (uint8_t*) p + padding;
1312 /* Readjust pointers */
1313 for (c = m->containers; c < m->containers + m->n_containers; c++)
1314 c->array_size = adjust_pointer(c->array_size, op, os, part->data);
1316 m->error.message = (const char*) adjust_pointer(m->error.message, op, os, part->data);
1319 m->header->body_size = end_body;
1320 message_extend_containers(m, added);
1325 int message_append_basic(sd_bus_message *m, char type, const void *p, const void **stored) {
1326 struct bus_container *c;
1334 assert_return(m, -EINVAL);
1335 assert_return(!m->sealed, -EPERM);
1336 assert_return(bus_type_is_basic(type), -EINVAL);
1337 assert_return(!m->poisoned, -ESTALE);
1339 c = message_get_container(m);
1341 if (c->signature && c->signature[c->index]) {
1342 /* Container signature is already set */
1344 if (c->signature[c->index] != type)
1349 /* Maybe we can append to the signature? But only if this is the top-level container*/
1350 if (c->enclosing != 0)
1353 e = strextend(&c->signature, CHAR_TO_STR(type), NULL);
1362 case SD_BUS_TYPE_STRING:
1363 /* To make things easy we'll serialize a NULL string
1364 * into the empty string */
1367 /* Fall through... */
1368 case SD_BUS_TYPE_OBJECT_PATH:
1376 sz = 4 + strlen(p) + 1;
1379 case SD_BUS_TYPE_SIGNATURE:
1387 sz = 1 + strlen(p) + 1;
1390 case SD_BUS_TYPE_BOOLEAN:
1399 assert_cc(sizeof(int) == sizeof(uint32_t));
1405 case SD_BUS_TYPE_UNIX_FD: {
1413 if (!m->allow_fds) {
1426 fd = fcntl(z, F_DUPFD_CLOEXEC, 3);
1432 f = realloc(m->fds, sizeof(int) * (m->n_fds + 1));
1452 align = bus_type_get_alignment(type);
1453 sz = bus_type_get_size(type);
1460 a = message_extend_body(m, align, sz);
1466 if (type == SD_BUS_TYPE_STRING || type == SD_BUS_TYPE_OBJECT_PATH) {
1467 *(uint32_t*) a = sz - 5;
1468 memcpy((uint8_t*) a + 4, p, sz - 4);
1471 *stored = (const uint8_t*) a + 4;
1473 } else if (type == SD_BUS_TYPE_SIGNATURE) {
1474 *(uint8_t*) a = sz - 1;
1475 memcpy((uint8_t*) a + 1, p, sz - 1);
1478 *stored = (const uint8_t*) a + 1;
1479 } else if (type == SD_BUS_TYPE_UNIX_FD) {
1480 *(uint32_t*) a = fdi;
1494 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1501 close_nointr_nofail(fd);
1506 _public_ int sd_bus_message_append_basic(sd_bus_message *m, char type, const void *p) {
1507 return message_append_basic(m, type, p, NULL);
1510 _public_ int sd_bus_message_append_string_space(
1515 struct bus_container *c;
1518 assert_return(m, -EINVAL);
1519 assert_return(s, -EINVAL);
1520 assert_return(!m->sealed, -EPERM);
1521 assert_return(!m->poisoned, -ESTALE);
1523 c = message_get_container(m);
1525 if (c->signature && c->signature[c->index]) {
1526 /* Container signature is already set */
1528 if (c->signature[c->index] != SD_BUS_TYPE_STRING)
1533 /* Maybe we can append to the signature? But only if this is the top-level container*/
1534 if (c->enclosing != 0)
1537 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRING), NULL);
1544 a = message_extend_body(m, 4, 4 + size + 1);
1548 *(uint32_t*) a = size;
1553 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1559 _public_ int sd_bus_message_append_string_iovec(
1561 const struct iovec *iov,
1569 assert_return(m, -EINVAL);
1570 assert_return(!m->sealed, -EPERM);
1571 assert_return(iov || n == 0, -EINVAL);
1572 assert_return(!m->poisoned, -ESTALE);
1574 size = IOVEC_TOTAL_SIZE(iov, n);
1576 r = sd_bus_message_append_string_space(m, size, &p);
1580 for (i = 0; i < n; i++) {
1582 if (iov[i].iov_base)
1583 memcpy(p, iov[i].iov_base, iov[i].iov_len);
1585 memset(p, ' ', iov[i].iov_len);
1587 p += iov[i].iov_len;
1593 static int bus_message_open_array(
1595 struct bus_container *c,
1596 const char *contents,
1597 uint32_t **array_size) {
1603 struct bus_body_part *o;
1610 if (!signature_is_single(contents, true))
1613 alignment = bus_type_get_alignment(contents[0]);
1617 if (c->signature && c->signature[c->index]) {
1619 /* Verify the existing signature */
1621 if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
1624 if (!startswith(c->signature + c->index + 1, contents))
1627 nindex = c->index + 1 + strlen(contents);
1631 if (c->enclosing != 0)
1634 /* Extend the existing signature */
1636 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_ARRAY), contents, NULL);
1642 nindex = e - c->signature;
1645 a = message_extend_body(m, 4, 4);
1650 op = m->body_end->data;
1651 os = m->body_end->size;
1653 /* Add alignment between size and first element */
1654 if (!message_extend_body(m, alignment, 0))
1657 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1660 /* location of array size might have changed so let's readjust a */
1661 if (o == m->body_end)
1662 a = adjust_pointer(a, op, os, m->body_end->data);
1669 static int bus_message_open_variant(
1671 struct bus_container *c,
1672 const char *contents) {
1681 if (!signature_is_single(contents, false))
1684 if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
1687 if (c->signature && c->signature[c->index]) {
1689 if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
1695 if (c->enclosing != 0)
1698 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_VARIANT), NULL);
1705 l = strlen(contents);
1706 a = message_extend_body(m, 1, 1 + l + 1);
1711 memcpy((uint8_t*) a + 1, contents, l + 1);
1713 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1719 static int bus_message_open_struct(
1721 struct bus_container *c,
1722 const char *contents) {
1730 if (!signature_is_valid(contents, false))
1733 if (c->signature && c->signature[c->index]) {
1736 l = strlen(contents);
1738 if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
1739 !startswith(c->signature + c->index + 1, contents) ||
1740 c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
1743 nindex = c->index + 1 + l + 1;
1747 if (c->enclosing != 0)
1750 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_BEGIN), contents, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_END), NULL);
1756 nindex = e - c->signature;
1759 /* Align contents to 8 byte boundary */
1760 if (!message_extend_body(m, 8, 0))
1763 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1769 static int bus_message_open_dict_entry(
1771 struct bus_container *c,
1772 const char *contents) {
1780 if (!signature_is_pair(contents))
1783 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1786 if (c->signature && c->signature[c->index]) {
1789 l = strlen(contents);
1791 if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
1792 !startswith(c->signature + c->index + 1, contents) ||
1793 c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
1796 nindex = c->index + 1 + l + 1;
1800 /* Align contents to 8 byte boundary */
1801 if (!message_extend_body(m, 8, 0))
1804 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1810 _public_ int sd_bus_message_open_container(
1813 const char *contents) {
1815 struct bus_container *c, *w;
1816 uint32_t *array_size = NULL;
1821 assert_return(m, -EINVAL);
1822 assert_return(!m->sealed, -EPERM);
1823 assert_return(contents, -EINVAL);
1824 assert_return(!m->poisoned, -ESTALE);
1826 /* Make sure we have space for one more container */
1827 w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
1835 c = message_get_container(m);
1837 signature = strdup(contents);
1843 /* Save old index in the parent container, in case we have to
1844 * abort this container */
1845 c->saved_index = c->index;
1846 before = m->header->body_size;
1848 if (type == SD_BUS_TYPE_ARRAY)
1849 r = bus_message_open_array(m, c, contents, &array_size);
1850 else if (type == SD_BUS_TYPE_VARIANT)
1851 r = bus_message_open_variant(m, c, contents);
1852 else if (type == SD_BUS_TYPE_STRUCT)
1853 r = bus_message_open_struct(m, c, contents);
1854 else if (type == SD_BUS_TYPE_DICT_ENTRY)
1855 r = bus_message_open_dict_entry(m, c, contents);
1864 /* OK, let's fill it in */
1865 w += m->n_containers++;
1866 w->enclosing = type;
1867 w->signature = signature;
1869 w->array_size = array_size;
1871 w->begin = m->rindex;
1876 _public_ int sd_bus_message_close_container(sd_bus_message *m) {
1877 struct bus_container *c;
1879 assert_return(m, -EINVAL);
1880 assert_return(!m->sealed, -EPERM);
1881 assert_return(m->n_containers > 0, -EINVAL);
1882 assert_return(!m->poisoned, -ESTALE);
1884 c = message_get_container(m);
1885 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1886 if (c->signature && c->signature[c->index] != 0)
1901 static int type_stack_push(TypeStack *stack, unsigned max, unsigned *i, const char *types, unsigned n_struct, unsigned n_array) {
1908 stack[*i].types = types;
1909 stack[*i].n_struct = n_struct;
1910 stack[*i].n_array = n_array;
1916 static int type_stack_pop(TypeStack *stack, unsigned max, unsigned *i, const char **types, unsigned *n_struct, unsigned *n_array) {
1927 *types = stack[*i].types;
1928 *n_struct = stack[*i].n_struct;
1929 *n_array = stack[*i].n_array;
1934 int bus_message_append_ap(
1939 unsigned n_array, n_struct;
1940 TypeStack stack[BUS_CONTAINER_DEPTH];
1941 unsigned stack_ptr = 0;
1949 n_array = (unsigned) -1;
1950 n_struct = strlen(types);
1955 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
1956 r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
1962 r = sd_bus_message_close_container(m);
1970 if (n_array != (unsigned) -1)
1979 case SD_BUS_TYPE_BYTE: {
1982 x = (uint8_t) va_arg(ap, int);
1983 r = sd_bus_message_append_basic(m, *t, &x);
1987 case SD_BUS_TYPE_BOOLEAN:
1988 case SD_BUS_TYPE_INT32:
1989 case SD_BUS_TYPE_UINT32:
1990 case SD_BUS_TYPE_UNIX_FD: {
1993 /* We assume a boolean is the same as int32_t */
1994 assert_cc(sizeof(int32_t) == sizeof(int));
1996 x = va_arg(ap, uint32_t);
1997 r = sd_bus_message_append_basic(m, *t, &x);
2001 case SD_BUS_TYPE_INT16:
2002 case SD_BUS_TYPE_UINT16: {
2005 x = (uint16_t) va_arg(ap, int);
2006 r = sd_bus_message_append_basic(m, *t, &x);
2010 case SD_BUS_TYPE_INT64:
2011 case SD_BUS_TYPE_UINT64:
2012 case SD_BUS_TYPE_DOUBLE: {
2015 x = va_arg(ap, uint64_t);
2016 r = sd_bus_message_append_basic(m, *t, &x);
2020 case SD_BUS_TYPE_STRING:
2021 case SD_BUS_TYPE_OBJECT_PATH:
2022 case SD_BUS_TYPE_SIGNATURE: {
2025 x = va_arg(ap, const char*);
2026 r = sd_bus_message_append_basic(m, *t, x);
2030 case SD_BUS_TYPE_ARRAY: {
2033 r = signature_element_length(t + 1, &k);
2039 memcpy(s, t + 1, k);
2042 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, s);
2047 if (n_array == (unsigned) -1) {
2052 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2058 n_array = va_arg(ap, unsigned);
2063 case SD_BUS_TYPE_VARIANT: {
2066 s = va_arg(ap, const char*);
2070 r = sd_bus_message_open_container(m, SD_BUS_TYPE_VARIANT, s);
2074 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2079 n_struct = strlen(s);
2080 n_array = (unsigned) -1;
2085 case SD_BUS_TYPE_STRUCT_BEGIN:
2086 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
2089 r = signature_element_length(t, &k);
2096 memcpy(s, t + 1, k - 2);
2099 r = sd_bus_message_open_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
2104 if (n_array == (unsigned) -1) {
2109 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2115 n_array = (unsigned) -1;
2131 _public_ int sd_bus_message_append(sd_bus_message *m, const char *types, ...) {
2135 assert_return(m, -EINVAL);
2136 assert_return(types, -EINVAL);
2137 assert_return(!m->sealed, -EPERM);
2138 assert_return(!m->poisoned, -ESTALE);
2140 va_start(ap, types);
2141 r = bus_message_append_ap(m, types, ap);
2147 _public_ int sd_bus_message_append_array_space(sd_bus_message *m,
2155 assert_return(m, -EINVAL);
2156 assert_return(!m->sealed, -EPERM);
2157 assert_return(bus_type_is_trivial(type), -EINVAL);
2158 assert_return(ptr || size == 0, -EINVAL);
2159 assert_return(!m->poisoned, -ESTALE);
2161 align = bus_type_get_alignment(type);
2162 sz = bus_type_get_size(type);
2164 assert_se(align > 0);
2170 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
2174 a = message_extend_body(m, align, size);
2178 r = sd_bus_message_close_container(m);
2186 _public_ int sd_bus_message_append_array(sd_bus_message *m,
2193 assert_return(m, -EINVAL);
2194 assert_return(!m->sealed, -EPERM);
2195 assert_return(bus_type_is_trivial(type), -EINVAL);
2196 assert_return(ptr || size == 0, -EINVAL);
2197 assert_return(!m->poisoned, -ESTALE);
2199 r = sd_bus_message_append_array_space(m, type, size, &p);
2204 memcpy(p, ptr, size);
2209 _public_ int sd_bus_message_append_array_iovec(
2212 const struct iovec *iov,
2220 assert_return(m, -EINVAL);
2221 assert_return(!m->sealed, -EPERM);
2222 assert_return(bus_type_is_trivial(type), -EINVAL);
2223 assert_return(iov || n == 0, -EINVAL);
2224 assert_return(!m->poisoned, -ESTALE);
2226 size = IOVEC_TOTAL_SIZE(iov, n);
2228 r = sd_bus_message_append_array_space(m, type, size, &p);
2232 for (i = 0; i < n; i++) {
2234 if (iov[i].iov_base)
2235 memcpy(p, iov[i].iov_base, iov[i].iov_len);
2237 memset(p, 0, iov[i].iov_len);
2239 p = (uint8_t*) p + iov[i].iov_len;
2245 _public_ int sd_bus_message_append_array_memfd(sd_bus_message *m,
2248 _cleanup_close_ int copy_fd = -1;
2249 struct bus_body_part *part;
2261 if (!bus_type_is_trivial(type))
2266 r = sd_memfd_set_sealed(memfd, true);
2270 copy_fd = sd_memfd_dup_fd(memfd);
2274 r = sd_memfd_get_size(memfd, &size);
2278 align = bus_type_get_alignment(type);
2279 sz = bus_type_get_size(type);
2281 assert_se(align > 0);
2287 if (size > (uint64_t) (uint32_t) -1)
2290 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
2294 a = message_extend_body(m, align, 0);
2298 part = message_append_part(m);
2302 part->memfd = copy_fd;
2303 part->sealed = true;
2307 message_extend_containers(m, size);
2308 m->header->body_size += size;
2310 return sd_bus_message_close_container(m);
2313 _public_ int sd_bus_message_append_string_memfd(sd_bus_message *m, sd_memfd *memfd) {
2314 _cleanup_close_ int copy_fd = -1;
2315 struct bus_body_part *part;
2316 struct bus_container *c;
2321 assert_return(m, -EINVAL);
2322 assert_return(memfd, -EINVAL);
2323 assert_return(!m->sealed, -EPERM);
2324 assert_return(!m->poisoned, -ESTALE);
2326 r = sd_memfd_set_sealed(memfd, true);
2330 copy_fd = sd_memfd_dup_fd(memfd);
2334 r = sd_memfd_get_size(memfd, &size);
2338 /* We require this to be NUL terminated */
2342 if (size > (uint64_t) (uint32_t) -1)
2345 c = message_get_container(m);
2346 if (c->signature && c->signature[c->index]) {
2347 /* Container signature is already set */
2349 if (c->signature[c->index] != SD_BUS_TYPE_STRING)
2354 /* Maybe we can append to the signature? But only if this is the top-level container*/
2355 if (c->enclosing != 0)
2358 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRING), NULL);
2365 a = message_extend_body(m, 4, 4);
2369 *(uint32_t*) a = size - 1;
2371 part = message_append_part(m);
2375 part->memfd = copy_fd;
2376 part->sealed = true;
2380 message_extend_containers(m, size);
2381 m->header->body_size += size;
2383 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2389 _public_ int sd_bus_message_append_strv(sd_bus_message *m, char **l) {
2393 assert_return(m, -EINVAL);
2394 assert_return(!m->sealed, -EPERM);
2395 assert_return(!m->poisoned, -ESTALE);
2397 r = sd_bus_message_open_container(m, 'a', "s");
2401 STRV_FOREACH(i, l) {
2402 r = sd_bus_message_append_basic(m, 's', *i);
2407 return sd_bus_message_close_container(m);
2410 int bus_body_part_map(struct bus_body_part *part) {
2419 if (part->size <= 0)
2422 /* For smaller zero parts (as used for padding) we don't need to map anything... */
2423 if (part->memfd < 0 && part->is_zero && part->size < 8) {
2424 static const uint8_t zeroes[7] = { };
2425 part->data = (void*) zeroes;
2429 psz = PAGE_ALIGN(part->size);
2431 if (part->memfd >= 0)
2432 p = mmap(NULL, psz, PROT_READ, MAP_SHARED, part->memfd, 0);
2433 else if (part->is_zero)
2434 p = mmap(NULL, psz, PROT_READ, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
2438 if (p == MAP_FAILED)
2443 part->munmap_this = true;
2448 void bus_body_part_unmap(struct bus_body_part *part) {
2452 if (part->memfd < 0)
2458 if (!part->munmap_this)
2461 assert_se(munmap(part->data, part->mapped) == 0);
2465 part->munmap_this = false;
2470 static int buffer_peek(const void *p, uint32_t sz, size_t *rindex, size_t align, size_t nbytes, void **r) {
2471 size_t k, start, end;
2476 start = ALIGN_TO((size_t) *rindex, align);
2477 end = start + nbytes;
2482 /* Verify that padding is 0 */
2483 for (k = *rindex; k < start; k++)
2484 if (((const uint8_t*) p)[k] != 0)
2488 *r = (uint8_t*) p + start;
2495 static bool message_end_of_signature(sd_bus_message *m) {
2496 struct bus_container *c;
2500 c = message_get_container(m);
2501 return !c->signature || c->signature[c->index] == 0;
2504 static bool message_end_of_array(sd_bus_message *m, size_t index) {
2505 struct bus_container *c;
2509 c = message_get_container(m);
2513 return index >= c->begin + BUS_MESSAGE_BSWAP32(m, *c->array_size);
2516 _public_ int sd_bus_message_at_end(sd_bus_message *m, int complete) {
2517 assert_return(m, -EINVAL);
2518 assert_return(m->sealed, -EPERM);
2520 if (complete && m->n_containers > 0)
2523 if (message_end_of_signature(m))
2526 if (message_end_of_array(m, m->rindex))
2532 static struct bus_body_part* find_part(sd_bus_message *m, size_t index, size_t sz, void **p) {
2533 struct bus_body_part *part;
2539 if (m->cached_rindex_part && index >= m->cached_rindex_part_begin) {
2540 part = m->cached_rindex_part;
2541 begin = m->cached_rindex_part_begin;
2551 if (index + sz <= begin + part->size) {
2553 r = bus_body_part_map(part);
2558 *p = (uint8_t*) part->data + index - begin;
2560 m->cached_rindex_part = part;
2561 m->cached_rindex_part_begin = begin;
2566 begin += part->size;
2573 static int message_peek_body(
2580 size_t k, start, end, padding;
2581 struct bus_body_part *part;
2588 if (message_end_of_array(m, *rindex))
2591 start = ALIGN_TO((size_t) *rindex, align);
2592 padding = start - *rindex;
2593 end = start + nbytes;
2595 if (end > BUS_MESSAGE_BODY_SIZE(m))
2598 part = find_part(m, *rindex, padding, (void**) &q);
2603 /* Verify padding */
2604 for (k = 0; k < padding; k++)
2609 part = find_part(m, start, nbytes, (void**) &q);
2621 static bool validate_nul(const char *s, size_t l) {
2623 /* Check for NUL chars in the string */
2624 if (memchr(s, 0, l))
2627 /* Check for NUL termination */
2634 static bool validate_string(const char *s, size_t l) {
2636 if (!validate_nul(s, l))
2639 /* Check if valid UTF8 */
2640 if (!utf8_is_valid(s))
2646 static bool validate_signature(const char *s, size_t l) {
2648 if (!validate_nul(s, l))
2651 /* Check if valid signature */
2652 if (!signature_is_valid(s, true))
2658 static bool validate_object_path(const char *s, size_t l) {
2660 if (!validate_nul(s, l))
2663 if (!object_path_is_valid(s))
2669 _public_ int sd_bus_message_read_basic(sd_bus_message *m, char type, void *p) {
2670 struct bus_container *c;
2674 assert_return(m, -EINVAL);
2675 assert_return(m->sealed, -EPERM);
2676 assert_return(bus_type_is_basic(type), -EINVAL);
2678 if (message_end_of_signature(m))
2681 if (message_end_of_array(m, m->rindex))
2684 c = message_get_container(m);
2685 if (c->signature[c->index] != type)
2690 case SD_BUS_TYPE_STRING:
2691 case SD_BUS_TYPE_OBJECT_PATH: {
2696 r = message_peek_body(m, &rindex, 4, 4, &q);
2700 l = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2701 r = message_peek_body(m, &rindex, 1, l+1, &q);
2707 if (type == SD_BUS_TYPE_OBJECT_PATH) {
2708 if (!validate_object_path(q, l))
2711 if (!validate_string(q, l))
2717 *(const char**) p = q;
2722 case SD_BUS_TYPE_SIGNATURE: {
2727 r = message_peek_body(m, &rindex, 1, 1, &q);
2732 r = message_peek_body(m, &rindex, 1, l+1, &q);
2738 if (!validate_signature(q, l))
2744 *(const char**) p = q;
2752 align = bus_type_get_alignment(type);
2753 sz = bus_type_get_size(type);
2754 assert(align > 0 && sz > 0);
2757 r = message_peek_body(m, &rindex, align, sz, &q);
2763 case SD_BUS_TYPE_BYTE:
2765 *(uint8_t*) p = *(uint8_t*) q;
2768 case SD_BUS_TYPE_BOOLEAN:
2770 *(int*) p = !!*(uint32_t*) q;
2773 case SD_BUS_TYPE_INT16:
2774 case SD_BUS_TYPE_UINT16:
2776 *(uint16_t*) p = BUS_MESSAGE_BSWAP16(m, *(uint16_t*) q);
2779 case SD_BUS_TYPE_INT32:
2780 case SD_BUS_TYPE_UINT32:
2782 *(uint32_t*) p = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2785 case SD_BUS_TYPE_INT64:
2786 case SD_BUS_TYPE_UINT64:
2787 case SD_BUS_TYPE_DOUBLE:
2789 *(uint64_t*) p = BUS_MESSAGE_BSWAP64(m, *(uint64_t*) q);
2792 case SD_BUS_TYPE_UNIX_FD: {
2795 j = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2800 *(int*) p = m->fds[j];
2805 assert_not_reached("Unknown basic type...");
2814 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2820 static int bus_message_enter_array(
2822 struct bus_container *c,
2823 const char *contents,
2824 uint32_t **array_size) {
2835 if (!signature_is_single(contents, true))
2838 alignment = bus_type_get_alignment(contents[0]);
2842 if (!c->signature || c->signature[c->index] == 0)
2845 if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
2848 if (!startswith(c->signature + c->index + 1, contents))
2852 r = message_peek_body(m, &rindex, 4, 4, &q);
2856 if (BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q) > BUS_ARRAY_MAX_SIZE)
2859 r = message_peek_body(m, &rindex, alignment, 0, NULL);
2865 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2866 c->index += 1 + strlen(contents);
2870 *array_size = (uint32_t*) q;
2875 static int bus_message_enter_variant(
2877 struct bus_container *c,
2878 const char *contents) {
2889 if (!signature_is_single(contents, false))
2892 if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
2895 if (!c->signature || c->signature[c->index] == 0)
2898 if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
2902 r = message_peek_body(m, &rindex, 1, 1, &q);
2907 r = message_peek_body(m, &rindex, 1, l+1, &q);
2913 if (!validate_signature(q, l))
2916 if (!streq(q, contents))
2919 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2927 static int bus_message_enter_struct(
2929 struct bus_container *c,
2930 const char *contents) {
2939 if (!signature_is_valid(contents, false))
2942 if (!c->signature || c->signature[c->index] == 0)
2945 l = strlen(contents);
2947 if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
2948 !startswith(c->signature + c->index + 1, contents) ||
2949 c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
2952 r = message_peek_body(m, &m->rindex, 8, 0, NULL);
2956 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2957 c->index += 1 + l + 1;
2962 static int bus_message_enter_dict_entry(
2964 struct bus_container *c,
2965 const char *contents) {
2974 if (!signature_is_pair(contents))
2977 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2980 if (!c->signature || c->signature[c->index] == 0)
2983 l = strlen(contents);
2985 if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
2986 !startswith(c->signature + c->index + 1, contents) ||
2987 c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
2990 r = message_peek_body(m, &m->rindex, 8, 0, NULL);
2994 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2995 c->index += 1 + l + 1;
3000 _public_ int sd_bus_message_enter_container(sd_bus_message *m,
3002 const char *contents) {
3003 struct bus_container *c, *w;
3004 uint32_t *array_size = NULL;
3009 assert_return(m, -EINVAL);
3010 assert_return(m->sealed, -EPERM);
3011 assert_return(type != 0 || !contents, -EINVAL);
3013 if (type == 0 || !contents) {
3017 /* Allow entering into anonymous containers */
3018 r = sd_bus_message_peek_type(m, &tt, &cc);
3022 if (type != 0 && type != tt)
3025 if (contents && !streq(contents, cc))
3033 * We enforce a global limit on container depth, that is much
3034 * higher than the 32 structs and 32 arrays the specification
3035 * mandates. This is simpler to implement for us, and we need
3036 * this only to ensure our container array doesn't grow
3037 * without bounds. We are happy to return any data from a
3038 * message as long as the data itself is valid, even if the
3039 * overall message might be not.
3041 * Note that the message signature is validated when
3042 * parsing the headers, and that validation does check the
3045 * Note that the specification defines no limits on the depth
3046 * of stacked variants, but we do.
3048 if (m->n_containers >= BUS_CONTAINER_DEPTH)
3051 w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
3056 if (message_end_of_signature(m))
3059 if (message_end_of_array(m, m->rindex))
3062 c = message_get_container(m);
3064 signature = strdup(contents);
3068 c->saved_index = c->index;
3071 if (type == SD_BUS_TYPE_ARRAY)
3072 r = bus_message_enter_array(m, c, contents, &array_size);
3073 else if (type == SD_BUS_TYPE_VARIANT)
3074 r = bus_message_enter_variant(m, c, contents);
3075 else if (type == SD_BUS_TYPE_STRUCT)
3076 r = bus_message_enter_struct(m, c, contents);
3077 else if (type == SD_BUS_TYPE_DICT_ENTRY)
3078 r = bus_message_enter_dict_entry(m, c, contents);
3087 /* OK, let's fill it in */
3088 w += m->n_containers++;
3089 w->enclosing = type;
3090 w->signature = signature;
3092 w->array_size = array_size;
3094 w->begin = m->rindex;
3099 _public_ int sd_bus_message_exit_container(sd_bus_message *m) {
3100 struct bus_container *c;
3102 assert_return(m, -EINVAL);
3103 assert_return(m->sealed, -EPERM);
3104 assert_return(m->n_containers > 0, -ENXIO);
3106 c = message_get_container(m);
3107 if (c->enclosing == SD_BUS_TYPE_ARRAY) {
3110 l = BUS_MESSAGE_BSWAP32(m, *c->array_size);
3111 if (c->begin + l != m->rindex)
3115 if (c->signature && c->signature[c->index] != 0)
3125 static void message_quit_container(sd_bus_message *m) {
3126 struct bus_container *c;
3130 assert(m->n_containers > 0);
3132 c = message_get_container(m);
3135 assert(m->rindex >= c->before);
3136 m->rindex = c->before;
3138 /* Free container */
3142 /* Correct index of new top-level container */
3143 c = message_get_container(m);
3144 c->index = c->saved_index;
3147 _public_ int sd_bus_message_peek_type(sd_bus_message *m, char *type, const char **contents) {
3148 struct bus_container *c;
3151 assert_return(m, -EINVAL);
3152 assert_return(m->sealed, -EPERM);
3154 if (message_end_of_signature(m))
3157 if (message_end_of_array(m, m->rindex))
3160 c = message_get_container(m);
3162 if (bus_type_is_basic(c->signature[c->index])) {
3166 *type = c->signature[c->index];
3170 if (c->signature[c->index] == SD_BUS_TYPE_ARRAY) {
3176 r = signature_element_length(c->signature+c->index+1, &l);
3182 sig = strndup(c->signature + c->index + 1, l);
3186 free(m->peeked_signature);
3187 m->peeked_signature = sig;
3193 *type = SD_BUS_TYPE_ARRAY;
3198 if (c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ||
3199 c->signature[c->index] == SD_BUS_TYPE_DICT_ENTRY_BEGIN) {
3205 r = signature_element_length(c->signature+c->index, &l);
3210 sig = strndup(c->signature + c->index + 1, l - 2);
3214 free(m->peeked_signature);
3215 m->peeked_signature = sig;
3221 *type = c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY;
3226 if (c->signature[c->index] == SD_BUS_TYPE_VARIANT) {
3232 r = message_peek_body(m, &rindex, 1, 1, &q);
3239 r = message_peek_body(m, &rindex, 1, l+1, &q);
3245 if (!validate_signature(q, l))
3252 *type = SD_BUS_TYPE_VARIANT;
3267 _public_ int sd_bus_message_rewind(sd_bus_message *m, int complete) {
3268 struct bus_container *c;
3270 assert_return(m, -EINVAL);
3271 assert_return(m->sealed, -EPERM);
3274 message_reset_containers(m);
3276 m->root_container.index = 0;
3278 c = message_get_container(m);
3280 c = message_get_container(m);
3283 m->rindex = c->begin;
3286 return !isempty(c->signature);
3289 static int message_read_ap(
3294 unsigned n_array, n_struct;
3295 TypeStack stack[BUS_CONTAINER_DEPTH];
3296 unsigned stack_ptr = 0;
3297 unsigned n_loop = 0;
3305 /* Ideally, we'd just call ourselves recursively on every
3306 * complex type. However, the state of a va_list that is
3307 * passed to a function is undefined after that function
3308 * returns. This means we need to docode the va_list linearly
3309 * in a single stackframe. We hence implement our own
3310 * home-grown stack in an array. */
3312 n_array = (unsigned) -1; /* lenght of current array entries */
3313 n_struct = strlen(types); /* length of current struct contents signature */
3320 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
3321 r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
3327 r = sd_bus_message_exit_container(m);
3335 if (n_array != (unsigned) -1)
3344 case SD_BUS_TYPE_BYTE:
3345 case SD_BUS_TYPE_BOOLEAN:
3346 case SD_BUS_TYPE_INT16:
3347 case SD_BUS_TYPE_UINT16:
3348 case SD_BUS_TYPE_INT32:
3349 case SD_BUS_TYPE_UINT32:
3350 case SD_BUS_TYPE_INT64:
3351 case SD_BUS_TYPE_UINT64:
3352 case SD_BUS_TYPE_DOUBLE:
3353 case SD_BUS_TYPE_STRING:
3354 case SD_BUS_TYPE_OBJECT_PATH:
3355 case SD_BUS_TYPE_SIGNATURE:
3356 case SD_BUS_TYPE_UNIX_FD: {
3359 p = va_arg(ap, void*);
3360 r = sd_bus_message_read_basic(m, *t, p);
3373 case SD_BUS_TYPE_ARRAY: {
3376 r = signature_element_length(t + 1, &k);
3382 memcpy(s, t + 1, k);
3385 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, s);
3396 if (n_array == (unsigned) -1) {
3401 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
3407 n_array = va_arg(ap, unsigned);
3412 case SD_BUS_TYPE_VARIANT: {
3415 s = va_arg(ap, const char *);
3419 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, s);
3429 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
3434 n_struct = strlen(s);
3435 n_array = (unsigned) -1;
3440 case SD_BUS_TYPE_STRUCT_BEGIN:
3441 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
3444 r = signature_element_length(t, &k);
3450 memcpy(s, t + 1, k - 2);
3453 r = sd_bus_message_enter_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
3463 if (n_array == (unsigned) -1) {
3468 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
3474 n_array = (unsigned) -1;
3487 _public_ int sd_bus_message_read(sd_bus_message *m, const char *types, ...) {
3491 assert_return(m, -EINVAL);
3492 assert_return(m->sealed, -EPERM);
3493 assert_return(types, -EINVAL);
3495 va_start(ap, types);
3496 r = message_read_ap(m, types, ap);
3502 _public_ int sd_bus_message_skip(sd_bus_message *m, const char *types) {
3505 assert_return(m, -EINVAL);
3506 assert_return(m->sealed, -EPERM);
3507 assert_return(types, -EINVAL);
3514 case SD_BUS_TYPE_BYTE:
3515 case SD_BUS_TYPE_BOOLEAN:
3516 case SD_BUS_TYPE_INT16:
3517 case SD_BUS_TYPE_UINT16:
3518 case SD_BUS_TYPE_INT32:
3519 case SD_BUS_TYPE_UINT32:
3520 case SD_BUS_TYPE_INT64:
3521 case SD_BUS_TYPE_UINT64:
3522 case SD_BUS_TYPE_DOUBLE:
3523 case SD_BUS_TYPE_STRING:
3524 case SD_BUS_TYPE_OBJECT_PATH:
3525 case SD_BUS_TYPE_SIGNATURE:
3526 case SD_BUS_TYPE_UNIX_FD:
3528 r = sd_bus_message_read_basic(m, *types, NULL);
3532 r = sd_bus_message_skip(m, types + 1);
3538 case SD_BUS_TYPE_ARRAY: {
3541 r = signature_element_length(types + 1, &k);
3547 memcpy(s, types+1, k);
3550 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, s);
3555 r = sd_bus_message_skip(m, s);
3562 r = sd_bus_message_exit_container(m);
3567 r = sd_bus_message_skip(m, types + 1 + k);
3574 case SD_BUS_TYPE_VARIANT: {
3575 const char *contents;
3578 r = sd_bus_message_peek_type(m, &x, &contents);
3582 if (x != SD_BUS_TYPE_VARIANT)
3585 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, contents);
3589 r = sd_bus_message_skip(m, contents);
3594 r = sd_bus_message_exit_container(m);
3598 r = sd_bus_message_skip(m, types + 1);
3605 case SD_BUS_TYPE_STRUCT_BEGIN:
3606 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
3609 r = signature_element_length(types, &k);
3615 memcpy(s, types+1, k-2);
3618 r = sd_bus_message_enter_container(m, *types == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
3622 r = sd_bus_message_skip(m, s);
3627 r = sd_bus_message_exit_container(m);
3632 r = sd_bus_message_skip(m, types + k);
3644 _public_ int sd_bus_message_read_array(sd_bus_message *m,
3648 struct bus_container *c;
3654 assert_return(m, -EINVAL);
3655 assert_return(m->sealed, -EPERM);
3656 assert_return(bus_type_is_trivial(type), -EINVAL);
3657 assert_return(ptr, -EINVAL);
3658 assert_return(size, -EINVAL);
3659 assert_return(!BUS_MESSAGE_NEED_BSWAP(m), -ENOTSUP);
3661 align = bus_type_get_alignment(type);
3665 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
3669 c = message_get_container(m);
3670 sz = BUS_MESSAGE_BSWAP32(m, *c->array_size);
3673 /* Zero length array, let's return some aligned
3674 * pointer that is not NULL */
3675 p = (uint8_t*) NULL + align;
3677 r = message_peek_body(m, &m->rindex, align, sz, &p);
3686 r = sd_bus_message_exit_container(m);
3690 *ptr = (const void*) p;
3696 message_quit_container(m);
3700 static int message_peek_fields(
3711 return buffer_peek(BUS_MESSAGE_FIELDS(m), BUS_MESSAGE_FIELDS_SIZE(m), rindex, align, nbytes, ret);
3714 static int message_peek_field_uint32(
3725 r = message_peek_fields(m, ri, 4, 4, &q);
3730 *ret = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
3735 static int message_peek_field_string(
3737 bool (*validate)(const char *p),
3748 r = message_peek_field_uint32(m, ri, &l);
3752 r = message_peek_fields(m, ri, 1, l+1, &q);
3757 if (!validate_nul(q, l))
3763 if (!validate_string(q, l))
3773 static int message_peek_field_signature(
3785 r = message_peek_fields(m, ri, 1, 1, &q);
3790 r = message_peek_fields(m, ri, 1, l+1, &q);
3794 if (!validate_signature(q, l))
3803 static int message_skip_fields(
3806 uint32_t array_size,
3807 const char **signature) {
3809 size_t original_index;
3816 original_index = *ri;
3822 if (array_size != (uint32_t) -1 &&
3823 array_size <= *ri - original_index)
3830 if (t == SD_BUS_TYPE_STRING) {
3832 r = message_peek_field_string(m, NULL, ri, NULL);
3838 } else if (t == SD_BUS_TYPE_OBJECT_PATH) {
3840 r = message_peek_field_string(m, object_path_is_valid, ri, NULL);
3846 } else if (t == SD_BUS_TYPE_SIGNATURE) {
3848 r = message_peek_field_signature(m, ri, NULL);
3854 } else if (bus_type_is_basic(t)) {
3857 align = bus_type_get_alignment(t);
3858 k = bus_type_get_size(t);
3859 assert(align > 0 && k > 0);
3861 r = message_peek_fields(m, ri, align, k, NULL);
3867 } else if (t == SD_BUS_TYPE_ARRAY) {
3869 r = signature_element_length(*signature+1, &l);
3879 strncpy(sig, *signature + 1, l-1);
3882 alignment = bus_type_get_alignment(sig[0]);
3886 r = message_peek_field_uint32(m, ri, &nas);
3889 if (nas > BUS_ARRAY_MAX_SIZE)
3892 r = message_peek_fields(m, ri, alignment, 0, NULL);
3896 r = message_skip_fields(m, ri, nas, (const char**) &s);
3901 (*signature) += 1 + l;
3903 } else if (t == SD_BUS_TYPE_VARIANT) {
3906 r = message_peek_field_signature(m, ri, &s);
3910 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
3916 } else if (t == SD_BUS_TYPE_STRUCT ||
3917 t == SD_BUS_TYPE_DICT_ENTRY) {
3919 r = signature_element_length(*signature, &l);
3926 strncpy(sig, *signature + 1, l-1);
3929 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
3940 int bus_message_parse_fields(sd_bus_message *m) {
3943 uint32_t unix_fds = 0;
3947 for (ri = 0; ri < BUS_MESSAGE_FIELDS_SIZE(m); ) {
3948 const char *signature;
3951 r = message_peek_fields(m, &ri, 8, 1, (void**) &header);
3955 r = message_peek_field_signature(m, &ri, &signature);
3960 case _SD_BUS_MESSAGE_HEADER_INVALID:
3963 case SD_BUS_MESSAGE_HEADER_PATH:
3968 if (!streq(signature, "o"))
3971 r = message_peek_field_string(m, object_path_is_valid, &ri, &m->path);
3974 case SD_BUS_MESSAGE_HEADER_INTERFACE:
3979 if (!streq(signature, "s"))
3982 r = message_peek_field_string(m, interface_name_is_valid, &ri, &m->interface);
3985 case SD_BUS_MESSAGE_HEADER_MEMBER:
3990 if (!streq(signature, "s"))
3993 r = message_peek_field_string(m, member_name_is_valid, &ri, &m->member);
3996 case SD_BUS_MESSAGE_HEADER_ERROR_NAME:
4001 if (!streq(signature, "s"))
4004 r = message_peek_field_string(m, error_name_is_valid, &ri, &m->error.name);
4007 case SD_BUS_MESSAGE_HEADER_DESTINATION:
4012 if (!streq(signature, "s"))
4015 r = message_peek_field_string(m, service_name_is_valid, &ri, &m->destination);
4018 case SD_BUS_MESSAGE_HEADER_SENDER:
4023 if (!streq(signature, "s"))
4026 r = message_peek_field_string(m, service_name_is_valid, &ri, &m->sender);
4030 case SD_BUS_MESSAGE_HEADER_SIGNATURE: {
4034 if (m->root_container.signature)
4037 if (!streq(signature, "g"))
4040 r = message_peek_field_signature(m, &ri, &s);
4048 free(m->root_container.signature);
4049 m->root_container.signature = c;
4053 case SD_BUS_MESSAGE_HEADER_REPLY_SERIAL:
4054 if (m->reply_serial != 0)
4057 if (!streq(signature, "u"))
4060 r = message_peek_field_uint32(m, &ri, &m->reply_serial);
4064 if (m->reply_serial == 0)
4069 case SD_BUS_MESSAGE_HEADER_UNIX_FDS:
4073 if (!streq(signature, "u"))
4076 r = message_peek_field_uint32(m, &ri, &unix_fds);
4086 r = message_skip_fields(m, &ri, (uint32_t) -1, (const char **) &signature);
4093 if (m->n_fds != unix_fds)
4096 if (isempty(m->root_container.signature) != (BUS_MESSAGE_BODY_SIZE(m) == 0))
4099 switch (m->header->type) {
4101 case SD_BUS_MESSAGE_SIGNAL:
4102 if (!m->path || !m->interface || !m->member)
4106 case SD_BUS_MESSAGE_METHOD_CALL:
4108 if (!m->path || !m->member)
4113 case SD_BUS_MESSAGE_METHOD_RETURN:
4115 if (m->reply_serial == 0)
4119 case SD_BUS_MESSAGE_METHOD_ERROR:
4121 if (m->reply_serial == 0 || !m->error.name)
4126 /* Try to read the error message, but if we can't it's a non-issue */
4127 if (m->header->type == SD_BUS_MESSAGE_METHOD_ERROR)
4128 sd_bus_message_read(m, "s", &m->error.message);
4133 int bus_message_seal(sd_bus_message *m, uint64_t serial) {
4134 struct bus_body_part *part;
4144 if (m->n_containers > 0)
4150 /* If there's a non-trivial signature set, then add it in here */
4151 if (!isempty(m->root_container.signature)) {
4152 r = message_append_field_signature(m, SD_BUS_MESSAGE_HEADER_SIGNATURE, m->root_container.signature, NULL);
4158 r = message_append_field_uint32(m, SD_BUS_MESSAGE_HEADER_UNIX_FDS, m->n_fds);
4163 /* Add padding at the end of the fields part, since we know
4164 * the body needs to start at an 8 byte alignment. We made
4165 * sure we allocated enough space for this, so all we need to
4166 * do here is to zero it out. */
4167 l = BUS_MESSAGE_FIELDS_SIZE(m);
4170 memset((uint8_t*) BUS_MESSAGE_FIELDS(m) + l, 0, a);
4172 /* If this is something we can send as memfd, then let's seal
4173 the memfd now. Note that we can send memfds as payload only
4174 for directed messages, and not for broadcasts. */
4175 if (m->destination && m->bus && m->bus->use_memfd) {
4176 MESSAGE_FOREACH_PART(part, i, m)
4177 if (part->memfd >= 0 && !part->sealed && (part->size > MEMFD_MIN_SIZE || m->bus->use_memfd < 0)) {
4178 bus_body_part_unmap(part);
4180 if (ioctl(part->memfd, KDBUS_CMD_MEMFD_SEAL_SET, 1) >= 0)
4181 part->sealed = true;
4185 m->header->serial = serial;
4191 _public_ int sd_bus_message_set_destination(sd_bus_message *m, const char *destination) {
4192 assert_return(m, -EINVAL);
4193 assert_return(destination, -EINVAL);
4194 assert_return(!m->sealed, -EPERM);
4195 assert_return(!m->destination, -EEXIST);
4197 return message_append_field_string(m, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &m->destination);
4200 int bus_message_get_blob(sd_bus_message *m, void **buffer, size_t *sz) {
4204 struct bus_body_part *part;
4210 total = BUS_MESSAGE_SIZE(m);
4216 e = mempcpy(p, m->header, BUS_MESSAGE_BODY_BEGIN(m));
4217 MESSAGE_FOREACH_PART(part, i, m)
4218 e = mempcpy(e, part->data, part->size);
4220 assert(total == (size_t) ((uint8_t*) e - (uint8_t*) p));
4228 int bus_message_read_strv_extend(sd_bus_message *m, char ***l) {
4234 r = sd_bus_message_enter_container(m, 'a', "s");
4241 r = sd_bus_message_read_basic(m, 's', &s);
4247 r = strv_extend(l, s);
4252 r = sd_bus_message_exit_container(m);
4259 _public_ int sd_bus_message_read_strv(sd_bus_message *m, char ***l) {
4263 assert_return(m, -EINVAL);
4264 assert_return(m->sealed, -EPERM);
4265 assert_return(l, -EINVAL);
4267 r = bus_message_read_strv_extend(m, &strv);
4277 const char* bus_message_get_arg(sd_bus_message *m, unsigned i) {
4279 const char *t = NULL;
4284 r = sd_bus_message_rewind(m, true);
4288 for (j = 0; j <= i; j++) {
4291 r = sd_bus_message_peek_type(m, &type, NULL);
4295 if (type != SD_BUS_TYPE_STRING &&
4296 type != SD_BUS_TYPE_OBJECT_PATH &&
4297 type != SD_BUS_TYPE_SIGNATURE)
4300 r = sd_bus_message_read_basic(m, type, &t);
4308 bool bus_header_is_complete(struct bus_header *h, size_t size) {
4314 if (size < sizeof(struct bus_header))
4317 full = sizeof(struct bus_header) +
4318 (h->endian == SD_BUS_NATIVE_ENDIAN ? h->fields_size : bswap_32(h->fields_size));
4320 return size >= full;
4323 int bus_header_message_size(struct bus_header *h, size_t *sum) {
4329 if (h->endian == SD_BUS_NATIVE_ENDIAN) {
4330 fs = h->fields_size;
4332 } else if (h->endian == SD_BUS_REVERSE_ENDIAN) {
4333 fs = bswap_32(h->fields_size);
4334 bs = bswap_32(h->body_size);
4338 *sum = sizeof(struct bus_header) + ALIGN8(fs) + bs;
4342 _public_ int sd_bus_message_get_errno(sd_bus_message *m) {
4343 assert_return(m, -EINVAL);
4345 if (m->header->type != SD_BUS_MESSAGE_METHOD_ERROR)
4348 return sd_bus_error_get_errno(&m->error);
4351 _public_ const char* sd_bus_message_get_signature(sd_bus_message *m, int complete) {
4352 struct bus_container *c;
4354 assert_return(m, NULL);
4356 c = complete ? &m->root_container : message_get_container(m);
4357 return c->signature ?: "";
4360 _public_ int sd_bus_message_copy(sd_bus_message *m, sd_bus_message *source, int all) {
4361 bool done_something = false;
4364 assert_return(m, -EINVAL);
4365 assert_return(source, -EINVAL);
4366 assert_return(!m->sealed, -EPERM);
4367 assert_return(source->sealed, -EPERM);
4370 const char *contents;
4385 r = sd_bus_message_peek_type(source, &type, &contents);
4391 done_something = true;
4393 if (bus_type_is_container(type) > 0) {
4395 r = sd_bus_message_enter_container(source, type, contents);
4399 r = sd_bus_message_open_container(m, type, contents);
4403 r = sd_bus_message_copy(m, source, true);
4407 r = sd_bus_message_close_container(m);
4411 r = sd_bus_message_exit_container(source);
4418 r = sd_bus_message_read_basic(source, type, &basic);
4424 if (type == SD_BUS_TYPE_OBJECT_PATH ||
4425 type == SD_BUS_TYPE_SIGNATURE ||
4426 type == SD_BUS_TYPE_STRING)
4427 r = sd_bus_message_append_basic(m, type, basic.string);
4429 r = sd_bus_message_append_basic(m, type, &basic);
4436 return done_something;
4439 _public_ int sd_bus_message_verify_type(sd_bus_message *m, char type, const char *contents) {
4444 assert_return(m, -EINVAL);
4445 assert_return(m->sealed, -EPERM);
4446 assert_return(!type || bus_type_is_valid(type), -EINVAL);
4447 assert_return(!contents || signature_is_valid(contents, true), -EINVAL);
4448 assert_return(type || contents, -EINVAL);
4449 assert_return(!contents || !type || bus_type_is_container(type), -EINVAL);
4451 r = sd_bus_message_peek_type(m, &t, &c);
4455 if (type != 0 && type != t)
4458 if (contents && !streq_ptr(contents, c))
4464 _public_ sd_bus *sd_bus_message_get_bus(sd_bus_message *m) {
4465 assert_return(m, NULL);