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;
629 assert_return(name, -EINVAL);
630 assert_return(m, -EINVAL);
632 va_start(ap, format);
633 r = bus_error_setfv(&error, name, format, ap);
639 return sd_bus_message_new_method_error(call, &error, m);
642 _public_ int sd_bus_message_new_method_errno(
643 sd_bus_message *call,
645 const sd_bus_error *p,
646 sd_bus_message **m) {
648 _cleanup_free_ sd_bus_error berror = SD_BUS_ERROR_NULL;
650 if (sd_bus_error_is_set(p))
651 return sd_bus_message_new_method_error(call, p, m);
653 sd_bus_error_set_errno(&berror, error);
655 return sd_bus_message_new_method_error(call, &berror, m);
658 _public_ int sd_bus_message_new_method_errnof(
659 sd_bus_message *call,
665 _cleanup_free_ sd_bus_error berror = SD_BUS_ERROR_NULL;
669 va_start(ap, format);
670 r = bus_error_set_errnofv(&berror, error, format, ap);
676 return sd_bus_message_new_method_error(call, &berror, m);
679 int bus_message_new_synthetic_error(
682 const sd_bus_error *e,
683 sd_bus_message **m) {
688 assert(sd_bus_error_is_set(e));
691 t = message_new(bus, SD_BUS_MESSAGE_METHOD_ERROR);
695 t->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
696 t->reply_serial = serial;
698 r = message_append_field_uint32(t, SD_BUS_MESSAGE_HEADER_REPLY_SERIAL, t->reply_serial);
702 if (bus && bus->unique_name) {
703 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, bus->unique_name, &t->destination);
708 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_ERROR_NAME, SD_BUS_TYPE_STRING, e->name, &t->error.name);
713 r = message_append_basic(t, SD_BUS_TYPE_STRING, e->message, (const void**) &t->error.message);
726 _public_ sd_bus_message* sd_bus_message_ref(sd_bus_message *m) {
727 assert_return(m, NULL);
729 assert(m->n_ref > 0);
735 _public_ sd_bus_message* sd_bus_message_unref(sd_bus_message *m) {
736 assert_return(m, NULL);
738 assert(m->n_ref > 0);
747 _public_ int sd_bus_message_get_type(sd_bus_message *m, uint8_t *type) {
748 assert_return(m, -EINVAL);
749 assert_return(type, -EINVAL);
751 *type = m->header->type;
755 _public_ int sd_bus_message_get_serial(sd_bus_message *m, uint64_t *serial) {
756 assert_return(m, -EINVAL);
757 assert_return(serial, -EINVAL);
758 assert_return(m->header->serial != 0, -ENOENT);
760 *serial = BUS_MESSAGE_SERIAL(m);
764 _public_ int sd_bus_message_get_reply_serial(sd_bus_message *m, uint64_t *serial) {
765 assert_return(m, -EINVAL);
766 assert_return(serial, -EINVAL);
767 assert_return(m->reply_serial != 0, -ENOENT);
769 *serial = m->reply_serial;
773 _public_ int sd_bus_message_get_no_reply(sd_bus_message *m) {
774 assert_return(m, -EINVAL);
776 return m->header->type == SD_BUS_MESSAGE_METHOD_CALL ? !!(m->header->flags & SD_BUS_MESSAGE_NO_REPLY_EXPECTED) : 0;
779 _public_ int sd_bus_message_get_no_auto_start(sd_bus_message *m) {
780 assert_return(m, -EINVAL);
782 return !!(m->header->flags & SD_BUS_MESSAGE_NO_AUTO_START);
785 _public_ const char *sd_bus_message_get_path(sd_bus_message *m) {
786 assert_return(m, NULL);
791 _public_ const char *sd_bus_message_get_interface(sd_bus_message *m) {
792 assert_return(m, NULL);
797 _public_ const char *sd_bus_message_get_member(sd_bus_message *m) {
798 assert_return(m, NULL);
803 _public_ const char *sd_bus_message_get_destination(sd_bus_message *m) {
804 assert_return(m, NULL);
806 return m->destination;
809 _public_ const char *sd_bus_message_get_sender(sd_bus_message *m) {
810 assert_return(m, NULL);
815 _public_ const sd_bus_error *sd_bus_message_get_error(sd_bus_message *m) {
816 assert_return(m, NULL);
817 assert_return(sd_bus_error_is_set(&m->error), NULL);
822 _public_ int sd_bus_message_get_uid(sd_bus_message *m, uid_t *uid) {
823 assert_return(m, -EINVAL);
824 assert_return(uid, -EINVAL);
825 assert_return(m->uid_valid, -ESRCH);
831 _public_ int sd_bus_message_get_gid(sd_bus_message *m, gid_t *gid) {
832 assert_return(m, -EINVAL);
833 assert_return(gid, -EINVAL);
834 assert_return(m->gid_valid, -ESRCH);
840 _public_ int sd_bus_message_get_pid(sd_bus_message *m, pid_t *pid) {
841 assert_return(m, -EINVAL);
842 assert_return(pid, -EINVAL);
843 assert_return(m->pid > 0, -ESRCH);
849 _public_ int sd_bus_message_get_tid(sd_bus_message *m, pid_t *tid) {
850 assert_return(m, -EINVAL);
851 assert_return(tid, -EINVAL);
852 assert_return(m->tid > 0, -ESRCH);
858 _public_ int sd_bus_message_get_pid_starttime(sd_bus_message *m, uint64_t *usec) {
859 assert_return(m, -EINVAL);
860 assert_return(usec, -EINVAL);
861 assert_return(m->pid_starttime > 0, -ESRCH);
863 *usec = m->pid_starttime;
867 _public_ int sd_bus_message_get_selinux_context(sd_bus_message *m, const char **ret) {
868 assert_return(m, -EINVAL);
869 assert_return(m->label, -ESRCH);
875 _public_ int sd_bus_message_get_monotonic_timestamp(sd_bus_message *m, uint64_t *usec) {
876 assert_return(m, -EINVAL);
877 assert_return(usec, -EINVAL);
878 assert_return(m->monotonic > 0, -ESRCH);
880 *usec = m->monotonic;
884 _public_ int sd_bus_message_get_realtime_timestamp(sd_bus_message *m, uint64_t *usec) {
885 assert_return(m, -EINVAL);
886 assert_return(usec, -EINVAL);
887 assert_return(m->realtime > 0, -ESRCH);
893 _public_ int sd_bus_message_get_comm(sd_bus_message *m, const char **ret) {
894 assert_return(m, -EINVAL);
895 assert_return(ret, -EINVAL);
896 assert_return(m->comm, -ESRCH);
902 _public_ int sd_bus_message_get_tid_comm(sd_bus_message *m, const char **ret) {
903 assert_return(m, -EINVAL);
904 assert_return(ret, -EINVAL);
905 assert_return(m->tid_comm, -ESRCH);
911 _public_ int sd_bus_message_get_exe(sd_bus_message *m, const char **ret) {
912 assert_return(m, -EINVAL);
913 assert_return(ret, -EINVAL);
914 assert_return(m->exe, -ESRCH);
920 _public_ int sd_bus_message_get_cgroup(sd_bus_message *m, const char **ret) {
921 assert_return(m, -EINVAL);
922 assert_return(ret, -EINVAL);
923 assert_return(m->cgroup, -ESRCH);
929 _public_ int sd_bus_message_get_unit(sd_bus_message *m, const char **ret) {
932 assert_return(m, -EINVAL);
933 assert_return(ret, -EINVAL);
934 assert_return(m->cgroup, -ESRCH);
937 r = cg_path_get_unit(m->cgroup, &m->unit);
946 _public_ int sd_bus_message_get_user_unit(sd_bus_message *m, const char **ret) {
949 assert_return(m, -EINVAL);
950 assert_return(ret, -EINVAL);
951 assert_return(m->cgroup, -ESRCH);
954 r = cg_path_get_user_unit(m->cgroup, &m->user_unit);
963 _public_ int sd_bus_message_get_session(sd_bus_message *m, const char **ret) {
966 assert_return(m, -EINVAL);
967 assert_return(ret, -EINVAL);
968 assert_return(m->cgroup, -ESRCH);
971 r = cg_path_get_session(m->cgroup, &m->session);
980 _public_ int sd_bus_message_get_owner_uid(sd_bus_message *m, uid_t *uid) {
981 assert_return(m, -EINVAL);
982 assert_return(uid, -EINVAL);
983 assert_return(m->cgroup, -ESRCH);
985 return cg_path_get_owner_uid(m->cgroup, uid);
988 _public_ int sd_bus_message_get_cmdline(sd_bus_message *m, char ***cmdline) {
993 assert_return(m, -EINVAL);
994 assert_return(m->cmdline, -ESRCH);
996 for (p = m->cmdline, n = 0; p < m->cmdline + m->cmdline_length; p++)
1000 m->cmdline_array = new(char*, n + 1);
1001 if (!m->cmdline_array)
1004 for (p = m->cmdline, i = 0, first = true; p < m->cmdline + m->cmdline_length; p++) {
1006 m->cmdline_array[i++] = (char*) p;
1011 m->cmdline_array[i] = NULL;
1012 *cmdline = m->cmdline_array;
1017 _public_ int sd_bus_message_get_audit_sessionid(sd_bus_message *m, uint32_t *sessionid) {
1018 assert_return(m, -EINVAL);
1019 assert_return(sessionid, -EINVAL);
1020 assert_return(m->audit, -ESRCH);
1022 *sessionid = m->audit->sessionid;
1026 _public_ int sd_bus_message_get_audit_loginuid(sd_bus_message *m, uid_t *uid) {
1027 assert_return(m, -EINVAL);
1028 assert_return(uid, -EINVAL);
1029 assert_return(m->audit, -ESRCH);
1031 *uid = m->audit->loginuid;
1035 _public_ int sd_bus_message_has_effective_cap(sd_bus_message *m, int capability) {
1038 assert_return(m, -EINVAL);
1039 assert_return(capability < 0, -EINVAL);
1040 assert_return(!m->capability, -ESRCH);
1042 sz = m->capability_size / 4;
1043 if ((unsigned) capability >= sz*8)
1046 return !!(m->capability[2 * sz + (capability / 8)] & (1 << (capability % 8)));
1049 _public_ int sd_bus_message_is_signal(sd_bus_message *m,
1050 const char *interface,
1051 const char *member) {
1052 assert_return(m, -EINVAL);
1054 if (m->header->type != SD_BUS_MESSAGE_SIGNAL)
1057 if (interface && (!m->interface || !streq(m->interface, interface)))
1060 if (member && (!m->member || !streq(m->member, member)))
1066 _public_ int sd_bus_message_is_method_call(sd_bus_message *m,
1067 const char *interface,
1068 const char *member) {
1069 assert_return(m, -EINVAL);
1071 if (m->header->type != SD_BUS_MESSAGE_METHOD_CALL)
1074 if (interface && (!m->interface || !streq(m->interface, interface)))
1077 if (member && (!m->member || !streq(m->member, member)))
1083 _public_ int sd_bus_message_is_method_error(sd_bus_message *m, const char *name) {
1084 assert_return(m, -EINVAL);
1086 if (m->header->type != SD_BUS_MESSAGE_METHOD_ERROR)
1089 if (name && (!m->error.name || !streq(m->error.name, name)))
1095 _public_ int sd_bus_message_set_no_reply(sd_bus_message *m, int b) {
1096 assert_return(m, -EINVAL);
1097 assert_return(!m->sealed, -EPERM);
1098 assert_return(m->header->type == SD_BUS_MESSAGE_METHOD_CALL, -EPERM);
1101 m->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
1103 m->header->flags &= ~SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
1108 _public_ int sd_bus_message_set_no_auto_start(sd_bus_message *m, int b) {
1109 assert_return(m, -EINVAL);
1110 assert_return(!m->sealed, -EPERM);
1113 m->header->flags |= SD_BUS_MESSAGE_NO_AUTO_START;
1115 m->header->flags &= ~SD_BUS_MESSAGE_NO_AUTO_START;
1120 static struct bus_container *message_get_container(sd_bus_message *m) {
1123 if (m->n_containers == 0)
1124 return &m->root_container;
1126 assert(m->containers);
1127 return m->containers + m->n_containers - 1;
1130 struct bus_body_part *message_append_part(sd_bus_message *m) {
1131 struct bus_body_part *part;
1138 if (m->n_body_parts <= 0) {
1142 assert(m->body_end);
1144 part = new0(struct bus_body_part, 1);
1150 m->body_end->next = part;
1160 static void part_zero(struct bus_body_part *part, size_t sz) {
1165 /* All other fields can be left in their defaults */
1166 assert(!part->data);
1167 assert(part->memfd < 0);
1170 part->is_zero = true;
1171 part->sealed = true;
1174 static int part_make_space(
1175 struct sd_bus_message *m,
1176 struct bus_body_part *part,
1185 assert(!part->sealed);
1190 if (!part->data && part->memfd < 0)
1191 part->memfd = bus_kernel_pop_memfd(m->bus, &part->data, &part->mapped);
1193 if (part->memfd >= 0) {
1196 r = ioctl(part->memfd, KDBUS_CMD_MEMFD_SIZE_SET, &u);
1202 if (!part->data || sz > part->mapped) {
1203 size_t psz = PAGE_ALIGN(sz > 0 ? sz : 1);
1205 if (part->mapped <= 0)
1206 n = mmap(NULL, psz, PROT_READ|PROT_WRITE, MAP_SHARED, part->memfd, 0);
1208 n = mremap(part->data, part->mapped, psz, MREMAP_MAYMOVE);
1210 if (n == MAP_FAILED) {
1219 part->munmap_this = true;
1221 n = realloc(part->data, MAX(sz, 1u));
1228 part->free_this = true;
1232 *q = part->data ? (uint8_t*) part->data + part->size : NULL;
1238 static void message_extend_containers(sd_bus_message *m, size_t expand) {
1239 struct bus_container *c;
1246 /* Update counters */
1247 for (c = m->containers; c < m->containers + m->n_containers; c++)
1249 *c->array_size += expand;
1252 static void *message_extend_body(sd_bus_message *m, size_t align, size_t sz) {
1253 struct bus_body_part *part = NULL;
1254 size_t start_body, end_body, padding, start_part, end_part, added;
1266 start_body = ALIGN_TO((size_t) m->header->body_size, align);
1267 end_body = start_body + sz;
1269 padding = start_body - m->header->body_size;
1270 added = padding + sz;
1272 /* Check for 32bit overflows */
1273 if (end_body > (size_t) ((uint32_t) -1)) {
1279 m->n_body_parts <= 0 ||
1280 m->body_end->sealed ||
1281 padding != ALIGN_TO(m->body_end->size, align) - m->body_end->size;
1285 part = message_append_part(m);
1289 part_zero(part, padding);
1292 part = message_append_part(m);
1296 r = part_make_space(m, part, sz, &p);
1300 struct bus_container *c;
1308 start_part = ALIGN_TO(part->size, align);
1309 end_part = start_part + sz;
1311 r = part_make_space(m, part, end_part, &p);
1316 memset(p, 0, padding);
1317 p = (uint8_t*) p + padding;
1320 /* Readjust pointers */
1321 for (c = m->containers; c < m->containers + m->n_containers; c++)
1322 c->array_size = adjust_pointer(c->array_size, op, os, part->data);
1324 m->error.message = (const char*) adjust_pointer(m->error.message, op, os, part->data);
1327 m->header->body_size = end_body;
1328 message_extend_containers(m, added);
1333 int message_append_basic(sd_bus_message *m, char type, const void *p, const void **stored) {
1334 struct bus_container *c;
1342 assert_return(m, -EINVAL);
1343 assert_return(!m->sealed, -EPERM);
1344 assert_return(bus_type_is_basic(type), -EINVAL);
1345 assert_return(!m->poisoned, -ESTALE);
1347 c = message_get_container(m);
1349 if (c->signature && c->signature[c->index]) {
1350 /* Container signature is already set */
1352 if (c->signature[c->index] != type)
1357 /* Maybe we can append to the signature? But only if this is the top-level container*/
1358 if (c->enclosing != 0)
1361 e = strextend(&c->signature, CHAR_TO_STR(type), NULL);
1370 case SD_BUS_TYPE_STRING:
1371 /* To make things easy we'll serialize a NULL string
1372 * into the empty string */
1375 /* Fall through... */
1376 case SD_BUS_TYPE_OBJECT_PATH:
1384 sz = 4 + strlen(p) + 1;
1387 case SD_BUS_TYPE_SIGNATURE:
1395 sz = 1 + strlen(p) + 1;
1398 case SD_BUS_TYPE_BOOLEAN:
1407 assert_cc(sizeof(int) == sizeof(uint32_t));
1413 case SD_BUS_TYPE_UNIX_FD: {
1421 if (!m->allow_fds) {
1434 fd = fcntl(z, F_DUPFD_CLOEXEC, 3);
1440 f = realloc(m->fds, sizeof(int) * (m->n_fds + 1));
1460 align = bus_type_get_alignment(type);
1461 sz = bus_type_get_size(type);
1468 a = message_extend_body(m, align, sz);
1474 if (type == SD_BUS_TYPE_STRING || type == SD_BUS_TYPE_OBJECT_PATH) {
1475 *(uint32_t*) a = sz - 5;
1476 memcpy((uint8_t*) a + 4, p, sz - 4);
1479 *stored = (const uint8_t*) a + 4;
1481 } else if (type == SD_BUS_TYPE_SIGNATURE) {
1482 *(uint8_t*) a = sz - 1;
1483 memcpy((uint8_t*) a + 1, p, sz - 1);
1486 *stored = (const uint8_t*) a + 1;
1487 } else if (type == SD_BUS_TYPE_UNIX_FD) {
1488 *(uint32_t*) a = fdi;
1502 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1509 close_nointr_nofail(fd);
1514 _public_ int sd_bus_message_append_basic(sd_bus_message *m, char type, const void *p) {
1515 return message_append_basic(m, type, p, NULL);
1518 _public_ int sd_bus_message_append_string_space(
1523 struct bus_container *c;
1526 assert_return(m, -EINVAL);
1527 assert_return(s, -EINVAL);
1528 assert_return(!m->sealed, -EPERM);
1529 assert_return(!m->poisoned, -ESTALE);
1531 c = message_get_container(m);
1533 if (c->signature && c->signature[c->index]) {
1534 /* Container signature is already set */
1536 if (c->signature[c->index] != SD_BUS_TYPE_STRING)
1541 /* Maybe we can append to the signature? But only if this is the top-level container*/
1542 if (c->enclosing != 0)
1545 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRING), NULL);
1552 a = message_extend_body(m, 4, 4 + size + 1);
1556 *(uint32_t*) a = size;
1561 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1567 _public_ int sd_bus_message_append_string_iovec(
1569 const struct iovec *iov,
1577 assert_return(m, -EINVAL);
1578 assert_return(!m->sealed, -EPERM);
1579 assert_return(iov || n == 0, -EINVAL);
1580 assert_return(!m->poisoned, -ESTALE);
1582 size = IOVEC_TOTAL_SIZE(iov, n);
1584 r = sd_bus_message_append_string_space(m, size, &p);
1588 for (i = 0; i < n; i++) {
1590 if (iov[i].iov_base)
1591 memcpy(p, iov[i].iov_base, iov[i].iov_len);
1593 memset(p, ' ', iov[i].iov_len);
1595 p += iov[i].iov_len;
1601 static int bus_message_open_array(
1603 struct bus_container *c,
1604 const char *contents,
1605 uint32_t **array_size) {
1611 struct bus_body_part *o;
1618 if (!signature_is_single(contents, true))
1621 alignment = bus_type_get_alignment(contents[0]);
1625 if (c->signature && c->signature[c->index]) {
1627 /* Verify the existing signature */
1629 if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
1632 if (!startswith(c->signature + c->index + 1, contents))
1635 nindex = c->index + 1 + strlen(contents);
1639 if (c->enclosing != 0)
1642 /* Extend the existing signature */
1644 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_ARRAY), contents, NULL);
1650 nindex = e - c->signature;
1653 a = message_extend_body(m, 4, 4);
1658 op = m->body_end->data;
1659 os = m->body_end->size;
1661 /* Add alignment between size and first element */
1662 if (!message_extend_body(m, alignment, 0))
1665 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1668 /* location of array size might have changed so let's readjust a */
1669 if (o == m->body_end)
1670 a = adjust_pointer(a, op, os, m->body_end->data);
1677 static int bus_message_open_variant(
1679 struct bus_container *c,
1680 const char *contents) {
1689 if (!signature_is_single(contents, false))
1692 if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
1695 if (c->signature && c->signature[c->index]) {
1697 if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
1703 if (c->enclosing != 0)
1706 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_VARIANT), NULL);
1713 l = strlen(contents);
1714 a = message_extend_body(m, 1, 1 + l + 1);
1719 memcpy((uint8_t*) a + 1, contents, l + 1);
1721 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1727 static int bus_message_open_struct(
1729 struct bus_container *c,
1730 const char *contents) {
1738 if (!signature_is_valid(contents, false))
1741 if (c->signature && c->signature[c->index]) {
1744 l = strlen(contents);
1746 if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
1747 !startswith(c->signature + c->index + 1, contents) ||
1748 c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
1751 nindex = c->index + 1 + l + 1;
1755 if (c->enclosing != 0)
1758 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_BEGIN), contents, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_END), NULL);
1764 nindex = e - c->signature;
1767 /* Align contents to 8 byte boundary */
1768 if (!message_extend_body(m, 8, 0))
1771 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1777 static int bus_message_open_dict_entry(
1779 struct bus_container *c,
1780 const char *contents) {
1788 if (!signature_is_pair(contents))
1791 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1794 if (c->signature && c->signature[c->index]) {
1797 l = strlen(contents);
1799 if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
1800 !startswith(c->signature + c->index + 1, contents) ||
1801 c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
1804 nindex = c->index + 1 + l + 1;
1808 /* Align contents to 8 byte boundary */
1809 if (!message_extend_body(m, 8, 0))
1812 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1818 _public_ int sd_bus_message_open_container(
1821 const char *contents) {
1823 struct bus_container *c, *w;
1824 uint32_t *array_size = NULL;
1829 assert_return(m, -EINVAL);
1830 assert_return(!m->sealed, -EPERM);
1831 assert_return(contents, -EINVAL);
1832 assert_return(!m->poisoned, -ESTALE);
1834 /* Make sure we have space for one more container */
1835 w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
1843 c = message_get_container(m);
1845 signature = strdup(contents);
1851 /* Save old index in the parent container, in case we have to
1852 * abort this container */
1853 c->saved_index = c->index;
1854 before = m->header->body_size;
1856 if (type == SD_BUS_TYPE_ARRAY)
1857 r = bus_message_open_array(m, c, contents, &array_size);
1858 else if (type == SD_BUS_TYPE_VARIANT)
1859 r = bus_message_open_variant(m, c, contents);
1860 else if (type == SD_BUS_TYPE_STRUCT)
1861 r = bus_message_open_struct(m, c, contents);
1862 else if (type == SD_BUS_TYPE_DICT_ENTRY)
1863 r = bus_message_open_dict_entry(m, c, contents);
1872 /* OK, let's fill it in */
1873 w += m->n_containers++;
1874 w->enclosing = type;
1875 w->signature = signature;
1877 w->array_size = array_size;
1879 w->begin = m->rindex;
1884 _public_ int sd_bus_message_close_container(sd_bus_message *m) {
1885 struct bus_container *c;
1887 assert_return(m, -EINVAL);
1888 assert_return(!m->sealed, -EPERM);
1889 assert_return(m->n_containers > 0, -EINVAL);
1890 assert_return(!m->poisoned, -ESTALE);
1892 c = message_get_container(m);
1893 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1894 if (c->signature && c->signature[c->index] != 0)
1909 static int type_stack_push(TypeStack *stack, unsigned max, unsigned *i, const char *types, unsigned n_struct, unsigned n_array) {
1916 stack[*i].types = types;
1917 stack[*i].n_struct = n_struct;
1918 stack[*i].n_array = n_array;
1924 static int type_stack_pop(TypeStack *stack, unsigned max, unsigned *i, const char **types, unsigned *n_struct, unsigned *n_array) {
1935 *types = stack[*i].types;
1936 *n_struct = stack[*i].n_struct;
1937 *n_array = stack[*i].n_array;
1942 int bus_message_append_ap(
1947 unsigned n_array, n_struct;
1948 TypeStack stack[BUS_CONTAINER_DEPTH];
1949 unsigned stack_ptr = 0;
1957 n_array = (unsigned) -1;
1958 n_struct = strlen(types);
1963 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
1964 r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
1970 r = sd_bus_message_close_container(m);
1978 if (n_array != (unsigned) -1)
1987 case SD_BUS_TYPE_BYTE: {
1990 x = (uint8_t) va_arg(ap, int);
1991 r = sd_bus_message_append_basic(m, *t, &x);
1995 case SD_BUS_TYPE_BOOLEAN:
1996 case SD_BUS_TYPE_INT32:
1997 case SD_BUS_TYPE_UINT32:
1998 case SD_BUS_TYPE_UNIX_FD: {
2001 /* We assume a boolean is the same as int32_t */
2002 assert_cc(sizeof(int32_t) == sizeof(int));
2004 x = va_arg(ap, uint32_t);
2005 r = sd_bus_message_append_basic(m, *t, &x);
2009 case SD_BUS_TYPE_INT16:
2010 case SD_BUS_TYPE_UINT16: {
2013 x = (uint16_t) va_arg(ap, int);
2014 r = sd_bus_message_append_basic(m, *t, &x);
2018 case SD_BUS_TYPE_INT64:
2019 case SD_BUS_TYPE_UINT64:
2020 case SD_BUS_TYPE_DOUBLE: {
2023 x = va_arg(ap, uint64_t);
2024 r = sd_bus_message_append_basic(m, *t, &x);
2028 case SD_BUS_TYPE_STRING:
2029 case SD_BUS_TYPE_OBJECT_PATH:
2030 case SD_BUS_TYPE_SIGNATURE: {
2033 x = va_arg(ap, const char*);
2034 r = sd_bus_message_append_basic(m, *t, x);
2038 case SD_BUS_TYPE_ARRAY: {
2041 r = signature_element_length(t + 1, &k);
2047 memcpy(s, t + 1, k);
2050 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, s);
2055 if (n_array == (unsigned) -1) {
2060 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2066 n_array = va_arg(ap, unsigned);
2071 case SD_BUS_TYPE_VARIANT: {
2074 s = va_arg(ap, const char*);
2078 r = sd_bus_message_open_container(m, SD_BUS_TYPE_VARIANT, s);
2082 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2087 n_struct = strlen(s);
2088 n_array = (unsigned) -1;
2093 case SD_BUS_TYPE_STRUCT_BEGIN:
2094 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
2097 r = signature_element_length(t, &k);
2104 memcpy(s, t + 1, k - 2);
2107 r = sd_bus_message_open_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
2112 if (n_array == (unsigned) -1) {
2117 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2123 n_array = (unsigned) -1;
2139 _public_ int sd_bus_message_append(sd_bus_message *m, const char *types, ...) {
2143 assert_return(m, -EINVAL);
2144 assert_return(types, -EINVAL);
2145 assert_return(!m->sealed, -EPERM);
2146 assert_return(!m->poisoned, -ESTALE);
2148 va_start(ap, types);
2149 r = bus_message_append_ap(m, types, ap);
2155 _public_ int sd_bus_message_append_array_space(sd_bus_message *m,
2163 assert_return(m, -EINVAL);
2164 assert_return(!m->sealed, -EPERM);
2165 assert_return(bus_type_is_trivial(type), -EINVAL);
2166 assert_return(ptr || size == 0, -EINVAL);
2167 assert_return(!m->poisoned, -ESTALE);
2169 align = bus_type_get_alignment(type);
2170 sz = bus_type_get_size(type);
2172 assert_se(align > 0);
2178 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
2182 a = message_extend_body(m, align, size);
2186 r = sd_bus_message_close_container(m);
2194 _public_ int sd_bus_message_append_array(sd_bus_message *m,
2201 assert_return(m, -EINVAL);
2202 assert_return(!m->sealed, -EPERM);
2203 assert_return(bus_type_is_trivial(type), -EINVAL);
2204 assert_return(ptr || size == 0, -EINVAL);
2205 assert_return(!m->poisoned, -ESTALE);
2207 r = sd_bus_message_append_array_space(m, type, size, &p);
2212 memcpy(p, ptr, size);
2217 _public_ int sd_bus_message_append_array_iovec(
2220 const struct iovec *iov,
2228 assert_return(m, -EINVAL);
2229 assert_return(!m->sealed, -EPERM);
2230 assert_return(bus_type_is_trivial(type), -EINVAL);
2231 assert_return(iov || n == 0, -EINVAL);
2232 assert_return(!m->poisoned, -ESTALE);
2234 size = IOVEC_TOTAL_SIZE(iov, n);
2236 r = sd_bus_message_append_array_space(m, type, size, &p);
2240 for (i = 0; i < n; i++) {
2242 if (iov[i].iov_base)
2243 memcpy(p, iov[i].iov_base, iov[i].iov_len);
2245 memset(p, 0, iov[i].iov_len);
2247 p = (uint8_t*) p + iov[i].iov_len;
2253 _public_ int sd_bus_message_append_array_memfd(sd_bus_message *m,
2256 _cleanup_close_ int copy_fd = -1;
2257 struct bus_body_part *part;
2269 if (!bus_type_is_trivial(type))
2274 r = sd_memfd_set_sealed(memfd, true);
2278 copy_fd = sd_memfd_dup_fd(memfd);
2282 r = sd_memfd_get_size(memfd, &size);
2286 align = bus_type_get_alignment(type);
2287 sz = bus_type_get_size(type);
2289 assert_se(align > 0);
2295 if (size > (uint64_t) (uint32_t) -1)
2298 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
2302 a = message_extend_body(m, align, 0);
2306 part = message_append_part(m);
2310 part->memfd = copy_fd;
2311 part->sealed = true;
2315 message_extend_containers(m, size);
2316 m->header->body_size += size;
2318 return sd_bus_message_close_container(m);
2321 _public_ int sd_bus_message_append_string_memfd(sd_bus_message *m, sd_memfd *memfd) {
2322 _cleanup_close_ int copy_fd = -1;
2323 struct bus_body_part *part;
2324 struct bus_container *c;
2329 assert_return(m, -EINVAL);
2330 assert_return(memfd, -EINVAL);
2331 assert_return(!m->sealed, -EPERM);
2332 assert_return(!m->poisoned, -ESTALE);
2334 r = sd_memfd_set_sealed(memfd, true);
2338 copy_fd = sd_memfd_dup_fd(memfd);
2342 r = sd_memfd_get_size(memfd, &size);
2346 /* We require this to be NUL terminated */
2350 if (size > (uint64_t) (uint32_t) -1)
2353 c = message_get_container(m);
2354 if (c->signature && c->signature[c->index]) {
2355 /* Container signature is already set */
2357 if (c->signature[c->index] != SD_BUS_TYPE_STRING)
2362 /* Maybe we can append to the signature? But only if this is the top-level container*/
2363 if (c->enclosing != 0)
2366 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRING), NULL);
2373 a = message_extend_body(m, 4, 4);
2377 *(uint32_t*) a = size - 1;
2379 part = message_append_part(m);
2383 part->memfd = copy_fd;
2384 part->sealed = true;
2388 message_extend_containers(m, size);
2389 m->header->body_size += size;
2391 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2397 _public_ int sd_bus_message_append_strv(sd_bus_message *m, char **l) {
2401 assert_return(m, -EINVAL);
2402 assert_return(!m->sealed, -EPERM);
2403 assert_return(!m->poisoned, -ESTALE);
2405 r = sd_bus_message_open_container(m, 'a', "s");
2409 STRV_FOREACH(i, l) {
2410 r = sd_bus_message_append_basic(m, 's', *i);
2415 return sd_bus_message_close_container(m);
2418 int bus_body_part_map(struct bus_body_part *part) {
2427 if (part->size <= 0)
2430 /* For smaller zero parts (as used for padding) we don't need to map anything... */
2431 if (part->memfd < 0 && part->is_zero && part->size < 8) {
2432 static const uint8_t zeroes[7] = { };
2433 part->data = (void*) zeroes;
2437 psz = PAGE_ALIGN(part->size);
2439 if (part->memfd >= 0)
2440 p = mmap(NULL, psz, PROT_READ, MAP_SHARED, part->memfd, 0);
2441 else if (part->is_zero)
2442 p = mmap(NULL, psz, PROT_READ, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
2446 if (p == MAP_FAILED)
2451 part->munmap_this = true;
2456 void bus_body_part_unmap(struct bus_body_part *part) {
2460 if (part->memfd < 0)
2466 if (!part->munmap_this)
2469 assert_se(munmap(part->data, part->mapped) == 0);
2473 part->munmap_this = false;
2478 static int buffer_peek(const void *p, uint32_t sz, size_t *rindex, size_t align, size_t nbytes, void **r) {
2479 size_t k, start, end;
2484 start = ALIGN_TO((size_t) *rindex, align);
2485 end = start + nbytes;
2490 /* Verify that padding is 0 */
2491 for (k = *rindex; k < start; k++)
2492 if (((const uint8_t*) p)[k] != 0)
2496 *r = (uint8_t*) p + start;
2503 static bool message_end_of_signature(sd_bus_message *m) {
2504 struct bus_container *c;
2508 c = message_get_container(m);
2509 return !c->signature || c->signature[c->index] == 0;
2512 static bool message_end_of_array(sd_bus_message *m, size_t index) {
2513 struct bus_container *c;
2517 c = message_get_container(m);
2521 return index >= c->begin + BUS_MESSAGE_BSWAP32(m, *c->array_size);
2524 _public_ int sd_bus_message_at_end(sd_bus_message *m, int complete) {
2525 assert_return(m, -EINVAL);
2526 assert_return(m->sealed, -EPERM);
2528 if (complete && m->n_containers > 0)
2531 if (message_end_of_signature(m))
2534 if (message_end_of_array(m, m->rindex))
2540 static struct bus_body_part* find_part(sd_bus_message *m, size_t index, size_t sz, void **p) {
2541 struct bus_body_part *part;
2547 if (m->cached_rindex_part && index >= m->cached_rindex_part_begin) {
2548 part = m->cached_rindex_part;
2549 begin = m->cached_rindex_part_begin;
2559 if (index + sz <= begin + part->size) {
2561 r = bus_body_part_map(part);
2566 *p = (uint8_t*) part->data + index - begin;
2568 m->cached_rindex_part = part;
2569 m->cached_rindex_part_begin = begin;
2574 begin += part->size;
2581 static int message_peek_body(
2588 size_t k, start, end, padding;
2589 struct bus_body_part *part;
2596 if (message_end_of_array(m, *rindex))
2599 start = ALIGN_TO((size_t) *rindex, align);
2600 padding = start - *rindex;
2601 end = start + nbytes;
2603 if (end > BUS_MESSAGE_BODY_SIZE(m))
2606 part = find_part(m, *rindex, padding, (void**) &q);
2611 /* Verify padding */
2612 for (k = 0; k < padding; k++)
2617 part = find_part(m, start, nbytes, (void**) &q);
2629 static bool validate_nul(const char *s, size_t l) {
2631 /* Check for NUL chars in the string */
2632 if (memchr(s, 0, l))
2635 /* Check for NUL termination */
2642 static bool validate_string(const char *s, size_t l) {
2644 if (!validate_nul(s, l))
2647 /* Check if valid UTF8 */
2648 if (!utf8_is_valid(s))
2654 static bool validate_signature(const char *s, size_t l) {
2656 if (!validate_nul(s, l))
2659 /* Check if valid signature */
2660 if (!signature_is_valid(s, true))
2666 static bool validate_object_path(const char *s, size_t l) {
2668 if (!validate_nul(s, l))
2671 if (!object_path_is_valid(s))
2677 _public_ int sd_bus_message_read_basic(sd_bus_message *m, char type, void *p) {
2678 struct bus_container *c;
2682 assert_return(m, -EINVAL);
2683 assert_return(m->sealed, -EPERM);
2684 assert_return(bus_type_is_basic(type), -EINVAL);
2686 if (message_end_of_signature(m))
2689 if (message_end_of_array(m, m->rindex))
2692 c = message_get_container(m);
2693 if (c->signature[c->index] != type)
2698 case SD_BUS_TYPE_STRING:
2699 case SD_BUS_TYPE_OBJECT_PATH: {
2704 r = message_peek_body(m, &rindex, 4, 4, &q);
2708 l = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2709 r = message_peek_body(m, &rindex, 1, l+1, &q);
2715 if (type == SD_BUS_TYPE_OBJECT_PATH) {
2716 if (!validate_object_path(q, l))
2719 if (!validate_string(q, l))
2725 *(const char**) p = q;
2730 case SD_BUS_TYPE_SIGNATURE: {
2735 r = message_peek_body(m, &rindex, 1, 1, &q);
2740 r = message_peek_body(m, &rindex, 1, l+1, &q);
2746 if (!validate_signature(q, l))
2752 *(const char**) p = q;
2760 align = bus_type_get_alignment(type);
2761 sz = bus_type_get_size(type);
2762 assert(align > 0 && sz > 0);
2765 r = message_peek_body(m, &rindex, align, sz, &q);
2771 case SD_BUS_TYPE_BYTE:
2773 *(uint8_t*) p = *(uint8_t*) q;
2776 case SD_BUS_TYPE_BOOLEAN:
2778 *(int*) p = !!*(uint32_t*) q;
2781 case SD_BUS_TYPE_INT16:
2782 case SD_BUS_TYPE_UINT16:
2784 *(uint16_t*) p = BUS_MESSAGE_BSWAP16(m, *(uint16_t*) q);
2787 case SD_BUS_TYPE_INT32:
2788 case SD_BUS_TYPE_UINT32:
2790 *(uint32_t*) p = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2793 case SD_BUS_TYPE_INT64:
2794 case SD_BUS_TYPE_UINT64:
2795 case SD_BUS_TYPE_DOUBLE:
2797 *(uint64_t*) p = BUS_MESSAGE_BSWAP64(m, *(uint64_t*) q);
2800 case SD_BUS_TYPE_UNIX_FD: {
2803 j = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2808 *(int*) p = m->fds[j];
2813 assert_not_reached("Unknown basic type...");
2822 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2828 static int bus_message_enter_array(
2830 struct bus_container *c,
2831 const char *contents,
2832 uint32_t **array_size) {
2843 if (!signature_is_single(contents, true))
2846 alignment = bus_type_get_alignment(contents[0]);
2850 if (!c->signature || c->signature[c->index] == 0)
2853 if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
2856 if (!startswith(c->signature + c->index + 1, contents))
2860 r = message_peek_body(m, &rindex, 4, 4, &q);
2864 if (BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q) > BUS_ARRAY_MAX_SIZE)
2867 r = message_peek_body(m, &rindex, alignment, 0, NULL);
2873 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2874 c->index += 1 + strlen(contents);
2878 *array_size = (uint32_t*) q;
2883 static int bus_message_enter_variant(
2885 struct bus_container *c,
2886 const char *contents) {
2897 if (!signature_is_single(contents, false))
2900 if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
2903 if (!c->signature || c->signature[c->index] == 0)
2906 if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
2910 r = message_peek_body(m, &rindex, 1, 1, &q);
2915 r = message_peek_body(m, &rindex, 1, l+1, &q);
2921 if (!validate_signature(q, l))
2924 if (!streq(q, contents))
2927 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2935 static int bus_message_enter_struct(
2937 struct bus_container *c,
2938 const char *contents) {
2947 if (!signature_is_valid(contents, false))
2950 if (!c->signature || c->signature[c->index] == 0)
2953 l = strlen(contents);
2955 if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
2956 !startswith(c->signature + c->index + 1, contents) ||
2957 c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
2960 r = message_peek_body(m, &m->rindex, 8, 0, NULL);
2964 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2965 c->index += 1 + l + 1;
2970 static int bus_message_enter_dict_entry(
2972 struct bus_container *c,
2973 const char *contents) {
2982 if (!signature_is_pair(contents))
2985 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2988 if (!c->signature || c->signature[c->index] == 0)
2991 l = strlen(contents);
2993 if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
2994 !startswith(c->signature + c->index + 1, contents) ||
2995 c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
2998 r = message_peek_body(m, &m->rindex, 8, 0, NULL);
3002 if (c->enclosing != SD_BUS_TYPE_ARRAY)
3003 c->index += 1 + l + 1;
3008 _public_ int sd_bus_message_enter_container(sd_bus_message *m,
3010 const char *contents) {
3011 struct bus_container *c, *w;
3012 uint32_t *array_size = NULL;
3017 assert_return(m, -EINVAL);
3018 assert_return(m->sealed, -EPERM);
3019 assert_return(type != 0 || !contents, -EINVAL);
3021 if (type == 0 || !contents) {
3025 /* Allow entering into anonymous containers */
3026 r = sd_bus_message_peek_type(m, &tt, &cc);
3030 if (type != 0 && type != tt)
3033 if (contents && !streq(contents, cc))
3041 * We enforce a global limit on container depth, that is much
3042 * higher than the 32 structs and 32 arrays the specification
3043 * mandates. This is simpler to implement for us, and we need
3044 * this only to ensure our container array doesn't grow
3045 * without bounds. We are happy to return any data from a
3046 * message as long as the data itself is valid, even if the
3047 * overall message might be not.
3049 * Note that the message signature is validated when
3050 * parsing the headers, and that validation does check the
3053 * Note that the specification defines no limits on the depth
3054 * of stacked variants, but we do.
3056 if (m->n_containers >= BUS_CONTAINER_DEPTH)
3059 w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
3064 if (message_end_of_signature(m))
3067 if (message_end_of_array(m, m->rindex))
3070 c = message_get_container(m);
3072 signature = strdup(contents);
3076 c->saved_index = c->index;
3079 if (type == SD_BUS_TYPE_ARRAY)
3080 r = bus_message_enter_array(m, c, contents, &array_size);
3081 else if (type == SD_BUS_TYPE_VARIANT)
3082 r = bus_message_enter_variant(m, c, contents);
3083 else if (type == SD_BUS_TYPE_STRUCT)
3084 r = bus_message_enter_struct(m, c, contents);
3085 else if (type == SD_BUS_TYPE_DICT_ENTRY)
3086 r = bus_message_enter_dict_entry(m, c, contents);
3095 /* OK, let's fill it in */
3096 w += m->n_containers++;
3097 w->enclosing = type;
3098 w->signature = signature;
3100 w->array_size = array_size;
3102 w->begin = m->rindex;
3107 _public_ int sd_bus_message_exit_container(sd_bus_message *m) {
3108 struct bus_container *c;
3110 assert_return(m, -EINVAL);
3111 assert_return(m->sealed, -EPERM);
3112 assert_return(m->n_containers > 0, -ENXIO);
3114 c = message_get_container(m);
3115 if (c->enclosing == SD_BUS_TYPE_ARRAY) {
3118 l = BUS_MESSAGE_BSWAP32(m, *c->array_size);
3119 if (c->begin + l != m->rindex)
3123 if (c->signature && c->signature[c->index] != 0)
3133 static void message_quit_container(sd_bus_message *m) {
3134 struct bus_container *c;
3138 assert(m->n_containers > 0);
3140 c = message_get_container(m);
3143 assert(m->rindex >= c->before);
3144 m->rindex = c->before;
3146 /* Free container */
3150 /* Correct index of new top-level container */
3151 c = message_get_container(m);
3152 c->index = c->saved_index;
3155 _public_ int sd_bus_message_peek_type(sd_bus_message *m, char *type, const char **contents) {
3156 struct bus_container *c;
3159 assert_return(m, -EINVAL);
3160 assert_return(m->sealed, -EPERM);
3162 if (message_end_of_signature(m))
3165 if (message_end_of_array(m, m->rindex))
3168 c = message_get_container(m);
3170 if (bus_type_is_basic(c->signature[c->index])) {
3174 *type = c->signature[c->index];
3178 if (c->signature[c->index] == SD_BUS_TYPE_ARRAY) {
3184 r = signature_element_length(c->signature+c->index+1, &l);
3190 sig = strndup(c->signature + c->index + 1, l);
3194 free(m->peeked_signature);
3195 m->peeked_signature = sig;
3201 *type = SD_BUS_TYPE_ARRAY;
3206 if (c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ||
3207 c->signature[c->index] == SD_BUS_TYPE_DICT_ENTRY_BEGIN) {
3213 r = signature_element_length(c->signature+c->index, &l);
3218 sig = strndup(c->signature + c->index + 1, l - 2);
3222 free(m->peeked_signature);
3223 m->peeked_signature = sig;
3229 *type = c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY;
3234 if (c->signature[c->index] == SD_BUS_TYPE_VARIANT) {
3240 r = message_peek_body(m, &rindex, 1, 1, &q);
3247 r = message_peek_body(m, &rindex, 1, l+1, &q);
3253 if (!validate_signature(q, l))
3260 *type = SD_BUS_TYPE_VARIANT;
3275 _public_ int sd_bus_message_rewind(sd_bus_message *m, int complete) {
3276 struct bus_container *c;
3278 assert_return(m, -EINVAL);
3279 assert_return(m->sealed, -EPERM);
3282 message_reset_containers(m);
3284 m->root_container.index = 0;
3286 c = message_get_container(m);
3288 c = message_get_container(m);
3291 m->rindex = c->begin;
3294 return !isempty(c->signature);
3297 static int message_read_ap(
3302 unsigned n_array, n_struct;
3303 TypeStack stack[BUS_CONTAINER_DEPTH];
3304 unsigned stack_ptr = 0;
3305 unsigned n_loop = 0;
3313 /* Ideally, we'd just call ourselves recursively on every
3314 * complex type. However, the state of a va_list that is
3315 * passed to a function is undefined after that function
3316 * returns. This means we need to docode the va_list linearly
3317 * in a single stackframe. We hence implement our own
3318 * home-grown stack in an array. */
3320 n_array = (unsigned) -1; /* lenght of current array entries */
3321 n_struct = strlen(types); /* length of current struct contents signature */
3328 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
3329 r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
3335 r = sd_bus_message_exit_container(m);
3343 if (n_array != (unsigned) -1)
3352 case SD_BUS_TYPE_BYTE:
3353 case SD_BUS_TYPE_BOOLEAN:
3354 case SD_BUS_TYPE_INT16:
3355 case SD_BUS_TYPE_UINT16:
3356 case SD_BUS_TYPE_INT32:
3357 case SD_BUS_TYPE_UINT32:
3358 case SD_BUS_TYPE_INT64:
3359 case SD_BUS_TYPE_UINT64:
3360 case SD_BUS_TYPE_DOUBLE:
3361 case SD_BUS_TYPE_STRING:
3362 case SD_BUS_TYPE_OBJECT_PATH:
3363 case SD_BUS_TYPE_SIGNATURE:
3364 case SD_BUS_TYPE_UNIX_FD: {
3367 p = va_arg(ap, void*);
3368 r = sd_bus_message_read_basic(m, *t, p);
3381 case SD_BUS_TYPE_ARRAY: {
3384 r = signature_element_length(t + 1, &k);
3390 memcpy(s, t + 1, k);
3393 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, s);
3404 if (n_array == (unsigned) -1) {
3409 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
3415 n_array = va_arg(ap, unsigned);
3420 case SD_BUS_TYPE_VARIANT: {
3423 s = va_arg(ap, const char *);
3427 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, s);
3437 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
3442 n_struct = strlen(s);
3443 n_array = (unsigned) -1;
3448 case SD_BUS_TYPE_STRUCT_BEGIN:
3449 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
3452 r = signature_element_length(t, &k);
3458 memcpy(s, t + 1, k - 2);
3461 r = sd_bus_message_enter_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
3471 if (n_array == (unsigned) -1) {
3476 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
3482 n_array = (unsigned) -1;
3495 _public_ int sd_bus_message_read(sd_bus_message *m, const char *types, ...) {
3499 assert_return(m, -EINVAL);
3500 assert_return(m->sealed, -EPERM);
3501 assert_return(types, -EINVAL);
3503 va_start(ap, types);
3504 r = message_read_ap(m, types, ap);
3510 _public_ int sd_bus_message_skip(sd_bus_message *m, const char *types) {
3513 assert_return(m, -EINVAL);
3514 assert_return(m->sealed, -EPERM);
3515 assert_return(types, -EINVAL);
3522 case SD_BUS_TYPE_BYTE:
3523 case SD_BUS_TYPE_BOOLEAN:
3524 case SD_BUS_TYPE_INT16:
3525 case SD_BUS_TYPE_UINT16:
3526 case SD_BUS_TYPE_INT32:
3527 case SD_BUS_TYPE_UINT32:
3528 case SD_BUS_TYPE_INT64:
3529 case SD_BUS_TYPE_UINT64:
3530 case SD_BUS_TYPE_DOUBLE:
3531 case SD_BUS_TYPE_STRING:
3532 case SD_BUS_TYPE_OBJECT_PATH:
3533 case SD_BUS_TYPE_SIGNATURE:
3534 case SD_BUS_TYPE_UNIX_FD:
3536 r = sd_bus_message_read_basic(m, *types, NULL);
3540 r = sd_bus_message_skip(m, types + 1);
3546 case SD_BUS_TYPE_ARRAY: {
3549 r = signature_element_length(types + 1, &k);
3555 memcpy(s, types+1, k);
3558 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, s);
3563 r = sd_bus_message_skip(m, s);
3570 r = sd_bus_message_exit_container(m);
3575 r = sd_bus_message_skip(m, types + 1 + k);
3582 case SD_BUS_TYPE_VARIANT: {
3583 const char *contents;
3586 r = sd_bus_message_peek_type(m, &x, &contents);
3590 if (x != SD_BUS_TYPE_VARIANT)
3593 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, contents);
3597 r = sd_bus_message_skip(m, contents);
3602 r = sd_bus_message_exit_container(m);
3606 r = sd_bus_message_skip(m, types + 1);
3613 case SD_BUS_TYPE_STRUCT_BEGIN:
3614 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
3617 r = signature_element_length(types, &k);
3623 memcpy(s, types+1, k-2);
3626 r = sd_bus_message_enter_container(m, *types == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
3630 r = sd_bus_message_skip(m, s);
3635 r = sd_bus_message_exit_container(m);
3640 r = sd_bus_message_skip(m, types + k);
3652 _public_ int sd_bus_message_read_array(sd_bus_message *m,
3656 struct bus_container *c;
3662 assert_return(m, -EINVAL);
3663 assert_return(m->sealed, -EPERM);
3664 assert_return(bus_type_is_trivial(type), -EINVAL);
3665 assert_return(ptr, -EINVAL);
3666 assert_return(size, -EINVAL);
3667 assert_return(!BUS_MESSAGE_NEED_BSWAP(m), -ENOTSUP);
3669 align = bus_type_get_alignment(type);
3673 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
3677 c = message_get_container(m);
3678 sz = BUS_MESSAGE_BSWAP32(m, *c->array_size);
3681 /* Zero length array, let's return some aligned
3682 * pointer that is not NULL */
3683 p = (uint8_t*) NULL + align;
3685 r = message_peek_body(m, &m->rindex, align, sz, &p);
3694 r = sd_bus_message_exit_container(m);
3698 *ptr = (const void*) p;
3704 message_quit_container(m);
3708 static int message_peek_fields(
3719 return buffer_peek(BUS_MESSAGE_FIELDS(m), BUS_MESSAGE_FIELDS_SIZE(m), rindex, align, nbytes, ret);
3722 static int message_peek_field_uint32(
3733 r = message_peek_fields(m, ri, 4, 4, &q);
3738 *ret = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
3743 static int message_peek_field_string(
3745 bool (*validate)(const char *p),
3756 r = message_peek_field_uint32(m, ri, &l);
3760 r = message_peek_fields(m, ri, 1, l+1, &q);
3765 if (!validate_nul(q, l))
3771 if (!validate_string(q, l))
3781 static int message_peek_field_signature(
3793 r = message_peek_fields(m, ri, 1, 1, &q);
3798 r = message_peek_fields(m, ri, 1, l+1, &q);
3802 if (!validate_signature(q, l))
3811 static int message_skip_fields(
3814 uint32_t array_size,
3815 const char **signature) {
3817 size_t original_index;
3824 original_index = *ri;
3830 if (array_size != (uint32_t) -1 &&
3831 array_size <= *ri - original_index)
3838 if (t == SD_BUS_TYPE_STRING) {
3840 r = message_peek_field_string(m, NULL, ri, NULL);
3846 } else if (t == SD_BUS_TYPE_OBJECT_PATH) {
3848 r = message_peek_field_string(m, object_path_is_valid, ri, NULL);
3854 } else if (t == SD_BUS_TYPE_SIGNATURE) {
3856 r = message_peek_field_signature(m, ri, NULL);
3862 } else if (bus_type_is_basic(t)) {
3865 align = bus_type_get_alignment(t);
3866 k = bus_type_get_size(t);
3867 assert(align > 0 && k > 0);
3869 r = message_peek_fields(m, ri, align, k, NULL);
3875 } else if (t == SD_BUS_TYPE_ARRAY) {
3877 r = signature_element_length(*signature+1, &l);
3887 strncpy(sig, *signature + 1, l-1);
3890 alignment = bus_type_get_alignment(sig[0]);
3894 r = message_peek_field_uint32(m, ri, &nas);
3897 if (nas > BUS_ARRAY_MAX_SIZE)
3900 r = message_peek_fields(m, ri, alignment, 0, NULL);
3904 r = message_skip_fields(m, ri, nas, (const char**) &s);
3909 (*signature) += 1 + l;
3911 } else if (t == SD_BUS_TYPE_VARIANT) {
3914 r = message_peek_field_signature(m, ri, &s);
3918 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
3924 } else if (t == SD_BUS_TYPE_STRUCT ||
3925 t == SD_BUS_TYPE_DICT_ENTRY) {
3927 r = signature_element_length(*signature, &l);
3934 strncpy(sig, *signature + 1, l-1);
3937 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
3948 int bus_message_parse_fields(sd_bus_message *m) {
3951 uint32_t unix_fds = 0;
3955 for (ri = 0; ri < BUS_MESSAGE_FIELDS_SIZE(m); ) {
3956 const char *signature;
3959 r = message_peek_fields(m, &ri, 8, 1, (void**) &header);
3963 r = message_peek_field_signature(m, &ri, &signature);
3968 case _SD_BUS_MESSAGE_HEADER_INVALID:
3971 case SD_BUS_MESSAGE_HEADER_PATH:
3976 if (!streq(signature, "o"))
3979 r = message_peek_field_string(m, object_path_is_valid, &ri, &m->path);
3982 case SD_BUS_MESSAGE_HEADER_INTERFACE:
3987 if (!streq(signature, "s"))
3990 r = message_peek_field_string(m, interface_name_is_valid, &ri, &m->interface);
3993 case SD_BUS_MESSAGE_HEADER_MEMBER:
3998 if (!streq(signature, "s"))
4001 r = message_peek_field_string(m, member_name_is_valid, &ri, &m->member);
4004 case SD_BUS_MESSAGE_HEADER_ERROR_NAME:
4009 if (!streq(signature, "s"))
4012 r = message_peek_field_string(m, error_name_is_valid, &ri, &m->error.name);
4015 case SD_BUS_MESSAGE_HEADER_DESTINATION:
4020 if (!streq(signature, "s"))
4023 r = message_peek_field_string(m, service_name_is_valid, &ri, &m->destination);
4026 case SD_BUS_MESSAGE_HEADER_SENDER:
4031 if (!streq(signature, "s"))
4034 r = message_peek_field_string(m, service_name_is_valid, &ri, &m->sender);
4038 case SD_BUS_MESSAGE_HEADER_SIGNATURE: {
4042 if (m->root_container.signature)
4045 if (!streq(signature, "g"))
4048 r = message_peek_field_signature(m, &ri, &s);
4056 free(m->root_container.signature);
4057 m->root_container.signature = c;
4061 case SD_BUS_MESSAGE_HEADER_REPLY_SERIAL:
4062 if (m->reply_serial != 0)
4065 if (!streq(signature, "u"))
4068 r = message_peek_field_uint32(m, &ri, &m->reply_serial);
4072 if (m->reply_serial == 0)
4077 case SD_BUS_MESSAGE_HEADER_UNIX_FDS:
4081 if (!streq(signature, "u"))
4084 r = message_peek_field_uint32(m, &ri, &unix_fds);
4094 r = message_skip_fields(m, &ri, (uint32_t) -1, (const char **) &signature);
4101 if (m->n_fds != unix_fds)
4104 if (isempty(m->root_container.signature) != (BUS_MESSAGE_BODY_SIZE(m) == 0))
4107 switch (m->header->type) {
4109 case SD_BUS_MESSAGE_SIGNAL:
4110 if (!m->path || !m->interface || !m->member)
4114 case SD_BUS_MESSAGE_METHOD_CALL:
4116 if (!m->path || !m->member)
4121 case SD_BUS_MESSAGE_METHOD_RETURN:
4123 if (m->reply_serial == 0)
4127 case SD_BUS_MESSAGE_METHOD_ERROR:
4129 if (m->reply_serial == 0 || !m->error.name)
4134 /* Try to read the error message, but if we can't it's a non-issue */
4135 if (m->header->type == SD_BUS_MESSAGE_METHOD_ERROR)
4136 sd_bus_message_read(m, "s", &m->error.message);
4141 int bus_message_seal(sd_bus_message *m, uint64_t serial) {
4142 struct bus_body_part *part;
4152 if (m->n_containers > 0)
4158 /* If there's a non-trivial signature set, then add it in here */
4159 if (!isempty(m->root_container.signature)) {
4160 r = message_append_field_signature(m, SD_BUS_MESSAGE_HEADER_SIGNATURE, m->root_container.signature, NULL);
4166 r = message_append_field_uint32(m, SD_BUS_MESSAGE_HEADER_UNIX_FDS, m->n_fds);
4171 /* Add padding at the end of the fields part, since we know
4172 * the body needs to start at an 8 byte alignment. We made
4173 * sure we allocated enough space for this, so all we need to
4174 * do here is to zero it out. */
4175 l = BUS_MESSAGE_FIELDS_SIZE(m);
4178 memset((uint8_t*) BUS_MESSAGE_FIELDS(m) + l, 0, a);
4180 /* If this is something we can send as memfd, then let's seal
4181 the memfd now. Note that we can send memfds as payload only
4182 for directed messages, and not for broadcasts. */
4183 if (m->destination && m->bus && m->bus->use_memfd) {
4184 MESSAGE_FOREACH_PART(part, i, m)
4185 if (part->memfd >= 0 && !part->sealed && (part->size > MEMFD_MIN_SIZE || m->bus->use_memfd < 0)) {
4186 bus_body_part_unmap(part);
4188 if (ioctl(part->memfd, KDBUS_CMD_MEMFD_SEAL_SET, 1) >= 0)
4189 part->sealed = true;
4193 m->header->serial = serial;
4199 _public_ int sd_bus_message_set_destination(sd_bus_message *m, const char *destination) {
4200 assert_return(m, -EINVAL);
4201 assert_return(destination, -EINVAL);
4202 assert_return(!m->sealed, -EPERM);
4203 assert_return(!m->destination, -EEXIST);
4205 return message_append_field_string(m, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &m->destination);
4208 int bus_message_get_blob(sd_bus_message *m, void **buffer, size_t *sz) {
4212 struct bus_body_part *part;
4218 total = BUS_MESSAGE_SIZE(m);
4224 e = mempcpy(p, m->header, BUS_MESSAGE_BODY_BEGIN(m));
4225 MESSAGE_FOREACH_PART(part, i, m)
4226 e = mempcpy(e, part->data, part->size);
4228 assert(total == (size_t) ((uint8_t*) e - (uint8_t*) p));
4236 int bus_message_read_strv_extend(sd_bus_message *m, char ***l) {
4242 r = sd_bus_message_enter_container(m, 'a', "s");
4249 r = sd_bus_message_read_basic(m, 's', &s);
4255 r = strv_extend(l, s);
4260 r = sd_bus_message_exit_container(m);
4267 _public_ int sd_bus_message_read_strv(sd_bus_message *m, char ***l) {
4271 assert_return(m, -EINVAL);
4272 assert_return(m->sealed, -EPERM);
4273 assert_return(l, -EINVAL);
4275 r = bus_message_read_strv_extend(m, &strv);
4285 const char* bus_message_get_arg(sd_bus_message *m, unsigned i) {
4287 const char *t = NULL;
4292 r = sd_bus_message_rewind(m, true);
4296 for (j = 0; j <= i; j++) {
4299 r = sd_bus_message_peek_type(m, &type, NULL);
4303 if (type != SD_BUS_TYPE_STRING &&
4304 type != SD_BUS_TYPE_OBJECT_PATH &&
4305 type != SD_BUS_TYPE_SIGNATURE)
4308 r = sd_bus_message_read_basic(m, type, &t);
4316 bool bus_header_is_complete(struct bus_header *h, size_t size) {
4322 if (size < sizeof(struct bus_header))
4325 full = sizeof(struct bus_header) +
4326 (h->endian == SD_BUS_NATIVE_ENDIAN ? h->fields_size : bswap_32(h->fields_size));
4328 return size >= full;
4331 int bus_header_message_size(struct bus_header *h, size_t *sum) {
4337 if (h->endian == SD_BUS_NATIVE_ENDIAN) {
4338 fs = h->fields_size;
4340 } else if (h->endian == SD_BUS_REVERSE_ENDIAN) {
4341 fs = bswap_32(h->fields_size);
4342 bs = bswap_32(h->body_size);
4346 *sum = sizeof(struct bus_header) + ALIGN8(fs) + bs;
4350 _public_ int sd_bus_message_get_errno(sd_bus_message *m) {
4351 assert_return(m, -EINVAL);
4353 if (m->header->type != SD_BUS_MESSAGE_METHOD_ERROR)
4356 return sd_bus_error_get_errno(&m->error);
4359 _public_ const char* sd_bus_message_get_signature(sd_bus_message *m, int complete) {
4360 struct bus_container *c;
4362 assert_return(m, NULL);
4364 c = complete ? &m->root_container : message_get_container(m);
4365 return c->signature ?: "";
4368 _public_ int sd_bus_message_copy(sd_bus_message *m, sd_bus_message *source, int all) {
4369 bool done_something = false;
4372 assert_return(m, -EINVAL);
4373 assert_return(source, -EINVAL);
4374 assert_return(!m->sealed, -EPERM);
4375 assert_return(source->sealed, -EPERM);
4378 const char *contents;
4393 r = sd_bus_message_peek_type(source, &type, &contents);
4399 done_something = true;
4401 if (bus_type_is_container(type) > 0) {
4403 r = sd_bus_message_enter_container(source, type, contents);
4407 r = sd_bus_message_open_container(m, type, contents);
4411 r = sd_bus_message_copy(m, source, true);
4415 r = sd_bus_message_close_container(m);
4419 r = sd_bus_message_exit_container(source);
4426 r = sd_bus_message_read_basic(source, type, &basic);
4432 if (type == SD_BUS_TYPE_OBJECT_PATH ||
4433 type == SD_BUS_TYPE_SIGNATURE ||
4434 type == SD_BUS_TYPE_STRING)
4435 r = sd_bus_message_append_basic(m, type, basic.string);
4437 r = sd_bus_message_append_basic(m, type, &basic);
4444 return done_something;
4447 _public_ int sd_bus_message_verify_type(sd_bus_message *m, char type, const char *contents) {
4452 assert_return(m, -EINVAL);
4453 assert_return(m->sealed, -EPERM);
4454 assert_return(!type || bus_type_is_valid(type), -EINVAL);
4455 assert_return(!contents || signature_is_valid(contents, true), -EINVAL);
4456 assert_return(type || contents, -EINVAL);
4457 assert_return(!contents || !type || bus_type_is_container(type), -EINVAL);
4459 r = sd_bus_message_peek_type(m, &t, &c);
4463 if (type != 0 && type != t)
4466 if (contents && !streq_ptr(contents, c))