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 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 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 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 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 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 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 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 sd_bus_message* sd_bus_message_ref(sd_bus_message *m) {
728 assert_return(m, NULL);
730 assert(m->n_ref > 0);
736 sd_bus_message* sd_bus_message_unref(sd_bus_message *m) {
737 assert_return(m, NULL);
739 assert(m->n_ref > 0);
748 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 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 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 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 const char *sd_bus_message_get_path(sd_bus_message *m) {
781 assert_return(m, NULL);
786 const char *sd_bus_message_get_interface(sd_bus_message *m) {
787 assert_return(m, NULL);
792 const char *sd_bus_message_get_member(sd_bus_message *m) {
793 assert_return(m, NULL);
797 const char *sd_bus_message_get_destination(sd_bus_message *m) {
798 assert_return(m, NULL);
800 return m->destination;
803 const char *sd_bus_message_get_sender(sd_bus_message *m) {
804 assert_return(m, NULL);
809 const sd_bus_error *sd_bus_message_get_error(sd_bus_message *m) {
810 assert_return(m, NULL);
811 assert_return(sd_bus_error_is_set(&m->error), NULL);
816 int sd_bus_message_get_uid(sd_bus_message *m, uid_t *uid) {
817 assert_return(m, -EINVAL);
818 assert_return(uid, -EINVAL);
819 assert_return(m->uid_valid, -ESRCH);
825 int sd_bus_message_get_gid(sd_bus_message *m, gid_t *gid) {
826 assert_return(m, -EINVAL);
827 assert_return(gid, -EINVAL);
828 assert_return(m->gid_valid, -ESRCH);
834 int sd_bus_message_get_pid(sd_bus_message *m, pid_t *pid) {
835 assert_return(m, -EINVAL);
836 assert_return(pid, -EINVAL);
837 assert_return(m->pid > 0, -ESRCH);
843 int sd_bus_message_get_tid(sd_bus_message *m, pid_t *tid) {
844 assert_return(m, -EINVAL);
845 assert_return(tid, -EINVAL);
846 assert_return(m->tid > 0, -ESRCH);
852 int sd_bus_message_get_pid_starttime(sd_bus_message *m, uint64_t *usec) {
853 assert_return(m, -EINVAL);
854 assert_return(usec, -EINVAL);
855 assert_return(m->pid_starttime > 0, -ESRCH);
857 *usec = m->pid_starttime;
861 int sd_bus_message_get_selinux_context(sd_bus_message *m, const char **ret) {
862 assert_return(m, -EINVAL);
863 assert_return(m->label, -ESRCH);
869 int sd_bus_message_get_monotonic_timestamp(sd_bus_message *m, uint64_t *usec) {
870 assert_return(m, -EINVAL);
871 assert_return(usec, -EINVAL);
872 assert_return(m->monotonic > 0, -ESRCH);
874 *usec = m->monotonic;
878 int sd_bus_message_get_realtime_timestamp(sd_bus_message *m, uint64_t *usec) {
879 assert_return(m, -EINVAL);
880 assert_return(usec, -EINVAL);
881 assert_return(m->realtime > 0, -ESRCH);
887 int sd_bus_message_get_comm(sd_bus_message *m, const char **ret) {
888 assert_return(m, -EINVAL);
889 assert_return(ret, -EINVAL);
890 assert_return(m->comm, -ESRCH);
896 int sd_bus_message_get_tid_comm(sd_bus_message *m, const char **ret) {
897 assert_return(m, -EINVAL);
898 assert_return(ret, -EINVAL);
899 assert_return(m->tid_comm, -ESRCH);
905 int sd_bus_message_get_exe(sd_bus_message *m, const char **ret) {
906 assert_return(m, -EINVAL);
907 assert_return(ret, -EINVAL);
908 assert_return(m->exe, -ESRCH);
914 int sd_bus_message_get_cgroup(sd_bus_message *m, const char **ret) {
915 assert_return(m, -EINVAL);
916 assert_return(ret, -EINVAL);
917 assert_return(m->cgroup, -ESRCH);
923 int sd_bus_message_get_unit(sd_bus_message *m, const char **ret) {
926 assert_return(m, -EINVAL);
927 assert_return(ret, -EINVAL);
928 assert_return(m->cgroup, -ESRCH);
931 r = cg_path_get_unit(m->cgroup, &m->unit);
940 int sd_bus_message_get_user_unit(sd_bus_message *m, const char **ret) {
943 assert_return(m, -EINVAL);
944 assert_return(ret, -EINVAL);
945 assert_return(m->cgroup, -ESRCH);
948 r = cg_path_get_user_unit(m->cgroup, &m->user_unit);
957 int sd_bus_message_get_session(sd_bus_message *m, const char **ret) {
960 assert_return(m, -EINVAL);
961 assert_return(ret, -EINVAL);
962 assert_return(m->cgroup, -ESRCH);
965 r = cg_path_get_session(m->cgroup, &m->session);
974 int sd_bus_message_get_owner_uid(sd_bus_message *m, uid_t *uid) {
975 assert_return(m, -EINVAL);
976 assert_return(uid, -EINVAL);
977 assert_return(m->cgroup, -ESRCH);
979 return cg_path_get_owner_uid(m->cgroup, uid);
982 int sd_bus_message_get_cmdline(sd_bus_message *m, char ***cmdline) {
987 assert_return(m, -EINVAL);
988 assert_return(m->cmdline, -ESRCH);
990 for (p = m->cmdline, n = 0; p < m->cmdline + m->cmdline_length; p++)
994 m->cmdline_array = new(char*, n + 1);
995 if (!m->cmdline_array)
998 for (p = m->cmdline, i = 0, first = true; p < m->cmdline + m->cmdline_length; p++) {
1000 m->cmdline_array[i++] = (char*) p;
1005 m->cmdline_array[i] = NULL;
1006 *cmdline = m->cmdline_array;
1011 int sd_bus_message_get_audit_sessionid(sd_bus_message *m, uint32_t *sessionid) {
1012 assert_return(m, -EINVAL);
1013 assert_return(sessionid, -EINVAL);
1014 assert_return(m->audit, -ESRCH);
1016 *sessionid = m->audit->sessionid;
1020 int sd_bus_message_get_audit_loginuid(sd_bus_message *m, uid_t *uid) {
1021 assert_return(m, -EINVAL);
1022 assert_return(uid, -EINVAL);
1023 assert_return(m->audit, -ESRCH);
1025 *uid = m->audit->loginuid;
1029 int sd_bus_message_has_effective_cap(sd_bus_message *m, int capability) {
1032 assert_return(m, -EINVAL);
1033 assert_return(capability < 0, -EINVAL);
1034 assert_return(!m->capability, -ESRCH);
1036 sz = m->capability_size / 4;
1037 if ((unsigned) capability >= sz*8)
1040 return !!(m->capability[2 * sz + (capability / 8)] & (1 << (capability % 8)));
1043 int sd_bus_message_is_signal(sd_bus_message *m, const char *interface, const char *member) {
1044 assert_return(m, -EINVAL);
1046 if (m->header->type != SD_BUS_MESSAGE_SIGNAL)
1049 if (interface && (!m->interface || !streq(m->interface, interface)))
1052 if (member && (!m->member || !streq(m->member, member)))
1058 int sd_bus_message_is_method_call(sd_bus_message *m, const char *interface, const char *member) {
1059 assert_return(m, -EINVAL);
1061 if (m->header->type != SD_BUS_MESSAGE_METHOD_CALL)
1064 if (interface && (!m->interface || !streq(m->interface, interface)))
1067 if (member && (!m->member || !streq(m->member, member)))
1073 int sd_bus_message_is_method_error(sd_bus_message *m, const char *name) {
1074 assert_return(m, -EINVAL);
1076 if (m->header->type != SD_BUS_MESSAGE_METHOD_ERROR)
1079 if (name && (!m->error.name || !streq(m->error.name, name)))
1085 int sd_bus_message_set_no_reply(sd_bus_message *m, int b) {
1086 assert_return(m, -EINVAL);
1087 assert_return(!m->sealed, -EPERM);
1088 assert_return(m->header->type == SD_BUS_MESSAGE_METHOD_CALL, -EPERM);
1091 m->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
1093 m->header->flags &= ~SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
1098 static struct bus_container *message_get_container(sd_bus_message *m) {
1101 if (m->n_containers == 0)
1102 return &m->root_container;
1104 assert(m->containers);
1105 return m->containers + m->n_containers - 1;
1108 struct bus_body_part *message_append_part(sd_bus_message *m) {
1109 struct bus_body_part *part;
1116 if (m->n_body_parts <= 0) {
1120 assert(m->body_end);
1122 part = new0(struct bus_body_part, 1);
1128 m->body_end->next = part;
1138 static void part_zero(struct bus_body_part *part, size_t sz) {
1143 /* All other fields can be left in their defaults */
1144 assert(!part->data);
1145 assert(part->memfd < 0);
1148 part->is_zero = true;
1149 part->sealed = true;
1152 static int part_make_space(
1153 struct sd_bus_message *m,
1154 struct bus_body_part *part,
1163 assert(!part->sealed);
1168 if (!part->data && part->memfd < 0)
1169 part->memfd = bus_kernel_pop_memfd(m->bus, &part->data, &part->mapped);
1171 if (part->memfd >= 0) {
1174 r = ioctl(part->memfd, KDBUS_CMD_MEMFD_SIZE_SET, &u);
1180 if (!part->data || sz > part->mapped) {
1181 size_t psz = PAGE_ALIGN(sz > 0 ? sz : 1);
1183 if (part->mapped <= 0)
1184 n = mmap(NULL, psz, PROT_READ|PROT_WRITE, MAP_SHARED, part->memfd, 0);
1186 n = mremap(part->data, part->mapped, psz, MREMAP_MAYMOVE);
1188 if (n == MAP_FAILED) {
1197 part->munmap_this = true;
1199 n = realloc(part->data, MAX(sz, 1u));
1206 part->free_this = true;
1210 *q = part->data ? (uint8_t*) part->data + part->size : NULL;
1216 static void message_extend_containers(sd_bus_message *m, size_t expand) {
1217 struct bus_container *c;
1224 /* Update counters */
1225 for (c = m->containers; c < m->containers + m->n_containers; c++)
1227 *c->array_size += expand;
1230 static void *message_extend_body(sd_bus_message *m, size_t align, size_t sz) {
1231 struct bus_body_part *part = NULL;
1232 size_t start_body, end_body, padding, start_part, end_part, added;
1244 start_body = ALIGN_TO((size_t) m->header->body_size, align);
1245 end_body = start_body + sz;
1247 padding = start_body - m->header->body_size;
1248 added = padding + sz;
1250 /* Check for 32bit overflows */
1251 if (end_body > (size_t) ((uint32_t) -1)) {
1257 m->n_body_parts <= 0 ||
1258 m->body_end->sealed ||
1259 padding != ALIGN_TO(m->body_end->size, align) - m->body_end->size;
1263 part = message_append_part(m);
1267 part_zero(part, padding);
1270 part = message_append_part(m);
1274 r = part_make_space(m, part, sz, &p);
1278 struct bus_container *c;
1286 start_part = ALIGN_TO(part->size, align);
1287 end_part = start_part + sz;
1289 r = part_make_space(m, part, end_part, &p);
1294 memset(p, 0, padding);
1295 p = (uint8_t*) p + padding;
1298 /* Readjust pointers */
1299 for (c = m->containers; c < m->containers + m->n_containers; c++)
1300 c->array_size = adjust_pointer(c->array_size, op, os, part->data);
1302 m->error.message = (const char*) adjust_pointer(m->error.message, op, os, part->data);
1305 m->header->body_size = end_body;
1306 message_extend_containers(m, added);
1311 int message_append_basic(sd_bus_message *m, char type, const void *p, const void **stored) {
1312 struct bus_container *c;
1320 assert_return(m, -EINVAL);
1321 assert_return(p, -EINVAL);
1322 assert_return(!m->sealed, -EPERM);
1323 assert_return(bus_type_is_basic(type), -EINVAL);
1324 assert_return(!m->poisoned, -ESTALE);
1326 c = message_get_container(m);
1328 if (c->signature && c->signature[c->index]) {
1329 /* Container signature is already set */
1331 if (c->signature[c->index] != type)
1336 /* Maybe we can append to the signature? But only if this is the top-level container*/
1337 if (c->enclosing != 0)
1340 e = strextend(&c->signature, CHAR_TO_STR(type), NULL);
1349 case SD_BUS_TYPE_STRING:
1350 case SD_BUS_TYPE_OBJECT_PATH:
1353 sz = 4 + strlen(p) + 1;
1356 case SD_BUS_TYPE_SIGNATURE:
1359 sz = 1 + strlen(p) + 1;
1362 case SD_BUS_TYPE_BOOLEAN:
1365 assert_cc(sizeof(int) == sizeof(uint32_t));
1371 case SD_BUS_TYPE_UNIX_FD: {
1374 if (!m->allow_fds) {
1387 fd = fcntl(z, F_DUPFD_CLOEXEC, 3);
1393 f = realloc(m->fds, sizeof(int) * (m->n_fds + 1));
1408 align = bus_type_get_alignment(type);
1409 sz = bus_type_get_size(type);
1416 a = message_extend_body(m, align, sz);
1422 if (type == SD_BUS_TYPE_STRING || type == SD_BUS_TYPE_OBJECT_PATH) {
1423 *(uint32_t*) a = sz - 5;
1424 memcpy((uint8_t*) a + 4, p, sz - 4);
1427 *stored = (const uint8_t*) a + 4;
1429 } else if (type == SD_BUS_TYPE_SIGNATURE) {
1430 *(uint8_t*) a = sz - 1;
1431 memcpy((uint8_t*) a + 1, p, sz - 1);
1434 *stored = (const uint8_t*) a + 1;
1435 } else if (type == SD_BUS_TYPE_UNIX_FD) {
1436 *(uint32_t*) a = fdi;
1450 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1457 close_nointr_nofail(fd);
1462 int sd_bus_message_append_basic(sd_bus_message *m, char type, const void *p) {
1463 return message_append_basic(m, type, p, NULL);
1466 int sd_bus_message_append_string_space(sd_bus_message *m, size_t size, char **s) {
1467 struct bus_container *c;
1470 assert_return(m, -EINVAL);
1471 assert_return(s, -EINVAL);
1472 assert_return(!m->sealed, -EPERM);
1473 assert_return(!m->poisoned, -ESTALE);
1475 c = message_get_container(m);
1477 if (c->signature && c->signature[c->index]) {
1478 /* Container signature is already set */
1480 if (c->signature[c->index] != SD_BUS_TYPE_STRING)
1485 /* Maybe we can append to the signature? But only if this is the top-level container*/
1486 if (c->enclosing != 0)
1489 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRING), NULL);
1496 a = message_extend_body(m, 4, 4 + size + 1);
1500 *(uint32_t*) a = size;
1505 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1511 static int bus_message_open_array(
1513 struct bus_container *c,
1514 const char *contents,
1515 uint32_t **array_size) {
1521 struct bus_body_part *o;
1528 if (!signature_is_single(contents, true))
1531 alignment = bus_type_get_alignment(contents[0]);
1535 if (c->signature && c->signature[c->index]) {
1537 /* Verify the existing signature */
1539 if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
1542 if (!startswith(c->signature + c->index + 1, contents))
1545 nindex = c->index + 1 + strlen(contents);
1549 if (c->enclosing != 0)
1552 /* Extend the existing signature */
1554 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_ARRAY), contents, NULL);
1560 nindex = e - c->signature;
1563 a = message_extend_body(m, 4, 4);
1568 op = m->body_end->data;
1569 os = m->body_end->size;
1571 /* Add alignment between size and first element */
1572 if (!message_extend_body(m, alignment, 0))
1575 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1578 /* location of array size might have changed so let's readjust a */
1579 if (o == m->body_end)
1580 a = adjust_pointer(a, op, os, m->body_end->data);
1587 static int bus_message_open_variant(
1589 struct bus_container *c,
1590 const char *contents) {
1599 if (!signature_is_single(contents, false))
1602 if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
1605 if (c->signature && c->signature[c->index]) {
1607 if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
1613 if (c->enclosing != 0)
1616 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_VARIANT), NULL);
1623 l = strlen(contents);
1624 a = message_extend_body(m, 1, 1 + l + 1);
1629 memcpy((uint8_t*) a + 1, contents, l + 1);
1631 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1637 static int bus_message_open_struct(
1639 struct bus_container *c,
1640 const char *contents) {
1648 if (!signature_is_valid(contents, false))
1651 if (c->signature && c->signature[c->index]) {
1654 l = strlen(contents);
1656 if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
1657 !startswith(c->signature + c->index + 1, contents) ||
1658 c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
1661 nindex = c->index + 1 + l + 1;
1665 if (c->enclosing != 0)
1668 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_BEGIN), contents, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_END), NULL);
1674 nindex = e - c->signature;
1677 /* Align contents to 8 byte boundary */
1678 if (!message_extend_body(m, 8, 0))
1681 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1687 static int bus_message_open_dict_entry(
1689 struct bus_container *c,
1690 const char *contents) {
1698 if (!signature_is_pair(contents))
1701 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1704 if (c->signature && c->signature[c->index]) {
1707 l = strlen(contents);
1709 if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
1710 !startswith(c->signature + c->index + 1, contents) ||
1711 c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
1714 nindex = c->index + 1 + l + 1;
1718 /* Align contents to 8 byte boundary */
1719 if (!message_extend_body(m, 8, 0))
1722 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1728 int sd_bus_message_open_container(
1731 const char *contents) {
1733 struct bus_container *c, *w;
1734 uint32_t *array_size = NULL;
1739 assert_return(m, -EINVAL);
1740 assert_return(!m->sealed, -EPERM);
1741 assert_return(contents, -EINVAL);
1742 assert_return(!m->poisoned, -ESTALE);
1744 /* Make sure we have space for one more container */
1745 w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
1753 c = message_get_container(m);
1755 signature = strdup(contents);
1761 /* Save old index in the parent container, in case we have to
1762 * abort this container */
1763 c->saved_index = c->index;
1764 before = m->header->body_size;
1766 if (type == SD_BUS_TYPE_ARRAY)
1767 r = bus_message_open_array(m, c, contents, &array_size);
1768 else if (type == SD_BUS_TYPE_VARIANT)
1769 r = bus_message_open_variant(m, c, contents);
1770 else if (type == SD_BUS_TYPE_STRUCT)
1771 r = bus_message_open_struct(m, c, contents);
1772 else if (type == SD_BUS_TYPE_DICT_ENTRY)
1773 r = bus_message_open_dict_entry(m, c, contents);
1782 /* OK, let's fill it in */
1783 w += m->n_containers++;
1784 w->enclosing = type;
1785 w->signature = signature;
1787 w->array_size = array_size;
1789 w->begin = m->rindex;
1794 int sd_bus_message_close_container(sd_bus_message *m) {
1795 struct bus_container *c;
1797 assert_return(m, -EINVAL);
1798 assert_return(!m->sealed, -EPERM);
1799 assert_return(m->n_containers > 0, -EINVAL);
1800 assert_return(!m->poisoned, -ESTALE);
1802 c = message_get_container(m);
1803 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1804 if (c->signature && c->signature[c->index] != 0)
1819 static int type_stack_push(TypeStack *stack, unsigned max, unsigned *i, const char *types, unsigned n_struct, unsigned n_array) {
1826 stack[*i].types = types;
1827 stack[*i].n_struct = n_struct;
1828 stack[*i].n_array = n_array;
1834 static int type_stack_pop(TypeStack *stack, unsigned max, unsigned *i, const char **types, unsigned *n_struct, unsigned *n_array) {
1845 *types = stack[*i].types;
1846 *n_struct = stack[*i].n_struct;
1847 *n_array = stack[*i].n_array;
1852 int bus_message_append_ap(
1857 unsigned n_array, n_struct;
1858 TypeStack stack[BUS_CONTAINER_DEPTH];
1859 unsigned stack_ptr = 0;
1867 n_array = (unsigned) -1;
1868 n_struct = strlen(types);
1873 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
1874 r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
1880 r = sd_bus_message_close_container(m);
1888 if (n_array != (unsigned) -1)
1897 case SD_BUS_TYPE_BYTE: {
1900 x = (uint8_t) va_arg(ap, int);
1901 r = sd_bus_message_append_basic(m, *t, &x);
1905 case SD_BUS_TYPE_BOOLEAN:
1906 case SD_BUS_TYPE_INT32:
1907 case SD_BUS_TYPE_UINT32:
1908 case SD_BUS_TYPE_UNIX_FD: {
1911 /* We assume a boolean is the same as int32_t */
1912 assert_cc(sizeof(int32_t) == sizeof(int));
1914 x = va_arg(ap, uint32_t);
1915 r = sd_bus_message_append_basic(m, *t, &x);
1919 case SD_BUS_TYPE_INT16:
1920 case SD_BUS_TYPE_UINT16: {
1923 x = (uint16_t) va_arg(ap, int);
1924 r = sd_bus_message_append_basic(m, *t, &x);
1928 case SD_BUS_TYPE_INT64:
1929 case SD_BUS_TYPE_UINT64:
1930 case SD_BUS_TYPE_DOUBLE: {
1933 x = va_arg(ap, uint64_t);
1934 r = sd_bus_message_append_basic(m, *t, &x);
1938 case SD_BUS_TYPE_STRING:
1939 case SD_BUS_TYPE_OBJECT_PATH:
1940 case SD_BUS_TYPE_SIGNATURE: {
1943 x = va_arg(ap, const char*);
1944 r = sd_bus_message_append_basic(m, *t, x);
1948 case SD_BUS_TYPE_ARRAY: {
1951 r = signature_element_length(t + 1, &k);
1957 memcpy(s, t + 1, k);
1960 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, s);
1965 if (n_array == (unsigned) -1) {
1970 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
1976 n_array = va_arg(ap, unsigned);
1981 case SD_BUS_TYPE_VARIANT: {
1984 s = va_arg(ap, const char*);
1988 r = sd_bus_message_open_container(m, SD_BUS_TYPE_VARIANT, s);
1992 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
1997 n_struct = strlen(s);
1998 n_array = (unsigned) -1;
2003 case SD_BUS_TYPE_STRUCT_BEGIN:
2004 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
2007 r = signature_element_length(t, &k);
2014 memcpy(s, t + 1, k - 2);
2017 r = sd_bus_message_open_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
2022 if (n_array == (unsigned) -1) {
2027 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2033 n_array = (unsigned) -1;
2049 int sd_bus_message_append(sd_bus_message *m, const char *types, ...) {
2053 assert_return(m, -EINVAL);
2054 assert_return(types, -EINVAL);
2055 assert_return(!m->sealed, -EPERM);
2056 assert_return(!m->poisoned, -ESTALE);
2058 va_start(ap, types);
2059 r = bus_message_append_ap(m, types, ap);
2065 int sd_bus_message_append_array_space(sd_bus_message *m, char type, size_t size, void **ptr) {
2070 assert_return(m, -EINVAL);
2071 assert_return(!m->sealed, -EPERM);
2072 assert_return(bus_type_is_trivial(type), -EINVAL);
2073 assert_return(ptr || size == 0, -EINVAL);
2074 assert_return(!m->poisoned, -ESTALE);
2076 align = bus_type_get_alignment(type);
2077 sz = bus_type_get_size(type);
2079 assert_se(align > 0);
2085 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
2089 a = message_extend_body(m, align, size);
2093 r = sd_bus_message_close_container(m);
2101 int sd_bus_message_append_array(sd_bus_message *m, char type, const void *ptr, size_t size) {
2105 assert_return(m, -EINVAL);
2106 assert_return(!m->sealed, -EPERM);
2107 assert_return(bus_type_is_trivial(type), -EINVAL);
2108 assert_return(ptr || size == 0, -EINVAL);
2109 assert_return(!m->poisoned, -ESTALE);
2111 r = sd_bus_message_append_array_space(m, type, size, &p);
2116 memcpy(p, ptr, size);
2121 int sd_bus_message_append_array_memfd(sd_bus_message *m, char type, sd_memfd *memfd) {
2122 _cleanup_close_ int copy_fd = -1;
2123 struct bus_body_part *part;
2135 if (!bus_type_is_trivial(type))
2140 r = sd_memfd_set_sealed(memfd, true);
2144 copy_fd = sd_memfd_dup_fd(memfd);
2148 r = sd_memfd_get_size(memfd, &size);
2152 align = bus_type_get_alignment(type);
2153 sz = bus_type_get_size(type);
2155 assert_se(align > 0);
2161 if (size > (uint64_t) (uint32_t) -1)
2164 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
2168 a = message_extend_body(m, align, 0);
2172 part = message_append_part(m);
2176 part->memfd = copy_fd;
2177 part->sealed = true;
2181 message_extend_containers(m, size);
2182 m->header->body_size += size;
2184 return sd_bus_message_close_container(m);
2187 int sd_bus_message_append_string_memfd(sd_bus_message *m, sd_memfd *memfd) {
2188 _cleanup_close_ int copy_fd = -1;
2189 struct bus_body_part *part;
2190 struct bus_container *c;
2195 assert_return(m, -EINVAL);
2196 assert_return(memfd, -EINVAL);
2197 assert_return(!m->sealed, -EPERM);
2198 assert_return(!m->poisoned, -ESTALE);
2200 r = sd_memfd_set_sealed(memfd, true);
2204 copy_fd = sd_memfd_dup_fd(memfd);
2208 r = sd_memfd_get_size(memfd, &size);
2212 /* We require this to be NUL terminated */
2216 if (size > (uint64_t) (uint32_t) -1)
2219 c = message_get_container(m);
2220 if (c->signature && c->signature[c->index]) {
2221 /* Container signature is already set */
2223 if (c->signature[c->index] != SD_BUS_TYPE_STRING)
2228 /* Maybe we can append to the signature? But only if this is the top-level container*/
2229 if (c->enclosing != 0)
2232 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRING), NULL);
2239 a = message_extend_body(m, 4, 4);
2243 *(uint32_t*) a = size - 1;
2245 part = message_append_part(m);
2249 part->memfd = copy_fd;
2250 part->sealed = true;
2254 message_extend_containers(m, size);
2255 m->header->body_size += size;
2257 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2263 int sd_bus_message_append_strv(sd_bus_message *m, char **l) {
2267 assert_return(m, -EINVAL);
2268 assert_return(!m->sealed, -EPERM);
2269 assert_return(!m->poisoned, -ESTALE);
2271 r = sd_bus_message_open_container(m, 'a', "s");
2275 STRV_FOREACH(i, l) {
2276 r = sd_bus_message_append_basic(m, 's', *i);
2281 return sd_bus_message_close_container(m);
2284 int bus_body_part_map(struct bus_body_part *part) {
2293 if (part->size <= 0)
2296 /* For smaller zero parts (as used for padding) we don't need to map anything... */
2297 if (part->memfd < 0 && part->is_zero && part->size < 8) {
2298 static const uint8_t zeroes[7] = { };
2299 part->data = (void*) zeroes;
2303 psz = PAGE_ALIGN(part->size);
2305 if (part->memfd >= 0)
2306 p = mmap(NULL, psz, PROT_READ, MAP_SHARED, part->memfd, 0);
2307 else if (part->is_zero)
2308 p = mmap(NULL, psz, PROT_READ, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
2312 if (p == MAP_FAILED)
2317 part->munmap_this = true;
2322 void bus_body_part_unmap(struct bus_body_part *part) {
2326 if (part->memfd < 0)
2332 if (!part->munmap_this)
2335 assert_se(munmap(part->data, part->mapped) == 0);
2339 part->munmap_this = false;
2344 static int buffer_peek(const void *p, uint32_t sz, size_t *rindex, size_t align, size_t nbytes, void **r) {
2345 size_t k, start, end;
2350 start = ALIGN_TO((size_t) *rindex, align);
2351 end = start + nbytes;
2356 /* Verify that padding is 0 */
2357 for (k = *rindex; k < start; k++)
2358 if (((const uint8_t*) p)[k] != 0)
2362 *r = (uint8_t*) p + start;
2369 static bool message_end_of_signature(sd_bus_message *m) {
2370 struct bus_container *c;
2374 c = message_get_container(m);
2375 return !c->signature || c->signature[c->index] == 0;
2378 static bool message_end_of_array(sd_bus_message *m, size_t index) {
2379 struct bus_container *c;
2383 c = message_get_container(m);
2387 return index >= c->begin + BUS_MESSAGE_BSWAP32(m, *c->array_size);
2390 int sd_bus_message_at_end(sd_bus_message *m, int complete) {
2391 assert_return(m, -EINVAL);
2392 assert_return(m->sealed, -EPERM);
2394 if (complete && m->n_containers > 0)
2397 if (message_end_of_signature(m))
2400 if (message_end_of_array(m, m->rindex))
2406 static struct bus_body_part* find_part(sd_bus_message *m, size_t index, size_t sz, void **p) {
2407 struct bus_body_part *part;
2413 if (m->cached_rindex_part && index >= m->cached_rindex_part_begin) {
2414 part = m->cached_rindex_part;
2415 begin = m->cached_rindex_part_begin;
2425 if (index + sz <= begin + part->size) {
2427 r = bus_body_part_map(part);
2432 *p = (uint8_t*) part->data + index - begin;
2434 m->cached_rindex_part = part;
2435 m->cached_rindex_part_begin = begin;
2440 begin += part->size;
2447 static int message_peek_body(
2454 size_t k, start, end, padding;
2455 struct bus_body_part *part;
2462 if (message_end_of_array(m, *rindex))
2465 start = ALIGN_TO((size_t) *rindex, align);
2466 padding = start - *rindex;
2467 end = start + nbytes;
2469 if (end > BUS_MESSAGE_BODY_SIZE(m))
2472 part = find_part(m, *rindex, padding, (void**) &q);
2477 /* Verify padding */
2478 for (k = 0; k < padding; k++)
2483 part = find_part(m, start, nbytes, (void**) &q);
2495 static bool validate_nul(const char *s, size_t l) {
2497 /* Check for NUL chars in the string */
2498 if (memchr(s, 0, l))
2501 /* Check for NUL termination */
2508 static bool validate_string(const char *s, size_t l) {
2510 if (!validate_nul(s, l))
2513 /* Check if valid UTF8 */
2514 if (!utf8_is_valid(s))
2520 static bool validate_signature(const char *s, size_t l) {
2522 if (!validate_nul(s, l))
2525 /* Check if valid signature */
2526 if (!signature_is_valid(s, true))
2532 static bool validate_object_path(const char *s, size_t l) {
2534 if (!validate_nul(s, l))
2537 if (!object_path_is_valid(s))
2543 int sd_bus_message_read_basic(sd_bus_message *m, char type, void *p) {
2544 struct bus_container *c;
2548 assert_return(m, -EINVAL);
2549 assert_return(m->sealed, -EPERM);
2550 assert_return(bus_type_is_basic(type), -EINVAL);
2552 if (message_end_of_signature(m))
2555 if (message_end_of_array(m, m->rindex))
2558 c = message_get_container(m);
2559 if (c->signature[c->index] != type)
2564 case SD_BUS_TYPE_STRING:
2565 case SD_BUS_TYPE_OBJECT_PATH: {
2570 r = message_peek_body(m, &rindex, 4, 4, &q);
2574 l = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2575 r = message_peek_body(m, &rindex, 1, l+1, &q);
2581 if (type == SD_BUS_TYPE_OBJECT_PATH) {
2582 if (!validate_object_path(q, l))
2585 if (!validate_string(q, l))
2591 *(const char**) p = q;
2596 case SD_BUS_TYPE_SIGNATURE: {
2601 r = message_peek_body(m, &rindex, 1, 1, &q);
2606 r = message_peek_body(m, &rindex, 1, l+1, &q);
2612 if (!validate_signature(q, l))
2618 *(const char**) p = q;
2626 align = bus_type_get_alignment(type);
2627 sz = bus_type_get_size(type);
2628 assert(align > 0 && sz > 0);
2631 r = message_peek_body(m, &rindex, align, sz, &q);
2637 case SD_BUS_TYPE_BYTE:
2639 *(uint8_t*) p = *(uint8_t*) q;
2642 case SD_BUS_TYPE_BOOLEAN:
2644 *(unsigned*) p = !!*(uint32_t*) q;
2647 case SD_BUS_TYPE_INT16:
2648 case SD_BUS_TYPE_UINT16:
2650 *(uint16_t*) p = BUS_MESSAGE_BSWAP16(m, *(uint16_t*) q);
2653 case SD_BUS_TYPE_INT32:
2654 case SD_BUS_TYPE_UINT32:
2656 *(uint32_t*) p = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2659 case SD_BUS_TYPE_INT64:
2660 case SD_BUS_TYPE_UINT64:
2661 case SD_BUS_TYPE_DOUBLE:
2663 *(uint64_t*) p = BUS_MESSAGE_BSWAP64(m, *(uint64_t*) q);
2666 case SD_BUS_TYPE_UNIX_FD: {
2669 j = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2674 *(int*) p = m->fds[j];
2679 assert_not_reached("Unknown basic type...");
2688 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2694 static int bus_message_enter_array(
2696 struct bus_container *c,
2697 const char *contents,
2698 uint32_t **array_size) {
2709 if (!signature_is_single(contents, true))
2712 alignment = bus_type_get_alignment(contents[0]);
2716 if (!c->signature || c->signature[c->index] == 0)
2719 if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
2722 if (!startswith(c->signature + c->index + 1, contents))
2726 r = message_peek_body(m, &rindex, 4, 4, &q);
2730 if (BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q) > BUS_ARRAY_MAX_SIZE)
2733 r = message_peek_body(m, &rindex, alignment, 0, NULL);
2739 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2740 c->index += 1 + strlen(contents);
2744 *array_size = (uint32_t*) q;
2749 static int bus_message_enter_variant(
2751 struct bus_container *c,
2752 const char *contents) {
2763 if (!signature_is_single(contents, false))
2766 if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
2769 if (!c->signature || c->signature[c->index] == 0)
2772 if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
2776 r = message_peek_body(m, &rindex, 1, 1, &q);
2781 r = message_peek_body(m, &rindex, 1, l+1, &q);
2787 if (!validate_signature(q, l))
2790 if (!streq(q, contents))
2793 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2801 static int bus_message_enter_struct(
2803 struct bus_container *c,
2804 const char *contents) {
2813 if (!signature_is_valid(contents, false))
2816 if (!c->signature || c->signature[c->index] == 0)
2819 l = strlen(contents);
2821 if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
2822 !startswith(c->signature + c->index + 1, contents) ||
2823 c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
2826 r = message_peek_body(m, &m->rindex, 8, 0, NULL);
2830 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2831 c->index += 1 + l + 1;
2836 static int bus_message_enter_dict_entry(
2838 struct bus_container *c,
2839 const char *contents) {
2848 if (!signature_is_pair(contents))
2851 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2854 if (!c->signature || c->signature[c->index] == 0)
2857 l = strlen(contents);
2859 if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
2860 !startswith(c->signature + c->index + 1, contents) ||
2861 c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
2864 r = message_peek_body(m, &m->rindex, 8, 0, NULL);
2868 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2869 c->index += 1 + l + 1;
2874 int sd_bus_message_enter_container(sd_bus_message *m, char type, const char *contents) {
2875 struct bus_container *c, *w;
2876 uint32_t *array_size = NULL;
2881 assert_return(m, -EINVAL);
2882 assert_return(m->sealed, -EPERM);
2883 assert_return(type != 0 || !contents, -EINVAL);
2885 if (type == 0 || !contents) {
2889 /* Allow entering into anonymous containers */
2890 r = sd_bus_message_peek_type(m, &tt, &cc);
2894 if (type != 0 && type != tt)
2897 if (contents && !streq(contents, cc))
2905 * We enforce a global limit on container depth, that is much
2906 * higher than the 32 structs and 32 arrays the specification
2907 * mandates. This is simpler to implement for us, and we need
2908 * this only to ensure our container array doesn't grow
2909 * without bounds. We are happy to return any data from a
2910 * message as long as the data itself is valid, even if the
2911 * overall message might be not.
2913 * Note that the message signature is validated when
2914 * parsing the headers, and that validation does check the
2917 * Note that the specification defines no limits on the depth
2918 * of stacked variants, but we do.
2920 if (m->n_containers >= BUS_CONTAINER_DEPTH)
2923 w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
2928 if (message_end_of_signature(m))
2931 if (message_end_of_array(m, m->rindex))
2934 c = message_get_container(m);
2936 signature = strdup(contents);
2940 c->saved_index = c->index;
2943 if (type == SD_BUS_TYPE_ARRAY)
2944 r = bus_message_enter_array(m, c, contents, &array_size);
2945 else if (type == SD_BUS_TYPE_VARIANT)
2946 r = bus_message_enter_variant(m, c, contents);
2947 else if (type == SD_BUS_TYPE_STRUCT)
2948 r = bus_message_enter_struct(m, c, contents);
2949 else if (type == SD_BUS_TYPE_DICT_ENTRY)
2950 r = bus_message_enter_dict_entry(m, c, contents);
2959 /* OK, let's fill it in */
2960 w += m->n_containers++;
2961 w->enclosing = type;
2962 w->signature = signature;
2964 w->array_size = array_size;
2966 w->begin = m->rindex;
2971 int sd_bus_message_exit_container(sd_bus_message *m) {
2972 struct bus_container *c;
2974 assert_return(m, -EINVAL);
2975 assert_return(m->sealed, -EPERM);
2976 assert_return(m->n_containers > 0, -EINVAL);
2978 c = message_get_container(m);
2979 if (c->enclosing == SD_BUS_TYPE_ARRAY) {
2982 l = BUS_MESSAGE_BSWAP32(m, *c->array_size);
2983 if (c->begin + l != m->rindex)
2987 if (c->signature && c->signature[c->index] != 0)
2997 static void message_quit_container(sd_bus_message *m) {
2998 struct bus_container *c;
3002 assert(m->n_containers > 0);
3004 c = message_get_container(m);
3007 assert(m->rindex >= c->before);
3008 m->rindex = c->before;
3010 /* Free container */
3014 /* Correct index of new top-level container */
3015 c = message_get_container(m);
3016 c->index = c->saved_index;
3019 int sd_bus_message_peek_type(sd_bus_message *m, char *type, const char **contents) {
3020 struct bus_container *c;
3023 assert_return(m, -EINVAL);
3024 assert_return(m->sealed, -EPERM);
3026 if (message_end_of_signature(m))
3029 if (message_end_of_array(m, m->rindex))
3032 c = message_get_container(m);
3034 if (bus_type_is_basic(c->signature[c->index])) {
3038 *type = c->signature[c->index];
3042 if (c->signature[c->index] == SD_BUS_TYPE_ARRAY) {
3048 r = signature_element_length(c->signature+c->index+1, &l);
3054 sig = strndup(c->signature + c->index + 1, l);
3058 free(m->peeked_signature);
3059 m->peeked_signature = sig;
3065 *type = SD_BUS_TYPE_ARRAY;
3070 if (c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ||
3071 c->signature[c->index] == SD_BUS_TYPE_DICT_ENTRY_BEGIN) {
3077 r = signature_element_length(c->signature+c->index, &l);
3082 sig = strndup(c->signature + c->index + 1, l - 2);
3086 free(m->peeked_signature);
3087 m->peeked_signature = sig;
3093 *type = c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY;
3098 if (c->signature[c->index] == SD_BUS_TYPE_VARIANT) {
3104 r = message_peek_body(m, &rindex, 1, 1, &q);
3111 r = message_peek_body(m, &rindex, 1, l+1, &q);
3117 if (!validate_signature(q, l))
3124 *type = SD_BUS_TYPE_VARIANT;
3139 int sd_bus_message_rewind(sd_bus_message *m, int complete) {
3140 struct bus_container *c;
3142 assert_return(m, -EINVAL);
3143 assert_return(m->sealed, -EPERM);
3146 message_reset_containers(m);
3148 m->root_container.index = 0;
3150 c = message_get_container(m);
3152 c = message_get_container(m);
3155 m->rindex = c->begin;
3158 return !isempty(c->signature);
3160 static int message_read_ap(
3165 unsigned n_array, n_struct;
3166 TypeStack stack[BUS_CONTAINER_DEPTH];
3167 unsigned stack_ptr = 0;
3168 unsigned n_loop = 0;
3176 /* Ideally, we'd just call ourselves recursively on every
3177 * complex type. However, the state of a va_list that is
3178 * passed to a function is undefined after that function
3179 * returns. This means we need to docode the va_list linearly
3180 * in a single stackframe. We hence implement our own
3181 * home-grown stack in an array. */
3183 n_array = (unsigned) -1; /* lenght of current array entries */
3184 n_struct = strlen(types); /* length of current struct contents signature */
3191 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
3192 r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
3198 r = sd_bus_message_exit_container(m);
3206 if (n_array != (unsigned) -1)
3215 case SD_BUS_TYPE_BYTE:
3216 case SD_BUS_TYPE_BOOLEAN:
3217 case SD_BUS_TYPE_INT16:
3218 case SD_BUS_TYPE_UINT16:
3219 case SD_BUS_TYPE_INT32:
3220 case SD_BUS_TYPE_UINT32:
3221 case SD_BUS_TYPE_INT64:
3222 case SD_BUS_TYPE_UINT64:
3223 case SD_BUS_TYPE_DOUBLE:
3224 case SD_BUS_TYPE_STRING:
3225 case SD_BUS_TYPE_OBJECT_PATH:
3226 case SD_BUS_TYPE_SIGNATURE:
3227 case SD_BUS_TYPE_UNIX_FD: {
3230 p = va_arg(ap, void*);
3231 r = sd_bus_message_read_basic(m, *t, p);
3244 case SD_BUS_TYPE_ARRAY: {
3247 r = signature_element_length(t + 1, &k);
3253 memcpy(s, t + 1, k);
3256 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, s);
3267 if (n_array == (unsigned) -1) {
3272 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
3278 n_array = va_arg(ap, unsigned);
3283 case SD_BUS_TYPE_VARIANT: {
3286 s = va_arg(ap, const char *);
3290 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, s);
3300 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
3305 n_struct = strlen(s);
3306 n_array = (unsigned) -1;
3311 case SD_BUS_TYPE_STRUCT_BEGIN:
3312 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
3315 r = signature_element_length(t, &k);
3321 memcpy(s, t + 1, k - 2);
3324 r = sd_bus_message_enter_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
3334 if (n_array == (unsigned) -1) {
3339 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
3345 n_array = (unsigned) -1;
3358 int sd_bus_message_read(sd_bus_message *m, const char *types, ...) {
3362 assert_return(m, -EINVAL);
3363 assert_return(m->sealed, -EPERM);
3364 assert_return(types, -EINVAL);
3366 va_start(ap, types);
3367 r = message_read_ap(m, types, ap);
3373 int sd_bus_message_skip(sd_bus_message *m, const char *types) {
3376 assert_return(m, -EINVAL);
3377 assert_return(m->sealed, -EPERM);
3378 assert_return(types, -EINVAL);
3385 case SD_BUS_TYPE_BYTE:
3386 case SD_BUS_TYPE_BOOLEAN:
3387 case SD_BUS_TYPE_INT16:
3388 case SD_BUS_TYPE_UINT16:
3389 case SD_BUS_TYPE_INT32:
3390 case SD_BUS_TYPE_UINT32:
3391 case SD_BUS_TYPE_INT64:
3392 case SD_BUS_TYPE_UINT64:
3393 case SD_BUS_TYPE_DOUBLE:
3394 case SD_BUS_TYPE_STRING:
3395 case SD_BUS_TYPE_OBJECT_PATH:
3396 case SD_BUS_TYPE_SIGNATURE:
3397 case SD_BUS_TYPE_UNIX_FD:
3399 r = sd_bus_message_read_basic(m, *types, NULL);
3403 r = sd_bus_message_skip(m, types + 1);
3409 case SD_BUS_TYPE_ARRAY: {
3412 r = signature_element_length(types + 1, &k);
3418 memcpy(s, types+1, k);
3421 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, s);
3426 r = sd_bus_message_skip(m, s);
3433 r = sd_bus_message_exit_container(m);
3438 r = sd_bus_message_skip(m, types + 1 + k);
3445 case SD_BUS_TYPE_VARIANT: {
3446 const char *contents;
3449 r = sd_bus_message_peek_type(m, &x, &contents);
3453 if (x != SD_BUS_TYPE_VARIANT)
3456 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, contents);
3460 r = sd_bus_message_skip(m, contents);
3465 r = sd_bus_message_exit_container(m);
3469 r = sd_bus_message_skip(m, types + 1);
3476 case SD_BUS_TYPE_STRUCT_BEGIN:
3477 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
3480 r = signature_element_length(types, &k);
3486 memcpy(s, types+1, k-2);
3489 r = sd_bus_message_enter_container(m, *types == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
3493 r = sd_bus_message_skip(m, s);
3498 r = sd_bus_message_exit_container(m);
3503 r = sd_bus_message_skip(m, types + k);
3515 int sd_bus_message_read_array(sd_bus_message *m, char type, const void **ptr, size_t *size) {
3516 struct bus_container *c;
3522 assert_return(m, -EINVAL);
3523 assert_return(m->sealed, -EPERM);
3524 assert_return(bus_type_is_trivial(type), -EINVAL);
3525 assert_return(ptr, -EINVAL);
3526 assert_return(size, -EINVAL);
3527 assert_return(!BUS_MESSAGE_NEED_BSWAP(m), -ENOTSUP);
3529 align = bus_type_get_alignment(type);
3533 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
3537 c = message_get_container(m);
3538 sz = BUS_MESSAGE_BSWAP32(m, *c->array_size);
3540 r = message_peek_body(m, &m->rindex, align, sz, &p);
3548 r = sd_bus_message_exit_container(m);
3552 *ptr = (const void*) p;
3558 message_quit_container(m);
3562 static int message_peek_fields(
3573 return buffer_peek(BUS_MESSAGE_FIELDS(m), BUS_MESSAGE_FIELDS_SIZE(m), rindex, align, nbytes, ret);
3576 static int message_peek_field_uint32(
3587 r = message_peek_fields(m, ri, 4, 4, &q);
3592 *ret = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
3597 static int message_peek_field_string(
3599 bool (*validate)(const char *p),
3610 r = message_peek_field_uint32(m, ri, &l);
3614 r = message_peek_fields(m, ri, 1, l+1, &q);
3619 if (!validate_nul(q, l))
3625 if (!validate_string(q, l))
3635 static int message_peek_field_signature(
3647 r = message_peek_fields(m, ri, 1, 1, &q);
3652 r = message_peek_fields(m, ri, 1, l+1, &q);
3656 if (!validate_signature(q, l))
3665 static int message_skip_fields(
3668 uint32_t array_size,
3669 const char **signature) {
3671 size_t original_index;
3678 original_index = *ri;
3684 if (array_size != (uint32_t) -1 &&
3685 array_size <= *ri - original_index)
3692 if (t == SD_BUS_TYPE_STRING) {
3694 r = message_peek_field_string(m, NULL, ri, NULL);
3700 } else if (t == SD_BUS_TYPE_OBJECT_PATH) {
3702 r = message_peek_field_string(m, object_path_is_valid, ri, NULL);
3708 } else if (t == SD_BUS_TYPE_SIGNATURE) {
3710 r = message_peek_field_signature(m, ri, NULL);
3716 } else if (bus_type_is_basic(t)) {
3719 align = bus_type_get_alignment(t);
3720 k = bus_type_get_size(t);
3721 assert(align > 0 && k > 0);
3723 r = message_peek_fields(m, ri, align, k, NULL);
3729 } else if (t == SD_BUS_TYPE_ARRAY) {
3731 r = signature_element_length(*signature+1, &l);
3741 strncpy(sig, *signature + 1, l-1);
3744 alignment = bus_type_get_alignment(sig[0]);
3748 r = message_peek_field_uint32(m, ri, &nas);
3751 if (nas > BUS_ARRAY_MAX_SIZE)
3754 r = message_peek_fields(m, ri, alignment, 0, NULL);
3758 r = message_skip_fields(m, ri, nas, (const char**) &s);
3763 (*signature) += 1 + l;
3765 } else if (t == SD_BUS_TYPE_VARIANT) {
3768 r = message_peek_field_signature(m, ri, &s);
3772 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
3778 } else if (t == SD_BUS_TYPE_STRUCT ||
3779 t == SD_BUS_TYPE_DICT_ENTRY) {
3781 r = signature_element_length(*signature, &l);
3788 strncpy(sig, *signature + 1, l-1);
3791 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
3802 int bus_message_parse_fields(sd_bus_message *m) {
3805 uint32_t unix_fds = 0;
3809 for (ri = 0; ri < BUS_MESSAGE_FIELDS_SIZE(m); ) {
3810 const char *signature;
3813 r = message_peek_fields(m, &ri, 8, 1, (void**) &header);
3817 r = message_peek_field_signature(m, &ri, &signature);
3822 case _SD_BUS_MESSAGE_HEADER_INVALID:
3825 case SD_BUS_MESSAGE_HEADER_PATH:
3830 if (!streq(signature, "o"))
3833 r = message_peek_field_string(m, object_path_is_valid, &ri, &m->path);
3836 case SD_BUS_MESSAGE_HEADER_INTERFACE:
3841 if (!streq(signature, "s"))
3844 r = message_peek_field_string(m, interface_name_is_valid, &ri, &m->interface);
3847 case SD_BUS_MESSAGE_HEADER_MEMBER:
3852 if (!streq(signature, "s"))
3855 r = message_peek_field_string(m, member_name_is_valid, &ri, &m->member);
3858 case SD_BUS_MESSAGE_HEADER_ERROR_NAME:
3863 if (!streq(signature, "s"))
3866 r = message_peek_field_string(m, error_name_is_valid, &ri, &m->error.name);
3869 case SD_BUS_MESSAGE_HEADER_DESTINATION:
3874 if (!streq(signature, "s"))
3877 r = message_peek_field_string(m, service_name_is_valid, &ri, &m->destination);
3880 case SD_BUS_MESSAGE_HEADER_SENDER:
3885 if (!streq(signature, "s"))
3888 r = message_peek_field_string(m, service_name_is_valid, &ri, &m->sender);
3892 case SD_BUS_MESSAGE_HEADER_SIGNATURE: {
3896 if (m->root_container.signature)
3899 if (!streq(signature, "g"))
3902 r = message_peek_field_signature(m, &ri, &s);
3910 free(m->root_container.signature);
3911 m->root_container.signature = c;
3915 case SD_BUS_MESSAGE_HEADER_REPLY_SERIAL:
3916 if (m->reply_serial != 0)
3919 if (!streq(signature, "u"))
3922 r = message_peek_field_uint32(m, &ri, &m->reply_serial);
3926 if (m->reply_serial == 0)
3931 case SD_BUS_MESSAGE_HEADER_UNIX_FDS:
3935 if (!streq(signature, "u"))
3938 r = message_peek_field_uint32(m, &ri, &unix_fds);
3948 r = message_skip_fields(m, &ri, (uint32_t) -1, (const char **) &signature);
3955 if (m->n_fds != unix_fds)
3958 if (isempty(m->root_container.signature) != (BUS_MESSAGE_BODY_SIZE(m) == 0))
3961 switch (m->header->type) {
3963 case SD_BUS_MESSAGE_SIGNAL:
3964 if (!m->path || !m->interface || !m->member)
3968 case SD_BUS_MESSAGE_METHOD_CALL:
3970 if (!m->path || !m->member)
3975 case SD_BUS_MESSAGE_METHOD_RETURN:
3977 if (m->reply_serial == 0)
3981 case SD_BUS_MESSAGE_METHOD_ERROR:
3983 if (m->reply_serial == 0 || !m->error.name)
3988 /* Try to read the error message, but if we can't it's a non-issue */
3989 if (m->header->type == SD_BUS_MESSAGE_METHOD_ERROR)
3990 sd_bus_message_read(m, "s", &m->error.message);
3995 int bus_message_seal(sd_bus_message *m, uint64_t serial) {
3996 struct bus_body_part *part;
4006 if (m->n_containers > 0)
4012 /* If there's a non-trivial signature set, then add it in here */
4013 if (!isempty(m->root_container.signature)) {
4014 r = message_append_field_signature(m, SD_BUS_MESSAGE_HEADER_SIGNATURE, m->root_container.signature, NULL);
4020 r = message_append_field_uint32(m, SD_BUS_MESSAGE_HEADER_UNIX_FDS, m->n_fds);
4025 /* Add padding at the end of the fields part, since we know
4026 * the body needs to start at an 8 byte alignment. We made
4027 * sure we allocated enough space for this, so all we need to
4028 * do here is to zero it out. */
4029 l = BUS_MESSAGE_FIELDS_SIZE(m);
4032 memset((uint8_t*) BUS_MESSAGE_FIELDS(m) + l, 0, a);
4034 /* If this is something we can send as memfd, then let's seal
4035 the memfd now. Note that we can send memfds as payload only
4036 for directed messages, and not for broadcasts. */
4037 if (m->destination && m->bus && m->bus->use_memfd) {
4038 MESSAGE_FOREACH_PART(part, i, m)
4039 if (part->memfd >= 0 && !part->sealed && (part->size > MEMFD_MIN_SIZE || m->bus->use_memfd < 0)) {
4040 bus_body_part_unmap(part);
4042 if (ioctl(part->memfd, KDBUS_CMD_MEMFD_SEAL_SET, 1) >= 0)
4043 part->sealed = true;
4047 m->header->serial = serial;
4053 int sd_bus_message_set_destination(sd_bus_message *m, const char *destination) {
4054 assert_return(m, -EINVAL);
4055 assert_return(destination, -EINVAL);
4056 assert_return(!m->sealed, -EPERM);
4057 assert_return(!m->destination, -EEXIST);
4059 return message_append_field_string(m, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &m->destination);
4062 int bus_message_dump(sd_bus_message *m, FILE *f, bool with_header) {
4063 const char *u = NULL, *uu = NULL, *s = NULL;
4064 char **cmdline = NULL;
4067 uid_t owner, audit_loginuid;
4068 uint32_t audit_sessionid;
4084 "\tfields_size=%u\n"
4089 "\tdestination=%s\n"
4092 "\treply_serial=%u\n"
4094 "\tn_body_parts=%u\n",
4101 BUS_MESSAGE_SERIAL(m),
4102 BUS_MESSAGE_FIELDS_SIZE(m),
4103 BUS_MESSAGE_BODY_SIZE(m),
4105 strna(m->interface),
4107 strna(m->destination),
4109 strna(m->root_container.signature),
4114 if (sd_bus_error_is_set(&m->error))
4117 "\terror.message=%s\n",
4118 strna(m->error.name),
4119 strna(m->error.message));
4122 fprintf(f, "\tpid=%lu\n", (unsigned long) m->pid);
4124 fprintf(f, "\ttid=%lu\n", (unsigned long) m->tid);
4126 fprintf(f, "\tuid=%lu\n", (unsigned long) m->uid);
4128 fprintf(f, "\tgid=%lu\n", (unsigned long) m->gid);
4129 if (m->pid_starttime != 0)
4130 fprintf(f, "\tpid_starttime=%llu\n", (unsigned long long) m->pid_starttime);
4131 if (m->monotonic != 0)
4132 fprintf(f, "\tmonotonic=%llu\n", (unsigned long long) m->monotonic);
4133 if (m->realtime != 0)
4134 fprintf(f, "\trealtime=%llu\n", (unsigned long long) m->realtime);
4136 fprintf(f, "\texe=[%s]\n", m->exe);
4138 fprintf(f, "\tcomm=[%s]\n", m->comm);
4140 fprintf(f, "\ttid_comm=[%s]\n", m->tid_comm);
4142 fprintf(f, "\tlabel=[%s]\n", m->label);
4144 fprintf(f, "\tcgroup=[%s]\n", m->cgroup);
4146 sd_bus_message_get_unit(m, &u);
4148 fprintf(f, "\tunit=[%s]\n", u);
4149 sd_bus_message_get_user_unit(m, &uu);
4151 fprintf(f, "\tuser_unit=[%s]\n", uu);
4152 sd_bus_message_get_session(m, &s);
4154 fprintf(f, "\tsession=[%s]\n", s);
4155 if (sd_bus_message_get_owner_uid(m, &owner) >= 0)
4156 fprintf(f, "\towner_uid=%lu\n", (unsigned long) owner);
4157 if (sd_bus_message_get_audit_loginuid(m, &audit_loginuid) >= 0)
4158 fprintf(f, "\taudit_loginuid=%lu\n", (unsigned long) audit_loginuid);
4159 if (sd_bus_message_get_audit_sessionid(m, &audit_sessionid) >= 0)
4160 fprintf(f, "\taudit_sessionid=%lu\n", (unsigned long) audit_sessionid);
4162 r = sd_bus_message_has_effective_cap(m, 5);
4164 fprintf(f, "\tCAP_KILL=%s\n", yes_no(r));
4166 if (sd_bus_message_get_cmdline(m, &cmdline) >= 0) {
4169 fputs("\tcmdline=[", f);
4170 STRV_FOREACH(c, cmdline) {
4181 r = sd_bus_message_rewind(m, true);
4183 log_error("Failed to rewind: %s", strerror(-r));
4187 fprintf(f, "BEGIN_MESSAGE \"%s\" {\n", strempty(m->root_container.signature));
4190 _cleanup_free_ char *prefix = NULL;
4191 const char *contents = NULL;
4206 r = sd_bus_message_peek_type(m, &type, &contents);
4208 log_error("Failed to peek type: %s", strerror(-r));
4215 r = sd_bus_message_exit_container(m);
4217 log_error("Failed to exit container: %s", strerror(-r));
4223 prefix = strrep("\t", level);
4227 if (type == SD_BUS_TYPE_ARRAY)
4228 fprintf(f, "%s} END_ARRAY \n", prefix);
4229 else if (type == SD_BUS_TYPE_VARIANT)
4230 fprintf(f, "%s} END_VARIANT\n", prefix);
4231 else if (type == SD_BUS_TYPE_STRUCT)
4232 fprintf(f, "%s} END_STRUCT\n", prefix);
4233 else if (type == SD_BUS_TYPE_DICT_ENTRY)
4234 fprintf(f, "%s} END_DICT_ENTRY\n", prefix);
4239 prefix = strrep("\t", level);
4243 if (bus_type_is_container(type) > 0) {
4244 r = sd_bus_message_enter_container(m, type, contents);
4246 log_error("Failed to enter container: %s", strerror(-r));
4250 if (type == SD_BUS_TYPE_ARRAY)
4251 fprintf(f, "%sBEGIN_ARRAY \"%s\" {\n", prefix, contents);
4252 else if (type == SD_BUS_TYPE_VARIANT)
4253 fprintf(f, "%sBEGIN_VARIANT \"%s\" {\n", prefix, contents);
4254 else if (type == SD_BUS_TYPE_STRUCT)
4255 fprintf(f, "%sBEGIN_STRUCT \"%s\" {\n", prefix, contents);
4256 else if (type == SD_BUS_TYPE_DICT_ENTRY)
4257 fprintf(f, "%sBEGIN_DICT_ENTRY \"%s\" {\n", prefix, contents);
4264 r = sd_bus_message_read_basic(m, type, &basic);
4266 log_error("Failed to get basic: %s", strerror(-r));
4274 case SD_BUS_TYPE_BYTE:
4275 fprintf(f, "%sBYTE: %u\n", prefix, basic.u8);
4278 case SD_BUS_TYPE_BOOLEAN:
4279 fprintf(f, "%sBOOLEAN: %s\n", prefix, yes_no(basic.i));
4282 case SD_BUS_TYPE_INT16:
4283 fprintf(f, "%sINT16: %i\n", prefix, basic.s16);
4286 case SD_BUS_TYPE_UINT16:
4287 fprintf(f, "%sUINT16: %u\n", prefix, basic.u16);
4290 case SD_BUS_TYPE_INT32:
4291 fprintf(f, "%sINT32: %i\n", prefix, basic.s32);
4294 case SD_BUS_TYPE_UINT32:
4295 fprintf(f, "%sUINT32: %u\n", prefix, basic.u32);
4298 case SD_BUS_TYPE_INT64:
4299 fprintf(f, "%sINT64: %lli\n", prefix, (long long) basic.s64);
4302 case SD_BUS_TYPE_UINT64:
4303 fprintf(f, "%sUINT64: %llu\n", prefix, (unsigned long long) basic.u64);
4306 case SD_BUS_TYPE_DOUBLE:
4307 fprintf(f, "%sDOUBLE: %g\n", prefix, basic.d64);
4310 case SD_BUS_TYPE_STRING:
4311 fprintf(f, "%sSTRING: \"%s\"\n", prefix, basic.string);
4314 case SD_BUS_TYPE_OBJECT_PATH:
4315 fprintf(f, "%sOBJECT_PATH: \"%s\"\n", prefix, basic.string);
4318 case SD_BUS_TYPE_SIGNATURE:
4319 fprintf(f, "%sSIGNATURE: \"%s\"\n", prefix, basic.string);
4322 case SD_BUS_TYPE_UNIX_FD:
4323 fprintf(f, "%sUNIX_FD: %i\n", prefix, basic.i);
4327 assert_not_reached("Unknown basic type.");
4331 fprintf(f, "} END_MESSAGE\n");
4335 int bus_message_get_blob(sd_bus_message *m, void **buffer, size_t *sz) {
4339 struct bus_body_part *part;
4345 total = BUS_MESSAGE_SIZE(m);
4351 e = mempcpy(p, m->header, BUS_MESSAGE_BODY_BEGIN(m));
4352 MESSAGE_FOREACH_PART(part, i, m)
4353 e = mempcpy(e, part->data, part->size);
4355 assert(total == (size_t) ((uint8_t*) e - (uint8_t*) p));
4363 int bus_message_read_strv_extend(sd_bus_message *m, char ***l) {
4369 r = sd_bus_message_enter_container(m, 'a', "s");
4376 r = sd_bus_message_read_basic(m, 's', &s);
4382 r = strv_extend(l, s);
4387 r = sd_bus_message_exit_container(m);
4394 int sd_bus_message_read_strv(sd_bus_message *m, char ***l) {
4398 assert_return(m, -EINVAL);
4399 assert_return(m->sealed, -EPERM);
4400 assert_return(l, -EINVAL);
4402 r = bus_message_read_strv_extend(m, &strv);
4412 const char* bus_message_get_arg(sd_bus_message *m, unsigned i) {
4414 const char *t = NULL;
4419 r = sd_bus_message_rewind(m, true);
4423 for (j = 0; j <= i; j++) {
4426 r = sd_bus_message_peek_type(m, &type, NULL);
4430 if (type != SD_BUS_TYPE_STRING &&
4431 type != SD_BUS_TYPE_OBJECT_PATH &&
4432 type != SD_BUS_TYPE_SIGNATURE)
4435 r = sd_bus_message_read_basic(m, type, &t);
4443 bool bus_header_is_complete(struct bus_header *h, size_t size) {
4449 if (size < sizeof(struct bus_header))
4452 full = sizeof(struct bus_header) +
4453 (h->endian == SD_BUS_NATIVE_ENDIAN ? h->fields_size : bswap_32(h->fields_size));
4455 return size >= full;
4458 int bus_header_message_size(struct bus_header *h, size_t *sum) {
4464 if (h->endian == SD_BUS_NATIVE_ENDIAN) {
4465 fs = h->fields_size;
4467 } else if (h->endian == SD_BUS_REVERSE_ENDIAN) {
4468 fs = bswap_32(h->fields_size);
4469 bs = bswap_32(h->body_size);
4473 *sum = sizeof(struct bus_header) + ALIGN8(fs) + bs;
4477 int sd_bus_message_get_errno(sd_bus_message *m) {
4478 assert_return(m, -EINVAL);
4480 if (m->header->type != SD_BUS_MESSAGE_METHOD_ERROR)
4483 return sd_bus_error_get_errno(&m->error);
4486 const char* sd_bus_message_get_signature(sd_bus_message *m, int complete) {
4487 struct bus_container *c;
4489 assert_return(m, NULL);
4491 c = complete ? &m->root_container : message_get_container(m);
4492 return c->signature ?: "";
4495 int sd_bus_message_copy(sd_bus_message *m, sd_bus_message *source, int all) {
4496 bool done_something = false;
4499 assert_return(m, -EINVAL);
4500 assert_return(source, -EINVAL);
4501 assert_return(!m->sealed, -EPERM);
4502 assert_return(source->sealed, -EPERM);
4505 const char *contents;
4520 r = sd_bus_message_peek_type(source, &type, &contents);
4526 done_something = true;
4528 if (bus_type_is_container(type) > 0) {
4530 r = sd_bus_message_enter_container(source, type, contents);
4534 r = sd_bus_message_open_container(m, type, contents);
4538 r = sd_bus_message_copy(m, source, true);
4542 r = sd_bus_message_close_container(m);
4546 r = sd_bus_message_exit_container(source);
4553 r = sd_bus_message_read_basic(source, type, &basic);
4559 if (type == SD_BUS_TYPE_OBJECT_PATH ||
4560 type == SD_BUS_TYPE_SIGNATURE ||
4561 type == SD_BUS_TYPE_STRING)
4562 r = sd_bus_message_append_basic(m, type, basic.string);
4564 r = sd_bus_message_append_basic(m, type, &basic);
4571 return done_something;
4574 int sd_bus_message_verify_type(sd_bus_message *m, char type, const char *contents) {
4579 assert_return(m, -EINVAL);
4580 assert_return(m->sealed, -EPERM);
4581 assert_return(!type || bus_type_is_valid(type), -EINVAL);
4582 assert_return(!contents || signature_is_valid(contents, true), -EINVAL);
4583 assert_return(type || contents, -EINVAL);
4584 assert_return(!contents || !type || bus_type_is_container(type), -EINVAL);
4586 r = sd_bus_message_peek_type(m, &t, &c);
4590 if (type != 0 && type != t)
4593 if (contents && !streq_ptr(contents, c))