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(
312 const struct ucred *ucred,
315 sd_bus_message **ret) {
318 struct bus_header *h;
321 assert(buffer || length <= 0);
322 assert(fds || n_fds <= 0);
325 if (length < sizeof(struct bus_header))
335 if (h->type == _SD_BUS_MESSAGE_TYPE_INVALID)
338 if (h->endian != SD_BUS_LITTLE_ENDIAN &&
339 h->endian != SD_BUS_BIG_ENDIAN)
342 a = ALIGN(sizeof(sd_bus_message)) + ALIGN(extra);
345 label_sz = strlen(label);
363 m->uid_valid = m->gid_valid = true;
367 m->label = (char*) m + ALIGN(sizeof(sd_bus_message)) + ALIGN(extra);
368 memcpy(m->label, label, label_sz + 1);
375 int bus_message_from_malloc(
380 const struct ucred *ucred,
382 sd_bus_message **ret) {
387 r = bus_message_from_header(buffer, length, fds, n_fds, ucred, label, 0, &m);
391 if (length != BUS_MESSAGE_SIZE(m)) {
397 m->body.data = (uint8_t*) buffer + sizeof(struct bus_header) + ALIGN8(BUS_MESSAGE_FIELDS_SIZE(m));
398 m->body.size = length - sizeof(struct bus_header) - ALIGN8(BUS_MESSAGE_FIELDS_SIZE(m));
399 m->body.sealed = true;
403 m->iovec = m->iovec_fixed;
404 m->iovec[0].iov_base = buffer;
405 m->iovec[0].iov_len = length;
407 r = bus_message_parse_fields(m);
411 /* We take possession of the memory and fds now */
412 m->free_header = true;
423 static sd_bus_message *message_new(sd_bus *bus, uint8_t type) {
426 m = malloc0(ALIGN(sizeof(sd_bus_message)) + sizeof(struct bus_header));
431 m->header = (struct bus_header*) ((uint8_t*) m + ALIGN(sizeof(struct sd_bus_message)));
432 m->header->endian = SD_BUS_NATIVE_ENDIAN;
433 m->header->type = type;
434 m->header->version = bus ? bus->message_version : 1;
435 m->allow_fds = !bus || bus->can_fds || (bus->state != BUS_HELLO && bus->state != BUS_RUNNING);
438 m->bus = sd_bus_ref(bus);
443 _public_ int sd_bus_message_new_signal(
446 const char *interface,
448 sd_bus_message **m) {
453 assert_return(!bus || bus->state != BUS_UNSET, -ENOTCONN);
454 assert_return(object_path_is_valid(path), -EINVAL);
455 assert_return(interface_name_is_valid(interface), -EINVAL);
456 assert_return(member_name_is_valid(member), -EINVAL);
457 assert_return(m, -EINVAL);
459 t = message_new(bus, SD_BUS_MESSAGE_SIGNAL);
463 t->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
465 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_PATH, SD_BUS_TYPE_OBJECT_PATH, path, &t->path);
468 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_INTERFACE, SD_BUS_TYPE_STRING, interface, &t->interface);
471 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_MEMBER, SD_BUS_TYPE_STRING, member, &t->member);
479 sd_bus_message_unref(t);
483 _public_ int sd_bus_message_new_method_call(
485 const char *destination,
487 const char *interface,
489 sd_bus_message **m) {
494 assert_return(!bus || bus->state != BUS_UNSET, -ENOTCONN);
495 assert_return(!destination || service_name_is_valid(destination), -EINVAL);
496 assert_return(object_path_is_valid(path), -EINVAL);
497 assert_return(!interface || interface_name_is_valid(interface), -EINVAL);
498 assert_return(member_name_is_valid(member), -EINVAL);
499 assert_return(m, -EINVAL);
501 t = message_new(bus, SD_BUS_MESSAGE_METHOD_CALL);
505 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_PATH, SD_BUS_TYPE_OBJECT_PATH, path, &t->path);
508 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_MEMBER, SD_BUS_TYPE_STRING, member, &t->member);
513 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_INTERFACE, SD_BUS_TYPE_STRING, interface, &t->interface);
519 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &t->destination);
532 static int message_new_reply(
534 sd_bus_message *call,
536 sd_bus_message **m) {
541 assert_return(!bus || bus->state != BUS_UNSET, -ENOTCONN);
542 assert_return(call, -EINVAL);
543 assert_return(call->sealed, -EPERM);
544 assert_return(call->header->type == SD_BUS_MESSAGE_METHOD_CALL, -EINVAL);
545 assert_return(m, -EINVAL);
547 t = message_new(bus, type);
551 t->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
552 t->reply_serial = BUS_MESSAGE_SERIAL(call);
554 r = message_append_field_uint32(t, SD_BUS_MESSAGE_HEADER_REPLY_SERIAL, t->reply_serial);
559 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, call->sender, &t->destination);
564 t->dont_send = !!(call->header->flags & SD_BUS_MESSAGE_NO_REPLY_EXPECTED);
574 _public_ int sd_bus_message_new_method_return(
576 sd_bus_message *call,
577 sd_bus_message **m) {
579 return message_new_reply(bus, call, SD_BUS_MESSAGE_METHOD_RETURN, m);
582 _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(bus, 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(
618 sd_bus_message *call,
624 _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 r = bus_error_setfv(&error, name, format, ap);
638 return sd_bus_message_new_method_error(bus, call, &error, m);
641 _public_ int sd_bus_message_new_method_errno(
643 sd_bus_message *call,
645 const sd_bus_error *p,
646 sd_bus_message **m) {
648 _cleanup_free_ sd_bus_error berror = SD_BUS_ERROR_NULL;
650 if (sd_bus_error_is_set(p))
651 return sd_bus_message_new_method_error(bus, call, p, m);
653 sd_bus_error_set_errno(&berror, error);
655 return sd_bus_message_new_method_error(bus, call, &berror, m);
658 _public_ int sd_bus_message_new_method_errnof(
660 sd_bus_message *call,
666 _cleanup_free_ sd_bus_error berror = SD_BUS_ERROR_NULL;
670 va_start(ap, format);
671 r = bus_error_set_errnofv(&berror, error, format, ap);
677 return sd_bus_message_new_method_error(bus, call, &berror, m);
680 int bus_message_new_synthetic_error(
683 const sd_bus_error *e,
684 sd_bus_message **m) {
689 assert(sd_bus_error_is_set(e));
692 t = message_new(bus, SD_BUS_MESSAGE_METHOD_ERROR);
696 t->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
697 t->reply_serial = serial;
699 r = message_append_field_uint32(t, SD_BUS_MESSAGE_HEADER_REPLY_SERIAL, t->reply_serial);
703 if (bus && bus->unique_name) {
704 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, bus->unique_name, &t->destination);
709 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_ERROR_NAME, SD_BUS_TYPE_STRING, e->name, &t->error.name);
714 r = message_append_basic(t, SD_BUS_TYPE_STRING, e->message, (const void**) &t->error.message);
727 _public_ sd_bus_message* sd_bus_message_ref(sd_bus_message *m) {
728 assert_return(m, NULL);
730 assert(m->n_ref > 0);
736 _public_ sd_bus_message* sd_bus_message_unref(sd_bus_message *m) {
737 assert_return(m, NULL);
739 assert(m->n_ref > 0);
748 _public_ int sd_bus_message_get_type(sd_bus_message *m, uint8_t *type) {
749 assert_return(m, -EINVAL);
750 assert_return(type, -EINVAL);
752 *type = m->header->type;
756 _public_ int sd_bus_message_get_serial(sd_bus_message *m, uint64_t *serial) {
757 assert_return(m, -EINVAL);
758 assert_return(serial, -EINVAL);
759 assert_return(m->header->serial != 0, -ENOENT);
761 *serial = BUS_MESSAGE_SERIAL(m);
765 _public_ int sd_bus_message_get_reply_serial(sd_bus_message *m, uint64_t *serial) {
766 assert_return(m, -EINVAL);
767 assert_return(serial, -EINVAL);
768 assert_return(m->reply_serial != 0, -ENOENT);
770 *serial = m->reply_serial;
774 _public_ int sd_bus_message_get_no_reply(sd_bus_message *m) {
775 assert_return(m, -EINVAL);
777 return m->header->type == SD_BUS_MESSAGE_METHOD_CALL ? !!(m->header->flags & SD_BUS_MESSAGE_NO_REPLY_EXPECTED) : 0;
780 _public_ int sd_bus_message_get_no_auto_start(sd_bus_message *m) {
781 assert_return(m, -EINVAL);
783 return !!(m->header->flags & SD_BUS_MESSAGE_NO_AUTO_START);
786 _public_ const char *sd_bus_message_get_path(sd_bus_message *m) {
787 assert_return(m, NULL);
792 _public_ const char *sd_bus_message_get_interface(sd_bus_message *m) {
793 assert_return(m, NULL);
798 _public_ const char *sd_bus_message_get_member(sd_bus_message *m) {
799 assert_return(m, NULL);
804 _public_ const char *sd_bus_message_get_destination(sd_bus_message *m) {
805 assert_return(m, NULL);
807 return m->destination;
810 _public_ const char *sd_bus_message_get_sender(sd_bus_message *m) {
811 assert_return(m, NULL);
816 _public_ const sd_bus_error *sd_bus_message_get_error(sd_bus_message *m) {
817 assert_return(m, NULL);
818 assert_return(sd_bus_error_is_set(&m->error), NULL);
823 _public_ int sd_bus_message_get_uid(sd_bus_message *m, uid_t *uid) {
824 assert_return(m, -EINVAL);
825 assert_return(uid, -EINVAL);
826 assert_return(m->uid_valid, -ESRCH);
832 _public_ int sd_bus_message_get_gid(sd_bus_message *m, gid_t *gid) {
833 assert_return(m, -EINVAL);
834 assert_return(gid, -EINVAL);
835 assert_return(m->gid_valid, -ESRCH);
841 _public_ int sd_bus_message_get_pid(sd_bus_message *m, pid_t *pid) {
842 assert_return(m, -EINVAL);
843 assert_return(pid, -EINVAL);
844 assert_return(m->pid > 0, -ESRCH);
850 _public_ int sd_bus_message_get_tid(sd_bus_message *m, pid_t *tid) {
851 assert_return(m, -EINVAL);
852 assert_return(tid, -EINVAL);
853 assert_return(m->tid > 0, -ESRCH);
859 _public_ int sd_bus_message_get_pid_starttime(sd_bus_message *m, uint64_t *usec) {
860 assert_return(m, -EINVAL);
861 assert_return(usec, -EINVAL);
862 assert_return(m->pid_starttime > 0, -ESRCH);
864 *usec = m->pid_starttime;
868 _public_ int sd_bus_message_get_selinux_context(sd_bus_message *m, const char **ret) {
869 assert_return(m, -EINVAL);
870 assert_return(m->label, -ESRCH);
876 _public_ int sd_bus_message_get_monotonic_timestamp(sd_bus_message *m, uint64_t *usec) {
877 assert_return(m, -EINVAL);
878 assert_return(usec, -EINVAL);
879 assert_return(m->monotonic > 0, -ESRCH);
881 *usec = m->monotonic;
885 _public_ int sd_bus_message_get_realtime_timestamp(sd_bus_message *m, uint64_t *usec) {
886 assert_return(m, -EINVAL);
887 assert_return(usec, -EINVAL);
888 assert_return(m->realtime > 0, -ESRCH);
894 _public_ int sd_bus_message_get_comm(sd_bus_message *m, const char **ret) {
895 assert_return(m, -EINVAL);
896 assert_return(ret, -EINVAL);
897 assert_return(m->comm, -ESRCH);
903 _public_ int sd_bus_message_get_tid_comm(sd_bus_message *m, const char **ret) {
904 assert_return(m, -EINVAL);
905 assert_return(ret, -EINVAL);
906 assert_return(m->tid_comm, -ESRCH);
912 _public_ int sd_bus_message_get_exe(sd_bus_message *m, const char **ret) {
913 assert_return(m, -EINVAL);
914 assert_return(ret, -EINVAL);
915 assert_return(m->exe, -ESRCH);
921 _public_ int sd_bus_message_get_cgroup(sd_bus_message *m, const char **ret) {
922 assert_return(m, -EINVAL);
923 assert_return(ret, -EINVAL);
924 assert_return(m->cgroup, -ESRCH);
930 _public_ int sd_bus_message_get_unit(sd_bus_message *m, const char **ret) {
933 assert_return(m, -EINVAL);
934 assert_return(ret, -EINVAL);
935 assert_return(m->cgroup, -ESRCH);
938 r = cg_path_get_unit(m->cgroup, &m->unit);
947 _public_ int sd_bus_message_get_user_unit(sd_bus_message *m, const char **ret) {
950 assert_return(m, -EINVAL);
951 assert_return(ret, -EINVAL);
952 assert_return(m->cgroup, -ESRCH);
955 r = cg_path_get_user_unit(m->cgroup, &m->user_unit);
964 _public_ int sd_bus_message_get_session(sd_bus_message *m, const char **ret) {
967 assert_return(m, -EINVAL);
968 assert_return(ret, -EINVAL);
969 assert_return(m->cgroup, -ESRCH);
972 r = cg_path_get_session(m->cgroup, &m->session);
981 _public_ int sd_bus_message_get_owner_uid(sd_bus_message *m, uid_t *uid) {
982 assert_return(m, -EINVAL);
983 assert_return(uid, -EINVAL);
984 assert_return(m->cgroup, -ESRCH);
986 return cg_path_get_owner_uid(m->cgroup, uid);
989 _public_ int sd_bus_message_get_cmdline(sd_bus_message *m, char ***cmdline) {
994 assert_return(m, -EINVAL);
995 assert_return(m->cmdline, -ESRCH);
997 for (p = m->cmdline, n = 0; p < m->cmdline + m->cmdline_length; p++)
1001 m->cmdline_array = new(char*, n + 1);
1002 if (!m->cmdline_array)
1005 for (p = m->cmdline, i = 0, first = true; p < m->cmdline + m->cmdline_length; p++) {
1007 m->cmdline_array[i++] = (char*) p;
1012 m->cmdline_array[i] = NULL;
1013 *cmdline = m->cmdline_array;
1018 _public_ int sd_bus_message_get_audit_sessionid(sd_bus_message *m, uint32_t *sessionid) {
1019 assert_return(m, -EINVAL);
1020 assert_return(sessionid, -EINVAL);
1021 assert_return(m->audit, -ESRCH);
1023 *sessionid = m->audit->sessionid;
1027 _public_ int sd_bus_message_get_audit_loginuid(sd_bus_message *m, uid_t *uid) {
1028 assert_return(m, -EINVAL);
1029 assert_return(uid, -EINVAL);
1030 assert_return(m->audit, -ESRCH);
1032 *uid = m->audit->loginuid;
1036 _public_ int sd_bus_message_has_effective_cap(sd_bus_message *m, int capability) {
1039 assert_return(m, -EINVAL);
1040 assert_return(capability < 0, -EINVAL);
1041 assert_return(!m->capability, -ESRCH);
1043 sz = m->capability_size / 4;
1044 if ((unsigned) capability >= sz*8)
1047 return !!(m->capability[2 * sz + (capability / 8)] & (1 << (capability % 8)));
1050 _public_ int sd_bus_message_is_signal(sd_bus_message *m,
1051 const char *interface,
1052 const char *member) {
1053 assert_return(m, -EINVAL);
1055 if (m->header->type != SD_BUS_MESSAGE_SIGNAL)
1058 if (interface && (!m->interface || !streq(m->interface, interface)))
1061 if (member && (!m->member || !streq(m->member, member)))
1067 _public_ int sd_bus_message_is_method_call(sd_bus_message *m,
1068 const char *interface,
1069 const char *member) {
1070 assert_return(m, -EINVAL);
1072 if (m->header->type != SD_BUS_MESSAGE_METHOD_CALL)
1075 if (interface && (!m->interface || !streq(m->interface, interface)))
1078 if (member && (!m->member || !streq(m->member, member)))
1084 _public_ int sd_bus_message_is_method_error(sd_bus_message *m, const char *name) {
1085 assert_return(m, -EINVAL);
1087 if (m->header->type != SD_BUS_MESSAGE_METHOD_ERROR)
1090 if (name && (!m->error.name || !streq(m->error.name, name)))
1096 _public_ int sd_bus_message_set_no_reply(sd_bus_message *m, int b) {
1097 assert_return(m, -EINVAL);
1098 assert_return(!m->sealed, -EPERM);
1099 assert_return(m->header->type == SD_BUS_MESSAGE_METHOD_CALL, -EPERM);
1102 m->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
1104 m->header->flags &= ~SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
1109 _public_ int sd_bus_message_set_no_auto_start(sd_bus_message *m, int b) {
1110 assert_return(m, -EINVAL);
1111 assert_return(!m->sealed, -EPERM);
1114 m->header->flags |= SD_BUS_MESSAGE_NO_AUTO_START;
1116 m->header->flags &= ~SD_BUS_MESSAGE_NO_AUTO_START;
1121 static struct bus_container *message_get_container(sd_bus_message *m) {
1124 if (m->n_containers == 0)
1125 return &m->root_container;
1127 assert(m->containers);
1128 return m->containers + m->n_containers - 1;
1131 struct bus_body_part *message_append_part(sd_bus_message *m) {
1132 struct bus_body_part *part;
1139 if (m->n_body_parts <= 0) {
1143 assert(m->body_end);
1145 part = new0(struct bus_body_part, 1);
1151 m->body_end->next = part;
1161 static void part_zero(struct bus_body_part *part, size_t sz) {
1166 /* All other fields can be left in their defaults */
1167 assert(!part->data);
1168 assert(part->memfd < 0);
1171 part->is_zero = true;
1172 part->sealed = true;
1175 static int part_make_space(
1176 struct sd_bus_message *m,
1177 struct bus_body_part *part,
1186 assert(!part->sealed);
1191 if (!part->data && part->memfd < 0)
1192 part->memfd = bus_kernel_pop_memfd(m->bus, &part->data, &part->mapped);
1194 if (part->memfd >= 0) {
1197 r = ioctl(part->memfd, KDBUS_CMD_MEMFD_SIZE_SET, &u);
1203 if (!part->data || sz > part->mapped) {
1204 size_t psz = PAGE_ALIGN(sz > 0 ? sz : 1);
1206 if (part->mapped <= 0)
1207 n = mmap(NULL, psz, PROT_READ|PROT_WRITE, MAP_SHARED, part->memfd, 0);
1209 n = mremap(part->data, part->mapped, psz, MREMAP_MAYMOVE);
1211 if (n == MAP_FAILED) {
1220 part->munmap_this = true;
1222 n = realloc(part->data, MAX(sz, 1u));
1229 part->free_this = true;
1233 *q = part->data ? (uint8_t*) part->data + part->size : NULL;
1239 static void message_extend_containers(sd_bus_message *m, size_t expand) {
1240 struct bus_container *c;
1247 /* Update counters */
1248 for (c = m->containers; c < m->containers + m->n_containers; c++)
1250 *c->array_size += expand;
1253 static void *message_extend_body(sd_bus_message *m, size_t align, size_t sz) {
1254 struct bus_body_part *part = NULL;
1255 size_t start_body, end_body, padding, start_part, end_part, added;
1267 start_body = ALIGN_TO((size_t) m->header->body_size, align);
1268 end_body = start_body + sz;
1270 padding = start_body - m->header->body_size;
1271 added = padding + sz;
1273 /* Check for 32bit overflows */
1274 if (end_body > (size_t) ((uint32_t) -1)) {
1280 m->n_body_parts <= 0 ||
1281 m->body_end->sealed ||
1282 padding != ALIGN_TO(m->body_end->size, align) - m->body_end->size;
1286 part = message_append_part(m);
1290 part_zero(part, padding);
1293 part = message_append_part(m);
1297 r = part_make_space(m, part, sz, &p);
1301 struct bus_container *c;
1309 start_part = ALIGN_TO(part->size, align);
1310 end_part = start_part + sz;
1312 r = part_make_space(m, part, end_part, &p);
1317 memset(p, 0, padding);
1318 p = (uint8_t*) p + padding;
1321 /* Readjust pointers */
1322 for (c = m->containers; c < m->containers + m->n_containers; c++)
1323 c->array_size = adjust_pointer(c->array_size, op, os, part->data);
1325 m->error.message = (const char*) adjust_pointer(m->error.message, op, os, part->data);
1328 m->header->body_size = end_body;
1329 message_extend_containers(m, added);
1334 int message_append_basic(sd_bus_message *m, char type, const void *p, const void **stored) {
1335 struct bus_container *c;
1343 assert_return(m, -EINVAL);
1344 assert_return(!m->sealed, -EPERM);
1345 assert_return(bus_type_is_basic(type), -EINVAL);
1346 assert_return(!m->poisoned, -ESTALE);
1348 c = message_get_container(m);
1350 if (c->signature && c->signature[c->index]) {
1351 /* Container signature is already set */
1353 if (c->signature[c->index] != type)
1358 /* Maybe we can append to the signature? But only if this is the top-level container*/
1359 if (c->enclosing != 0)
1362 e = strextend(&c->signature, CHAR_TO_STR(type), NULL);
1371 case SD_BUS_TYPE_STRING:
1372 /* To make things easy we'll serialize a NULL string
1373 * into the empty string */
1376 /* Fall through... */
1377 case SD_BUS_TYPE_OBJECT_PATH:
1385 sz = 4 + strlen(p) + 1;
1388 case SD_BUS_TYPE_SIGNATURE:
1396 sz = 1 + strlen(p) + 1;
1399 case SD_BUS_TYPE_BOOLEAN:
1408 assert_cc(sizeof(int) == sizeof(uint32_t));
1414 case SD_BUS_TYPE_UNIX_FD: {
1422 if (!m->allow_fds) {
1435 fd = fcntl(z, F_DUPFD_CLOEXEC, 3);
1441 f = realloc(m->fds, sizeof(int) * (m->n_fds + 1));
1461 align = bus_type_get_alignment(type);
1462 sz = bus_type_get_size(type);
1469 a = message_extend_body(m, align, sz);
1475 if (type == SD_BUS_TYPE_STRING || type == SD_BUS_TYPE_OBJECT_PATH) {
1476 *(uint32_t*) a = sz - 5;
1477 memcpy((uint8_t*) a + 4, p, sz - 4);
1480 *stored = (const uint8_t*) a + 4;
1482 } else if (type == SD_BUS_TYPE_SIGNATURE) {
1483 *(uint8_t*) a = sz - 1;
1484 memcpy((uint8_t*) a + 1, p, sz - 1);
1487 *stored = (const uint8_t*) a + 1;
1488 } else if (type == SD_BUS_TYPE_UNIX_FD) {
1489 *(uint32_t*) a = fdi;
1503 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1510 close_nointr_nofail(fd);
1515 _public_ int sd_bus_message_append_basic(sd_bus_message *m, char type, const void *p) {
1516 return message_append_basic(m, type, p, NULL);
1519 _public_ int sd_bus_message_append_string_space(
1524 struct bus_container *c;
1527 assert_return(m, -EINVAL);
1528 assert_return(s, -EINVAL);
1529 assert_return(!m->sealed, -EPERM);
1530 assert_return(!m->poisoned, -ESTALE);
1532 c = message_get_container(m);
1534 if (c->signature && c->signature[c->index]) {
1535 /* Container signature is already set */
1537 if (c->signature[c->index] != SD_BUS_TYPE_STRING)
1542 /* Maybe we can append to the signature? But only if this is the top-level container*/
1543 if (c->enclosing != 0)
1546 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRING), NULL);
1553 a = message_extend_body(m, 4, 4 + size + 1);
1557 *(uint32_t*) a = size;
1562 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1568 _public_ int sd_bus_message_append_string_iovec(
1570 const struct iovec *iov,
1578 assert_return(m, -EINVAL);
1579 assert_return(!m->sealed, -EPERM);
1580 assert_return(iov || n == 0, -EINVAL);
1581 assert_return(!m->poisoned, -ESTALE);
1583 size = IOVEC_TOTAL_SIZE(iov, n);
1585 r = sd_bus_message_append_string_space(m, size, &p);
1589 for (i = 0; i < n; i++) {
1591 if (iov[i].iov_base)
1592 memcpy(p, iov[i].iov_base, iov[i].iov_len);
1594 memset(p, ' ', iov[i].iov_len);
1596 p += iov[i].iov_len;
1602 static int bus_message_open_array(
1604 struct bus_container *c,
1605 const char *contents,
1606 uint32_t **array_size) {
1612 struct bus_body_part *o;
1619 if (!signature_is_single(contents, true))
1622 alignment = bus_type_get_alignment(contents[0]);
1626 if (c->signature && c->signature[c->index]) {
1628 /* Verify the existing signature */
1630 if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
1633 if (!startswith(c->signature + c->index + 1, contents))
1636 nindex = c->index + 1 + strlen(contents);
1640 if (c->enclosing != 0)
1643 /* Extend the existing signature */
1645 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_ARRAY), contents, NULL);
1651 nindex = e - c->signature;
1654 a = message_extend_body(m, 4, 4);
1659 op = m->body_end->data;
1660 os = m->body_end->size;
1662 /* Add alignment between size and first element */
1663 if (!message_extend_body(m, alignment, 0))
1666 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1669 /* location of array size might have changed so let's readjust a */
1670 if (o == m->body_end)
1671 a = adjust_pointer(a, op, os, m->body_end->data);
1678 static int bus_message_open_variant(
1680 struct bus_container *c,
1681 const char *contents) {
1690 if (!signature_is_single(contents, false))
1693 if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
1696 if (c->signature && c->signature[c->index]) {
1698 if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
1704 if (c->enclosing != 0)
1707 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_VARIANT), NULL);
1714 l = strlen(contents);
1715 a = message_extend_body(m, 1, 1 + l + 1);
1720 memcpy((uint8_t*) a + 1, contents, l + 1);
1722 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1728 static int bus_message_open_struct(
1730 struct bus_container *c,
1731 const char *contents) {
1739 if (!signature_is_valid(contents, false))
1742 if (c->signature && c->signature[c->index]) {
1745 l = strlen(contents);
1747 if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
1748 !startswith(c->signature + c->index + 1, contents) ||
1749 c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
1752 nindex = c->index + 1 + l + 1;
1756 if (c->enclosing != 0)
1759 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_BEGIN), contents, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_END), NULL);
1765 nindex = e - c->signature;
1768 /* Align contents to 8 byte boundary */
1769 if (!message_extend_body(m, 8, 0))
1772 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1778 static int bus_message_open_dict_entry(
1780 struct bus_container *c,
1781 const char *contents) {
1789 if (!signature_is_pair(contents))
1792 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1795 if (c->signature && c->signature[c->index]) {
1798 l = strlen(contents);
1800 if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
1801 !startswith(c->signature + c->index + 1, contents) ||
1802 c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
1805 nindex = c->index + 1 + l + 1;
1809 /* Align contents to 8 byte boundary */
1810 if (!message_extend_body(m, 8, 0))
1813 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1819 _public_ int sd_bus_message_open_container(
1822 const char *contents) {
1824 struct bus_container *c, *w;
1825 uint32_t *array_size = NULL;
1830 assert_return(m, -EINVAL);
1831 assert_return(!m->sealed, -EPERM);
1832 assert_return(contents, -EINVAL);
1833 assert_return(!m->poisoned, -ESTALE);
1835 /* Make sure we have space for one more container */
1836 w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
1844 c = message_get_container(m);
1846 signature = strdup(contents);
1852 /* Save old index in the parent container, in case we have to
1853 * abort this container */
1854 c->saved_index = c->index;
1855 before = m->header->body_size;
1857 if (type == SD_BUS_TYPE_ARRAY)
1858 r = bus_message_open_array(m, c, contents, &array_size);
1859 else if (type == SD_BUS_TYPE_VARIANT)
1860 r = bus_message_open_variant(m, c, contents);
1861 else if (type == SD_BUS_TYPE_STRUCT)
1862 r = bus_message_open_struct(m, c, contents);
1863 else if (type == SD_BUS_TYPE_DICT_ENTRY)
1864 r = bus_message_open_dict_entry(m, c, contents);
1873 /* OK, let's fill it in */
1874 w += m->n_containers++;
1875 w->enclosing = type;
1876 w->signature = signature;
1878 w->array_size = array_size;
1880 w->begin = m->rindex;
1885 _public_ int sd_bus_message_close_container(sd_bus_message *m) {
1886 struct bus_container *c;
1888 assert_return(m, -EINVAL);
1889 assert_return(!m->sealed, -EPERM);
1890 assert_return(m->n_containers > 0, -EINVAL);
1891 assert_return(!m->poisoned, -ESTALE);
1893 c = message_get_container(m);
1894 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1895 if (c->signature && c->signature[c->index] != 0)
1910 static int type_stack_push(TypeStack *stack, unsigned max, unsigned *i, const char *types, unsigned n_struct, unsigned n_array) {
1917 stack[*i].types = types;
1918 stack[*i].n_struct = n_struct;
1919 stack[*i].n_array = n_array;
1925 static int type_stack_pop(TypeStack *stack, unsigned max, unsigned *i, const char **types, unsigned *n_struct, unsigned *n_array) {
1936 *types = stack[*i].types;
1937 *n_struct = stack[*i].n_struct;
1938 *n_array = stack[*i].n_array;
1943 int bus_message_append_ap(
1948 unsigned n_array, n_struct;
1949 TypeStack stack[BUS_CONTAINER_DEPTH];
1950 unsigned stack_ptr = 0;
1958 n_array = (unsigned) -1;
1959 n_struct = strlen(types);
1964 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
1965 r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
1971 r = sd_bus_message_close_container(m);
1979 if (n_array != (unsigned) -1)
1988 case SD_BUS_TYPE_BYTE: {
1991 x = (uint8_t) va_arg(ap, int);
1992 r = sd_bus_message_append_basic(m, *t, &x);
1996 case SD_BUS_TYPE_BOOLEAN:
1997 case SD_BUS_TYPE_INT32:
1998 case SD_BUS_TYPE_UINT32:
1999 case SD_BUS_TYPE_UNIX_FD: {
2002 /* We assume a boolean is the same as int32_t */
2003 assert_cc(sizeof(int32_t) == sizeof(int));
2005 x = va_arg(ap, uint32_t);
2006 r = sd_bus_message_append_basic(m, *t, &x);
2010 case SD_BUS_TYPE_INT16:
2011 case SD_BUS_TYPE_UINT16: {
2014 x = (uint16_t) va_arg(ap, int);
2015 r = sd_bus_message_append_basic(m, *t, &x);
2019 case SD_BUS_TYPE_INT64:
2020 case SD_BUS_TYPE_UINT64:
2021 case SD_BUS_TYPE_DOUBLE: {
2024 x = va_arg(ap, uint64_t);
2025 r = sd_bus_message_append_basic(m, *t, &x);
2029 case SD_BUS_TYPE_STRING:
2030 case SD_BUS_TYPE_OBJECT_PATH:
2031 case SD_BUS_TYPE_SIGNATURE: {
2034 x = va_arg(ap, const char*);
2035 r = sd_bus_message_append_basic(m, *t, x);
2039 case SD_BUS_TYPE_ARRAY: {
2042 r = signature_element_length(t + 1, &k);
2048 memcpy(s, t + 1, k);
2051 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, s);
2056 if (n_array == (unsigned) -1) {
2061 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2067 n_array = va_arg(ap, unsigned);
2072 case SD_BUS_TYPE_VARIANT: {
2075 s = va_arg(ap, const char*);
2079 r = sd_bus_message_open_container(m, SD_BUS_TYPE_VARIANT, s);
2083 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2088 n_struct = strlen(s);
2089 n_array = (unsigned) -1;
2094 case SD_BUS_TYPE_STRUCT_BEGIN:
2095 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
2098 r = signature_element_length(t, &k);
2105 memcpy(s, t + 1, k - 2);
2108 r = sd_bus_message_open_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
2113 if (n_array == (unsigned) -1) {
2118 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2124 n_array = (unsigned) -1;
2140 _public_ int sd_bus_message_append(sd_bus_message *m, const char *types, ...) {
2144 assert_return(m, -EINVAL);
2145 assert_return(types, -EINVAL);
2146 assert_return(!m->sealed, -EPERM);
2147 assert_return(!m->poisoned, -ESTALE);
2149 va_start(ap, types);
2150 r = bus_message_append_ap(m, types, ap);
2156 _public_ int sd_bus_message_append_array_space(sd_bus_message *m,
2164 assert_return(m, -EINVAL);
2165 assert_return(!m->sealed, -EPERM);
2166 assert_return(bus_type_is_trivial(type), -EINVAL);
2167 assert_return(ptr || size == 0, -EINVAL);
2168 assert_return(!m->poisoned, -ESTALE);
2170 align = bus_type_get_alignment(type);
2171 sz = bus_type_get_size(type);
2173 assert_se(align > 0);
2179 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
2183 a = message_extend_body(m, align, size);
2187 r = sd_bus_message_close_container(m);
2195 _public_ int sd_bus_message_append_array(sd_bus_message *m,
2202 assert_return(m, -EINVAL);
2203 assert_return(!m->sealed, -EPERM);
2204 assert_return(bus_type_is_trivial(type), -EINVAL);
2205 assert_return(ptr || size == 0, -EINVAL);
2206 assert_return(!m->poisoned, -ESTALE);
2208 r = sd_bus_message_append_array_space(m, type, size, &p);
2213 memcpy(p, ptr, size);
2218 _public_ int sd_bus_message_append_array_iovec(
2221 const struct iovec *iov,
2229 assert_return(m, -EINVAL);
2230 assert_return(!m->sealed, -EPERM);
2231 assert_return(bus_type_is_trivial(type), -EINVAL);
2232 assert_return(iov || n == 0, -EINVAL);
2233 assert_return(!m->poisoned, -ESTALE);
2235 size = IOVEC_TOTAL_SIZE(iov, n);
2237 r = sd_bus_message_append_array_space(m, type, size, &p);
2241 for (i = 0; i < n; i++) {
2243 if (iov[i].iov_base)
2244 memcpy(p, iov[i].iov_base, iov[i].iov_len);
2246 memset(p, 0, iov[i].iov_len);
2248 p = (uint8_t*) p + iov[i].iov_len;
2254 _public_ int sd_bus_message_append_array_memfd(sd_bus_message *m,
2257 _cleanup_close_ int copy_fd = -1;
2258 struct bus_body_part *part;
2270 if (!bus_type_is_trivial(type))
2275 r = sd_memfd_set_sealed(memfd, true);
2279 copy_fd = sd_memfd_dup_fd(memfd);
2283 r = sd_memfd_get_size(memfd, &size);
2287 align = bus_type_get_alignment(type);
2288 sz = bus_type_get_size(type);
2290 assert_se(align > 0);
2296 if (size > (uint64_t) (uint32_t) -1)
2299 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
2303 a = message_extend_body(m, align, 0);
2307 part = message_append_part(m);
2311 part->memfd = copy_fd;
2312 part->sealed = true;
2316 message_extend_containers(m, size);
2317 m->header->body_size += size;
2319 return sd_bus_message_close_container(m);
2322 _public_ int sd_bus_message_append_string_memfd(sd_bus_message *m, sd_memfd *memfd) {
2323 _cleanup_close_ int copy_fd = -1;
2324 struct bus_body_part *part;
2325 struct bus_container *c;
2330 assert_return(m, -EINVAL);
2331 assert_return(memfd, -EINVAL);
2332 assert_return(!m->sealed, -EPERM);
2333 assert_return(!m->poisoned, -ESTALE);
2335 r = sd_memfd_set_sealed(memfd, true);
2339 copy_fd = sd_memfd_dup_fd(memfd);
2343 r = sd_memfd_get_size(memfd, &size);
2347 /* We require this to be NUL terminated */
2351 if (size > (uint64_t) (uint32_t) -1)
2354 c = message_get_container(m);
2355 if (c->signature && c->signature[c->index]) {
2356 /* Container signature is already set */
2358 if (c->signature[c->index] != SD_BUS_TYPE_STRING)
2363 /* Maybe we can append to the signature? But only if this is the top-level container*/
2364 if (c->enclosing != 0)
2367 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRING), NULL);
2374 a = message_extend_body(m, 4, 4);
2378 *(uint32_t*) a = size - 1;
2380 part = message_append_part(m);
2384 part->memfd = copy_fd;
2385 part->sealed = true;
2389 message_extend_containers(m, size);
2390 m->header->body_size += size;
2392 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2398 _public_ int sd_bus_message_append_strv(sd_bus_message *m, char **l) {
2402 assert_return(m, -EINVAL);
2403 assert_return(!m->sealed, -EPERM);
2404 assert_return(!m->poisoned, -ESTALE);
2406 r = sd_bus_message_open_container(m, 'a', "s");
2410 STRV_FOREACH(i, l) {
2411 r = sd_bus_message_append_basic(m, 's', *i);
2416 return sd_bus_message_close_container(m);
2419 int bus_body_part_map(struct bus_body_part *part) {
2428 if (part->size <= 0)
2431 /* For smaller zero parts (as used for padding) we don't need to map anything... */
2432 if (part->memfd < 0 && part->is_zero && part->size < 8) {
2433 static const uint8_t zeroes[7] = { };
2434 part->data = (void*) zeroes;
2438 psz = PAGE_ALIGN(part->size);
2440 if (part->memfd >= 0)
2441 p = mmap(NULL, psz, PROT_READ, MAP_SHARED, part->memfd, 0);
2442 else if (part->is_zero)
2443 p = mmap(NULL, psz, PROT_READ, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
2447 if (p == MAP_FAILED)
2452 part->munmap_this = true;
2457 void bus_body_part_unmap(struct bus_body_part *part) {
2461 if (part->memfd < 0)
2467 if (!part->munmap_this)
2470 assert_se(munmap(part->data, part->mapped) == 0);
2474 part->munmap_this = false;
2479 static int buffer_peek(const void *p, uint32_t sz, size_t *rindex, size_t align, size_t nbytes, void **r) {
2480 size_t k, start, end;
2485 start = ALIGN_TO((size_t) *rindex, align);
2486 end = start + nbytes;
2491 /* Verify that padding is 0 */
2492 for (k = *rindex; k < start; k++)
2493 if (((const uint8_t*) p)[k] != 0)
2497 *r = (uint8_t*) p + start;
2504 static bool message_end_of_signature(sd_bus_message *m) {
2505 struct bus_container *c;
2509 c = message_get_container(m);
2510 return !c->signature || c->signature[c->index] == 0;
2513 static bool message_end_of_array(sd_bus_message *m, size_t index) {
2514 struct bus_container *c;
2518 c = message_get_container(m);
2522 return index >= c->begin + BUS_MESSAGE_BSWAP32(m, *c->array_size);
2525 _public_ int sd_bus_message_at_end(sd_bus_message *m, int complete) {
2526 assert_return(m, -EINVAL);
2527 assert_return(m->sealed, -EPERM);
2529 if (complete && m->n_containers > 0)
2532 if (message_end_of_signature(m))
2535 if (message_end_of_array(m, m->rindex))
2541 static struct bus_body_part* find_part(sd_bus_message *m, size_t index, size_t sz, void **p) {
2542 struct bus_body_part *part;
2548 if (m->cached_rindex_part && index >= m->cached_rindex_part_begin) {
2549 part = m->cached_rindex_part;
2550 begin = m->cached_rindex_part_begin;
2560 if (index + sz <= begin + part->size) {
2562 r = bus_body_part_map(part);
2567 *p = (uint8_t*) part->data + index - begin;
2569 m->cached_rindex_part = part;
2570 m->cached_rindex_part_begin = begin;
2575 begin += part->size;
2582 static int message_peek_body(
2589 size_t k, start, end, padding;
2590 struct bus_body_part *part;
2597 if (message_end_of_array(m, *rindex))
2600 start = ALIGN_TO((size_t) *rindex, align);
2601 padding = start - *rindex;
2602 end = start + nbytes;
2604 if (end > BUS_MESSAGE_BODY_SIZE(m))
2607 part = find_part(m, *rindex, padding, (void**) &q);
2612 /* Verify padding */
2613 for (k = 0; k < padding; k++)
2618 part = find_part(m, start, nbytes, (void**) &q);
2630 static bool validate_nul(const char *s, size_t l) {
2632 /* Check for NUL chars in the string */
2633 if (memchr(s, 0, l))
2636 /* Check for NUL termination */
2643 static bool validate_string(const char *s, size_t l) {
2645 if (!validate_nul(s, l))
2648 /* Check if valid UTF8 */
2649 if (!utf8_is_valid(s))
2655 static bool validate_signature(const char *s, size_t l) {
2657 if (!validate_nul(s, l))
2660 /* Check if valid signature */
2661 if (!signature_is_valid(s, true))
2667 static bool validate_object_path(const char *s, size_t l) {
2669 if (!validate_nul(s, l))
2672 if (!object_path_is_valid(s))
2678 _public_ int sd_bus_message_read_basic(sd_bus_message *m, char type, void *p) {
2679 struct bus_container *c;
2683 assert_return(m, -EINVAL);
2684 assert_return(m->sealed, -EPERM);
2685 assert_return(bus_type_is_basic(type), -EINVAL);
2687 if (message_end_of_signature(m))
2690 if (message_end_of_array(m, m->rindex))
2693 c = message_get_container(m);
2694 if (c->signature[c->index] != type)
2699 case SD_BUS_TYPE_STRING:
2700 case SD_BUS_TYPE_OBJECT_PATH: {
2705 r = message_peek_body(m, &rindex, 4, 4, &q);
2709 l = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2710 r = message_peek_body(m, &rindex, 1, l+1, &q);
2716 if (type == SD_BUS_TYPE_OBJECT_PATH) {
2717 if (!validate_object_path(q, l))
2720 if (!validate_string(q, l))
2726 *(const char**) p = q;
2731 case SD_BUS_TYPE_SIGNATURE: {
2736 r = message_peek_body(m, &rindex, 1, 1, &q);
2741 r = message_peek_body(m, &rindex, 1, l+1, &q);
2747 if (!validate_signature(q, l))
2753 *(const char**) p = q;
2761 align = bus_type_get_alignment(type);
2762 sz = bus_type_get_size(type);
2763 assert(align > 0 && sz > 0);
2766 r = message_peek_body(m, &rindex, align, sz, &q);
2772 case SD_BUS_TYPE_BYTE:
2774 *(uint8_t*) p = *(uint8_t*) q;
2777 case SD_BUS_TYPE_BOOLEAN:
2779 *(int*) p = !!*(uint32_t*) q;
2782 case SD_BUS_TYPE_INT16:
2783 case SD_BUS_TYPE_UINT16:
2785 *(uint16_t*) p = BUS_MESSAGE_BSWAP16(m, *(uint16_t*) q);
2788 case SD_BUS_TYPE_INT32:
2789 case SD_BUS_TYPE_UINT32:
2791 *(uint32_t*) p = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2794 case SD_BUS_TYPE_INT64:
2795 case SD_BUS_TYPE_UINT64:
2796 case SD_BUS_TYPE_DOUBLE:
2798 *(uint64_t*) p = BUS_MESSAGE_BSWAP64(m, *(uint64_t*) q);
2801 case SD_BUS_TYPE_UNIX_FD: {
2804 j = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2809 *(int*) p = m->fds[j];
2814 assert_not_reached("Unknown basic type...");
2823 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2829 static int bus_message_enter_array(
2831 struct bus_container *c,
2832 const char *contents,
2833 uint32_t **array_size) {
2844 if (!signature_is_single(contents, true))
2847 alignment = bus_type_get_alignment(contents[0]);
2851 if (!c->signature || c->signature[c->index] == 0)
2854 if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
2857 if (!startswith(c->signature + c->index + 1, contents))
2861 r = message_peek_body(m, &rindex, 4, 4, &q);
2865 if (BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q) > BUS_ARRAY_MAX_SIZE)
2868 r = message_peek_body(m, &rindex, alignment, 0, NULL);
2874 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2875 c->index += 1 + strlen(contents);
2879 *array_size = (uint32_t*) q;
2884 static int bus_message_enter_variant(
2886 struct bus_container *c,
2887 const char *contents) {
2898 if (!signature_is_single(contents, false))
2901 if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
2904 if (!c->signature || c->signature[c->index] == 0)
2907 if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
2911 r = message_peek_body(m, &rindex, 1, 1, &q);
2916 r = message_peek_body(m, &rindex, 1, l+1, &q);
2922 if (!validate_signature(q, l))
2925 if (!streq(q, contents))
2928 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2936 static int bus_message_enter_struct(
2938 struct bus_container *c,
2939 const char *contents) {
2948 if (!signature_is_valid(contents, false))
2951 if (!c->signature || c->signature[c->index] == 0)
2954 l = strlen(contents);
2956 if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
2957 !startswith(c->signature + c->index + 1, contents) ||
2958 c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
2961 r = message_peek_body(m, &m->rindex, 8, 0, NULL);
2965 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2966 c->index += 1 + l + 1;
2971 static int bus_message_enter_dict_entry(
2973 struct bus_container *c,
2974 const char *contents) {
2983 if (!signature_is_pair(contents))
2986 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2989 if (!c->signature || c->signature[c->index] == 0)
2992 l = strlen(contents);
2994 if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
2995 !startswith(c->signature + c->index + 1, contents) ||
2996 c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
2999 r = message_peek_body(m, &m->rindex, 8, 0, NULL);
3003 if (c->enclosing != SD_BUS_TYPE_ARRAY)
3004 c->index += 1 + l + 1;
3009 _public_ int sd_bus_message_enter_container(sd_bus_message *m,
3011 const char *contents) {
3012 struct bus_container *c, *w;
3013 uint32_t *array_size = NULL;
3018 assert_return(m, -EINVAL);
3019 assert_return(m->sealed, -EPERM);
3020 assert_return(type != 0 || !contents, -EINVAL);
3022 if (type == 0 || !contents) {
3026 /* Allow entering into anonymous containers */
3027 r = sd_bus_message_peek_type(m, &tt, &cc);
3031 if (type != 0 && type != tt)
3034 if (contents && !streq(contents, cc))
3042 * We enforce a global limit on container depth, that is much
3043 * higher than the 32 structs and 32 arrays the specification
3044 * mandates. This is simpler to implement for us, and we need
3045 * this only to ensure our container array doesn't grow
3046 * without bounds. We are happy to return any data from a
3047 * message as long as the data itself is valid, even if the
3048 * overall message might be not.
3050 * Note that the message signature is validated when
3051 * parsing the headers, and that validation does check the
3054 * Note that the specification defines no limits on the depth
3055 * of stacked variants, but we do.
3057 if (m->n_containers >= BUS_CONTAINER_DEPTH)
3060 w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
3065 if (message_end_of_signature(m))
3068 if (message_end_of_array(m, m->rindex))
3071 c = message_get_container(m);
3073 signature = strdup(contents);
3077 c->saved_index = c->index;
3080 if (type == SD_BUS_TYPE_ARRAY)
3081 r = bus_message_enter_array(m, c, contents, &array_size);
3082 else if (type == SD_BUS_TYPE_VARIANT)
3083 r = bus_message_enter_variant(m, c, contents);
3084 else if (type == SD_BUS_TYPE_STRUCT)
3085 r = bus_message_enter_struct(m, c, contents);
3086 else if (type == SD_BUS_TYPE_DICT_ENTRY)
3087 r = bus_message_enter_dict_entry(m, c, contents);
3096 /* OK, let's fill it in */
3097 w += m->n_containers++;
3098 w->enclosing = type;
3099 w->signature = signature;
3101 w->array_size = array_size;
3103 w->begin = m->rindex;
3108 _public_ int sd_bus_message_exit_container(sd_bus_message *m) {
3109 struct bus_container *c;
3111 assert_return(m, -EINVAL);
3112 assert_return(m->sealed, -EPERM);
3113 assert_return(m->n_containers > 0, -ENXIO);
3115 c = message_get_container(m);
3116 if (c->enclosing == SD_BUS_TYPE_ARRAY) {
3119 l = BUS_MESSAGE_BSWAP32(m, *c->array_size);
3120 if (c->begin + l != m->rindex)
3124 if (c->signature && c->signature[c->index] != 0)
3134 static void message_quit_container(sd_bus_message *m) {
3135 struct bus_container *c;
3139 assert(m->n_containers > 0);
3141 c = message_get_container(m);
3144 assert(m->rindex >= c->before);
3145 m->rindex = c->before;
3147 /* Free container */
3151 /* Correct index of new top-level container */
3152 c = message_get_container(m);
3153 c->index = c->saved_index;
3156 _public_ int sd_bus_message_peek_type(sd_bus_message *m, char *type, const char **contents) {
3157 struct bus_container *c;
3160 assert_return(m, -EINVAL);
3161 assert_return(m->sealed, -EPERM);
3163 if (message_end_of_signature(m))
3166 if (message_end_of_array(m, m->rindex))
3169 c = message_get_container(m);
3171 if (bus_type_is_basic(c->signature[c->index])) {
3175 *type = c->signature[c->index];
3179 if (c->signature[c->index] == SD_BUS_TYPE_ARRAY) {
3185 r = signature_element_length(c->signature+c->index+1, &l);
3191 sig = strndup(c->signature + c->index + 1, l);
3195 free(m->peeked_signature);
3196 m->peeked_signature = sig;
3202 *type = SD_BUS_TYPE_ARRAY;
3207 if (c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ||
3208 c->signature[c->index] == SD_BUS_TYPE_DICT_ENTRY_BEGIN) {
3214 r = signature_element_length(c->signature+c->index, &l);
3219 sig = strndup(c->signature + c->index + 1, l - 2);
3223 free(m->peeked_signature);
3224 m->peeked_signature = sig;
3230 *type = c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY;
3235 if (c->signature[c->index] == SD_BUS_TYPE_VARIANT) {
3241 r = message_peek_body(m, &rindex, 1, 1, &q);
3248 r = message_peek_body(m, &rindex, 1, l+1, &q);
3254 if (!validate_signature(q, l))
3261 *type = SD_BUS_TYPE_VARIANT;
3276 _public_ int sd_bus_message_rewind(sd_bus_message *m, int complete) {
3277 struct bus_container *c;
3279 assert_return(m, -EINVAL);
3280 assert_return(m->sealed, -EPERM);
3283 message_reset_containers(m);
3285 m->root_container.index = 0;
3287 c = message_get_container(m);
3289 c = message_get_container(m);
3292 m->rindex = c->begin;
3295 return !isempty(c->signature);
3298 static int message_read_ap(
3303 unsigned n_array, n_struct;
3304 TypeStack stack[BUS_CONTAINER_DEPTH];
3305 unsigned stack_ptr = 0;
3306 unsigned n_loop = 0;
3314 /* Ideally, we'd just call ourselves recursively on every
3315 * complex type. However, the state of a va_list that is
3316 * passed to a function is undefined after that function
3317 * returns. This means we need to docode the va_list linearly
3318 * in a single stackframe. We hence implement our own
3319 * home-grown stack in an array. */
3321 n_array = (unsigned) -1; /* lenght of current array entries */
3322 n_struct = strlen(types); /* length of current struct contents signature */
3329 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
3330 r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
3336 r = sd_bus_message_exit_container(m);
3344 if (n_array != (unsigned) -1)
3353 case SD_BUS_TYPE_BYTE:
3354 case SD_BUS_TYPE_BOOLEAN:
3355 case SD_BUS_TYPE_INT16:
3356 case SD_BUS_TYPE_UINT16:
3357 case SD_BUS_TYPE_INT32:
3358 case SD_BUS_TYPE_UINT32:
3359 case SD_BUS_TYPE_INT64:
3360 case SD_BUS_TYPE_UINT64:
3361 case SD_BUS_TYPE_DOUBLE:
3362 case SD_BUS_TYPE_STRING:
3363 case SD_BUS_TYPE_OBJECT_PATH:
3364 case SD_BUS_TYPE_SIGNATURE:
3365 case SD_BUS_TYPE_UNIX_FD: {
3368 p = va_arg(ap, void*);
3369 r = sd_bus_message_read_basic(m, *t, p);
3382 case SD_BUS_TYPE_ARRAY: {
3385 r = signature_element_length(t + 1, &k);
3391 memcpy(s, t + 1, k);
3394 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, s);
3405 if (n_array == (unsigned) -1) {
3410 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
3416 n_array = va_arg(ap, unsigned);
3421 case SD_BUS_TYPE_VARIANT: {
3424 s = va_arg(ap, const char *);
3428 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, s);
3438 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
3443 n_struct = strlen(s);
3444 n_array = (unsigned) -1;
3449 case SD_BUS_TYPE_STRUCT_BEGIN:
3450 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
3453 r = signature_element_length(t, &k);
3459 memcpy(s, t + 1, k - 2);
3462 r = sd_bus_message_enter_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
3472 if (n_array == (unsigned) -1) {
3477 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
3483 n_array = (unsigned) -1;
3496 _public_ int sd_bus_message_read(sd_bus_message *m, const char *types, ...) {
3500 assert_return(m, -EINVAL);
3501 assert_return(m->sealed, -EPERM);
3502 assert_return(types, -EINVAL);
3504 va_start(ap, types);
3505 r = message_read_ap(m, types, ap);
3511 _public_ int sd_bus_message_skip(sd_bus_message *m, const char *types) {
3514 assert_return(m, -EINVAL);
3515 assert_return(m->sealed, -EPERM);
3516 assert_return(types, -EINVAL);
3523 case SD_BUS_TYPE_BYTE:
3524 case SD_BUS_TYPE_BOOLEAN:
3525 case SD_BUS_TYPE_INT16:
3526 case SD_BUS_TYPE_UINT16:
3527 case SD_BUS_TYPE_INT32:
3528 case SD_BUS_TYPE_UINT32:
3529 case SD_BUS_TYPE_INT64:
3530 case SD_BUS_TYPE_UINT64:
3531 case SD_BUS_TYPE_DOUBLE:
3532 case SD_BUS_TYPE_STRING:
3533 case SD_BUS_TYPE_OBJECT_PATH:
3534 case SD_BUS_TYPE_SIGNATURE:
3535 case SD_BUS_TYPE_UNIX_FD:
3537 r = sd_bus_message_read_basic(m, *types, NULL);
3541 r = sd_bus_message_skip(m, types + 1);
3547 case SD_BUS_TYPE_ARRAY: {
3550 r = signature_element_length(types + 1, &k);
3556 memcpy(s, types+1, k);
3559 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, s);
3564 r = sd_bus_message_skip(m, s);
3571 r = sd_bus_message_exit_container(m);
3576 r = sd_bus_message_skip(m, types + 1 + k);
3583 case SD_BUS_TYPE_VARIANT: {
3584 const char *contents;
3587 r = sd_bus_message_peek_type(m, &x, &contents);
3591 if (x != SD_BUS_TYPE_VARIANT)
3594 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, contents);
3598 r = sd_bus_message_skip(m, contents);
3603 r = sd_bus_message_exit_container(m);
3607 r = sd_bus_message_skip(m, types + 1);
3614 case SD_BUS_TYPE_STRUCT_BEGIN:
3615 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
3618 r = signature_element_length(types, &k);
3624 memcpy(s, types+1, k-2);
3627 r = sd_bus_message_enter_container(m, *types == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
3631 r = sd_bus_message_skip(m, s);
3636 r = sd_bus_message_exit_container(m);
3641 r = sd_bus_message_skip(m, types + k);
3653 _public_ int sd_bus_message_read_array(sd_bus_message *m,
3657 struct bus_container *c;
3663 assert_return(m, -EINVAL);
3664 assert_return(m->sealed, -EPERM);
3665 assert_return(bus_type_is_trivial(type), -EINVAL);
3666 assert_return(ptr, -EINVAL);
3667 assert_return(size, -EINVAL);
3668 assert_return(!BUS_MESSAGE_NEED_BSWAP(m), -ENOTSUP);
3670 align = bus_type_get_alignment(type);
3674 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
3678 c = message_get_container(m);
3679 sz = BUS_MESSAGE_BSWAP32(m, *c->array_size);
3682 /* Zero length array, let's return some aligned
3683 * pointer that is not NULL */
3684 p = (uint8_t*) NULL + align;
3686 r = message_peek_body(m, &m->rindex, align, sz, &p);
3695 r = sd_bus_message_exit_container(m);
3699 *ptr = (const void*) p;
3705 message_quit_container(m);
3709 static int message_peek_fields(
3720 return buffer_peek(BUS_MESSAGE_FIELDS(m), BUS_MESSAGE_FIELDS_SIZE(m), rindex, align, nbytes, ret);
3723 static int message_peek_field_uint32(
3734 r = message_peek_fields(m, ri, 4, 4, &q);
3739 *ret = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
3744 static int message_peek_field_string(
3746 bool (*validate)(const char *p),
3757 r = message_peek_field_uint32(m, ri, &l);
3761 r = message_peek_fields(m, ri, 1, l+1, &q);
3766 if (!validate_nul(q, l))
3772 if (!validate_string(q, l))
3782 static int message_peek_field_signature(
3794 r = message_peek_fields(m, ri, 1, 1, &q);
3799 r = message_peek_fields(m, ri, 1, l+1, &q);
3803 if (!validate_signature(q, l))
3812 static int message_skip_fields(
3815 uint32_t array_size,
3816 const char **signature) {
3818 size_t original_index;
3825 original_index = *ri;
3831 if (array_size != (uint32_t) -1 &&
3832 array_size <= *ri - original_index)
3839 if (t == SD_BUS_TYPE_STRING) {
3841 r = message_peek_field_string(m, NULL, ri, NULL);
3847 } else if (t == SD_BUS_TYPE_OBJECT_PATH) {
3849 r = message_peek_field_string(m, object_path_is_valid, ri, NULL);
3855 } else if (t == SD_BUS_TYPE_SIGNATURE) {
3857 r = message_peek_field_signature(m, ri, NULL);
3863 } else if (bus_type_is_basic(t)) {
3866 align = bus_type_get_alignment(t);
3867 k = bus_type_get_size(t);
3868 assert(align > 0 && k > 0);
3870 r = message_peek_fields(m, ri, align, k, NULL);
3876 } else if (t == SD_BUS_TYPE_ARRAY) {
3878 r = signature_element_length(*signature+1, &l);
3888 strncpy(sig, *signature + 1, l-1);
3891 alignment = bus_type_get_alignment(sig[0]);
3895 r = message_peek_field_uint32(m, ri, &nas);
3898 if (nas > BUS_ARRAY_MAX_SIZE)
3901 r = message_peek_fields(m, ri, alignment, 0, NULL);
3905 r = message_skip_fields(m, ri, nas, (const char**) &s);
3910 (*signature) += 1 + l;
3912 } else if (t == SD_BUS_TYPE_VARIANT) {
3915 r = message_peek_field_signature(m, ri, &s);
3919 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
3925 } else if (t == SD_BUS_TYPE_STRUCT ||
3926 t == SD_BUS_TYPE_DICT_ENTRY) {
3928 r = signature_element_length(*signature, &l);
3935 strncpy(sig, *signature + 1, l-1);
3938 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
3949 int bus_message_parse_fields(sd_bus_message *m) {
3952 uint32_t unix_fds = 0;
3956 for (ri = 0; ri < BUS_MESSAGE_FIELDS_SIZE(m); ) {
3957 const char *signature;
3960 r = message_peek_fields(m, &ri, 8, 1, (void**) &header);
3964 r = message_peek_field_signature(m, &ri, &signature);
3969 case _SD_BUS_MESSAGE_HEADER_INVALID:
3972 case SD_BUS_MESSAGE_HEADER_PATH:
3977 if (!streq(signature, "o"))
3980 r = message_peek_field_string(m, object_path_is_valid, &ri, &m->path);
3983 case SD_BUS_MESSAGE_HEADER_INTERFACE:
3988 if (!streq(signature, "s"))
3991 r = message_peek_field_string(m, interface_name_is_valid, &ri, &m->interface);
3994 case SD_BUS_MESSAGE_HEADER_MEMBER:
3999 if (!streq(signature, "s"))
4002 r = message_peek_field_string(m, member_name_is_valid, &ri, &m->member);
4005 case SD_BUS_MESSAGE_HEADER_ERROR_NAME:
4010 if (!streq(signature, "s"))
4013 r = message_peek_field_string(m, error_name_is_valid, &ri, &m->error.name);
4016 case SD_BUS_MESSAGE_HEADER_DESTINATION:
4021 if (!streq(signature, "s"))
4024 r = message_peek_field_string(m, sender_name_is_valid, &ri, &m->destination);
4027 case SD_BUS_MESSAGE_HEADER_SENDER:
4032 if (!streq(signature, "s"))
4035 r = message_peek_field_string(m, sender_name_is_valid, &ri, &m->sender);
4039 case SD_BUS_MESSAGE_HEADER_SIGNATURE: {
4043 if (m->root_container.signature)
4046 if (!streq(signature, "g"))
4049 r = message_peek_field_signature(m, &ri, &s);
4057 free(m->root_container.signature);
4058 m->root_container.signature = c;
4062 case SD_BUS_MESSAGE_HEADER_REPLY_SERIAL:
4063 if (m->reply_serial != 0)
4066 if (!streq(signature, "u"))
4069 r = message_peek_field_uint32(m, &ri, &m->reply_serial);
4073 if (m->reply_serial == 0)
4078 case SD_BUS_MESSAGE_HEADER_UNIX_FDS:
4082 if (!streq(signature, "u"))
4085 r = message_peek_field_uint32(m, &ri, &unix_fds);
4095 r = message_skip_fields(m, &ri, (uint32_t) -1, (const char **) &signature);
4102 if (m->n_fds != unix_fds)
4105 if (isempty(m->root_container.signature) != (BUS_MESSAGE_BODY_SIZE(m) == 0))
4108 switch (m->header->type) {
4110 case SD_BUS_MESSAGE_SIGNAL:
4111 if (!m->path || !m->interface || !m->member)
4115 case SD_BUS_MESSAGE_METHOD_CALL:
4117 if (!m->path || !m->member)
4122 case SD_BUS_MESSAGE_METHOD_RETURN:
4124 if (m->reply_serial == 0)
4128 case SD_BUS_MESSAGE_METHOD_ERROR:
4130 if (m->reply_serial == 0 || !m->error.name)
4135 /* Try to read the error message, but if we can't it's a non-issue */
4136 if (m->header->type == SD_BUS_MESSAGE_METHOD_ERROR)
4137 sd_bus_message_read(m, "s", &m->error.message);
4142 int bus_message_seal(sd_bus_message *m, uint64_t serial) {
4143 struct bus_body_part *part;
4153 if (m->n_containers > 0)
4159 /* If there's a non-trivial signature set, then add it in here */
4160 if (!isempty(m->root_container.signature)) {
4161 r = message_append_field_signature(m, SD_BUS_MESSAGE_HEADER_SIGNATURE, m->root_container.signature, NULL);
4167 r = message_append_field_uint32(m, SD_BUS_MESSAGE_HEADER_UNIX_FDS, m->n_fds);
4172 /* Add padding at the end of the fields part, since we know
4173 * the body needs to start at an 8 byte alignment. We made
4174 * sure we allocated enough space for this, so all we need to
4175 * do here is to zero it out. */
4176 l = BUS_MESSAGE_FIELDS_SIZE(m);
4179 memset((uint8_t*) BUS_MESSAGE_FIELDS(m) + l, 0, a);
4181 /* If this is something we can send as memfd, then let's seal
4182 the memfd now. Note that we can send memfds as payload only
4183 for directed messages, and not for broadcasts. */
4184 if (m->destination && m->bus && m->bus->use_memfd) {
4185 MESSAGE_FOREACH_PART(part, i, m)
4186 if (part->memfd >= 0 && !part->sealed && (part->size > MEMFD_MIN_SIZE || m->bus->use_memfd < 0)) {
4187 bus_body_part_unmap(part);
4189 if (ioctl(part->memfd, KDBUS_CMD_MEMFD_SEAL_SET, 1) >= 0)
4190 part->sealed = true;
4194 m->header->serial = serial;
4200 _public_ int sd_bus_message_set_destination(sd_bus_message *m, const char *destination) {
4201 assert_return(m, -EINVAL);
4202 assert_return(destination, -EINVAL);
4203 assert_return(!m->sealed, -EPERM);
4204 assert_return(!m->destination, -EEXIST);
4206 return message_append_field_string(m, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &m->destination);
4209 int bus_message_get_blob(sd_bus_message *m, void **buffer, size_t *sz) {
4213 struct bus_body_part *part;
4219 total = BUS_MESSAGE_SIZE(m);
4225 e = mempcpy(p, m->header, BUS_MESSAGE_BODY_BEGIN(m));
4226 MESSAGE_FOREACH_PART(part, i, m)
4227 e = mempcpy(e, part->data, part->size);
4229 assert(total == (size_t) ((uint8_t*) e - (uint8_t*) p));
4237 int bus_message_read_strv_extend(sd_bus_message *m, char ***l) {
4243 r = sd_bus_message_enter_container(m, 'a', "s");
4250 r = sd_bus_message_read_basic(m, 's', &s);
4256 r = strv_extend(l, s);
4261 r = sd_bus_message_exit_container(m);
4268 _public_ int sd_bus_message_read_strv(sd_bus_message *m, char ***l) {
4272 assert_return(m, -EINVAL);
4273 assert_return(m->sealed, -EPERM);
4274 assert_return(l, -EINVAL);
4276 r = bus_message_read_strv_extend(m, &strv);
4286 const char* bus_message_get_arg(sd_bus_message *m, unsigned i) {
4288 const char *t = NULL;
4293 r = sd_bus_message_rewind(m, true);
4297 for (j = 0; j <= i; j++) {
4300 r = sd_bus_message_peek_type(m, &type, NULL);
4304 if (type != SD_BUS_TYPE_STRING &&
4305 type != SD_BUS_TYPE_OBJECT_PATH &&
4306 type != SD_BUS_TYPE_SIGNATURE)
4309 r = sd_bus_message_read_basic(m, type, &t);
4317 bool bus_header_is_complete(struct bus_header *h, size_t size) {
4323 if (size < sizeof(struct bus_header))
4326 full = sizeof(struct bus_header) +
4327 (h->endian == SD_BUS_NATIVE_ENDIAN ? h->fields_size : bswap_32(h->fields_size));
4329 return size >= full;
4332 int bus_header_message_size(struct bus_header *h, size_t *sum) {
4338 if (h->endian == SD_BUS_NATIVE_ENDIAN) {
4339 fs = h->fields_size;
4341 } else if (h->endian == SD_BUS_REVERSE_ENDIAN) {
4342 fs = bswap_32(h->fields_size);
4343 bs = bswap_32(h->body_size);
4347 *sum = sizeof(struct bus_header) + ALIGN8(fs) + bs;
4351 _public_ int sd_bus_message_get_errno(sd_bus_message *m) {
4352 assert_return(m, -EINVAL);
4354 if (m->header->type != SD_BUS_MESSAGE_METHOD_ERROR)
4357 return sd_bus_error_get_errno(&m->error);
4360 _public_ const char* sd_bus_message_get_signature(sd_bus_message *m, int complete) {
4361 struct bus_container *c;
4363 assert_return(m, NULL);
4365 c = complete ? &m->root_container : message_get_container(m);
4366 return c->signature ?: "";
4369 _public_ int sd_bus_message_copy(sd_bus_message *m, sd_bus_message *source, int all) {
4370 bool done_something = false;
4373 assert_return(m, -EINVAL);
4374 assert_return(source, -EINVAL);
4375 assert_return(!m->sealed, -EPERM);
4376 assert_return(source->sealed, -EPERM);
4379 const char *contents;
4394 r = sd_bus_message_peek_type(source, &type, &contents);
4400 done_something = true;
4402 if (bus_type_is_container(type) > 0) {
4404 r = sd_bus_message_enter_container(source, type, contents);
4408 r = sd_bus_message_open_container(m, type, contents);
4412 r = sd_bus_message_copy(m, source, true);
4416 r = sd_bus_message_close_container(m);
4420 r = sd_bus_message_exit_container(source);
4427 r = sd_bus_message_read_basic(source, type, &basic);
4433 if (type == SD_BUS_TYPE_OBJECT_PATH ||
4434 type == SD_BUS_TYPE_SIGNATURE ||
4435 type == SD_BUS_TYPE_STRING)
4436 r = sd_bus_message_append_basic(m, type, basic.string);
4438 r = sd_bus_message_append_basic(m, type, &basic);
4445 return done_something;
4448 _public_ int sd_bus_message_verify_type(sd_bus_message *m, char type, const char *contents) {
4453 assert_return(m, -EINVAL);
4454 assert_return(m->sealed, -EPERM);
4455 assert_return(!type || bus_type_is_valid(type), -EINVAL);
4456 assert_return(!contents || signature_is_valid(contents, true), -EINVAL);
4457 assert_return(type || contents, -EINVAL);
4458 assert_return(!contents || !type || bus_type_is_container(type), -EINVAL);
4460 r = sd_bus_message_peek_type(m, &t, &c);
4464 if (type != 0 && type != t)
4467 if (contents && !streq_ptr(contents, c))