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 /* To make things easy we'll serialize a NULL string
1351 * into the empty string */
1354 /* Fall through... */
1355 case SD_BUS_TYPE_OBJECT_PATH:
1363 sz = 4 + strlen(p) + 1;
1366 case SD_BUS_TYPE_SIGNATURE:
1374 sz = 1 + strlen(p) + 1;
1377 case SD_BUS_TYPE_BOOLEAN:
1380 assert_cc(sizeof(int) == sizeof(uint32_t));
1386 case SD_BUS_TYPE_UNIX_FD: {
1389 if (!m->allow_fds) {
1402 fd = fcntl(z, F_DUPFD_CLOEXEC, 3);
1408 f = realloc(m->fds, sizeof(int) * (m->n_fds + 1));
1423 align = bus_type_get_alignment(type);
1424 sz = bus_type_get_size(type);
1431 a = message_extend_body(m, align, sz);
1437 if (type == SD_BUS_TYPE_STRING || type == SD_BUS_TYPE_OBJECT_PATH) {
1438 *(uint32_t*) a = sz - 5;
1439 memcpy((uint8_t*) a + 4, p, sz - 4);
1442 *stored = (const uint8_t*) a + 4;
1444 } else if (type == SD_BUS_TYPE_SIGNATURE) {
1445 *(uint8_t*) a = sz - 1;
1446 memcpy((uint8_t*) a + 1, p, sz - 1);
1449 *stored = (const uint8_t*) a + 1;
1450 } else if (type == SD_BUS_TYPE_UNIX_FD) {
1451 *(uint32_t*) a = fdi;
1465 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1472 close_nointr_nofail(fd);
1477 int sd_bus_message_append_basic(sd_bus_message *m, char type, const void *p) {
1478 return message_append_basic(m, type, p, NULL);
1481 int sd_bus_message_append_string_space(sd_bus_message *m, size_t size, char **s) {
1482 struct bus_container *c;
1485 assert_return(m, -EINVAL);
1486 assert_return(s, -EINVAL);
1487 assert_return(!m->sealed, -EPERM);
1488 assert_return(!m->poisoned, -ESTALE);
1490 c = message_get_container(m);
1492 if (c->signature && c->signature[c->index]) {
1493 /* Container signature is already set */
1495 if (c->signature[c->index] != SD_BUS_TYPE_STRING)
1500 /* Maybe we can append to the signature? But only if this is the top-level container*/
1501 if (c->enclosing != 0)
1504 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRING), NULL);
1511 a = message_extend_body(m, 4, 4 + size + 1);
1515 *(uint32_t*) a = size;
1520 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1526 static int bus_message_open_array(
1528 struct bus_container *c,
1529 const char *contents,
1530 uint32_t **array_size) {
1536 struct bus_body_part *o;
1543 if (!signature_is_single(contents, true))
1546 alignment = bus_type_get_alignment(contents[0]);
1550 if (c->signature && c->signature[c->index]) {
1552 /* Verify the existing signature */
1554 if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
1557 if (!startswith(c->signature + c->index + 1, contents))
1560 nindex = c->index + 1 + strlen(contents);
1564 if (c->enclosing != 0)
1567 /* Extend the existing signature */
1569 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_ARRAY), contents, NULL);
1575 nindex = e - c->signature;
1578 a = message_extend_body(m, 4, 4);
1583 op = m->body_end->data;
1584 os = m->body_end->size;
1586 /* Add alignment between size and first element */
1587 if (!message_extend_body(m, alignment, 0))
1590 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1593 /* location of array size might have changed so let's readjust a */
1594 if (o == m->body_end)
1595 a = adjust_pointer(a, op, os, m->body_end->data);
1602 static int bus_message_open_variant(
1604 struct bus_container *c,
1605 const char *contents) {
1614 if (!signature_is_single(contents, false))
1617 if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
1620 if (c->signature && c->signature[c->index]) {
1622 if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
1628 if (c->enclosing != 0)
1631 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_VARIANT), NULL);
1638 l = strlen(contents);
1639 a = message_extend_body(m, 1, 1 + l + 1);
1644 memcpy((uint8_t*) a + 1, contents, l + 1);
1646 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1652 static int bus_message_open_struct(
1654 struct bus_container *c,
1655 const char *contents) {
1663 if (!signature_is_valid(contents, false))
1666 if (c->signature && c->signature[c->index]) {
1669 l = strlen(contents);
1671 if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
1672 !startswith(c->signature + c->index + 1, contents) ||
1673 c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
1676 nindex = c->index + 1 + l + 1;
1680 if (c->enclosing != 0)
1683 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_BEGIN), contents, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_END), NULL);
1689 nindex = e - c->signature;
1692 /* Align contents to 8 byte boundary */
1693 if (!message_extend_body(m, 8, 0))
1696 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1702 static int bus_message_open_dict_entry(
1704 struct bus_container *c,
1705 const char *contents) {
1713 if (!signature_is_pair(contents))
1716 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1719 if (c->signature && c->signature[c->index]) {
1722 l = strlen(contents);
1724 if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
1725 !startswith(c->signature + c->index + 1, contents) ||
1726 c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
1729 nindex = c->index + 1 + l + 1;
1733 /* Align contents to 8 byte boundary */
1734 if (!message_extend_body(m, 8, 0))
1737 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1743 int sd_bus_message_open_container(
1746 const char *contents) {
1748 struct bus_container *c, *w;
1749 uint32_t *array_size = NULL;
1754 assert_return(m, -EINVAL);
1755 assert_return(!m->sealed, -EPERM);
1756 assert_return(contents, -EINVAL);
1757 assert_return(!m->poisoned, -ESTALE);
1759 /* Make sure we have space for one more container */
1760 w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
1768 c = message_get_container(m);
1770 signature = strdup(contents);
1776 /* Save old index in the parent container, in case we have to
1777 * abort this container */
1778 c->saved_index = c->index;
1779 before = m->header->body_size;
1781 if (type == SD_BUS_TYPE_ARRAY)
1782 r = bus_message_open_array(m, c, contents, &array_size);
1783 else if (type == SD_BUS_TYPE_VARIANT)
1784 r = bus_message_open_variant(m, c, contents);
1785 else if (type == SD_BUS_TYPE_STRUCT)
1786 r = bus_message_open_struct(m, c, contents);
1787 else if (type == SD_BUS_TYPE_DICT_ENTRY)
1788 r = bus_message_open_dict_entry(m, c, contents);
1797 /* OK, let's fill it in */
1798 w += m->n_containers++;
1799 w->enclosing = type;
1800 w->signature = signature;
1802 w->array_size = array_size;
1804 w->begin = m->rindex;
1809 int sd_bus_message_close_container(sd_bus_message *m) {
1810 struct bus_container *c;
1812 assert_return(m, -EINVAL);
1813 assert_return(!m->sealed, -EPERM);
1814 assert_return(m->n_containers > 0, -EINVAL);
1815 assert_return(!m->poisoned, -ESTALE);
1817 c = message_get_container(m);
1818 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1819 if (c->signature && c->signature[c->index] != 0)
1834 static int type_stack_push(TypeStack *stack, unsigned max, unsigned *i, const char *types, unsigned n_struct, unsigned n_array) {
1841 stack[*i].types = types;
1842 stack[*i].n_struct = n_struct;
1843 stack[*i].n_array = n_array;
1849 static int type_stack_pop(TypeStack *stack, unsigned max, unsigned *i, const char **types, unsigned *n_struct, unsigned *n_array) {
1860 *types = stack[*i].types;
1861 *n_struct = stack[*i].n_struct;
1862 *n_array = stack[*i].n_array;
1867 int bus_message_append_ap(
1872 unsigned n_array, n_struct;
1873 TypeStack stack[BUS_CONTAINER_DEPTH];
1874 unsigned stack_ptr = 0;
1882 n_array = (unsigned) -1;
1883 n_struct = strlen(types);
1888 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
1889 r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
1895 r = sd_bus_message_close_container(m);
1903 if (n_array != (unsigned) -1)
1912 case SD_BUS_TYPE_BYTE: {
1915 x = (uint8_t) va_arg(ap, int);
1916 r = sd_bus_message_append_basic(m, *t, &x);
1920 case SD_BUS_TYPE_BOOLEAN:
1921 case SD_BUS_TYPE_INT32:
1922 case SD_BUS_TYPE_UINT32:
1923 case SD_BUS_TYPE_UNIX_FD: {
1926 /* We assume a boolean is the same as int32_t */
1927 assert_cc(sizeof(int32_t) == sizeof(int));
1929 x = va_arg(ap, uint32_t);
1930 r = sd_bus_message_append_basic(m, *t, &x);
1934 case SD_BUS_TYPE_INT16:
1935 case SD_BUS_TYPE_UINT16: {
1938 x = (uint16_t) va_arg(ap, int);
1939 r = sd_bus_message_append_basic(m, *t, &x);
1943 case SD_BUS_TYPE_INT64:
1944 case SD_BUS_TYPE_UINT64:
1945 case SD_BUS_TYPE_DOUBLE: {
1948 x = va_arg(ap, uint64_t);
1949 r = sd_bus_message_append_basic(m, *t, &x);
1953 case SD_BUS_TYPE_STRING:
1954 case SD_BUS_TYPE_OBJECT_PATH:
1955 case SD_BUS_TYPE_SIGNATURE: {
1958 x = va_arg(ap, const char*);
1959 r = sd_bus_message_append_basic(m, *t, x);
1963 case SD_BUS_TYPE_ARRAY: {
1966 r = signature_element_length(t + 1, &k);
1972 memcpy(s, t + 1, k);
1975 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, s);
1980 if (n_array == (unsigned) -1) {
1985 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
1991 n_array = va_arg(ap, unsigned);
1996 case SD_BUS_TYPE_VARIANT: {
1999 s = va_arg(ap, const char*);
2003 r = sd_bus_message_open_container(m, SD_BUS_TYPE_VARIANT, s);
2007 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2012 n_struct = strlen(s);
2013 n_array = (unsigned) -1;
2018 case SD_BUS_TYPE_STRUCT_BEGIN:
2019 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
2022 r = signature_element_length(t, &k);
2029 memcpy(s, t + 1, k - 2);
2032 r = sd_bus_message_open_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
2037 if (n_array == (unsigned) -1) {
2042 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2048 n_array = (unsigned) -1;
2064 int sd_bus_message_append(sd_bus_message *m, const char *types, ...) {
2068 assert_return(m, -EINVAL);
2069 assert_return(types, -EINVAL);
2070 assert_return(!m->sealed, -EPERM);
2071 assert_return(!m->poisoned, -ESTALE);
2073 va_start(ap, types);
2074 r = bus_message_append_ap(m, types, ap);
2080 int sd_bus_message_append_array_space(sd_bus_message *m, char type, size_t size, void **ptr) {
2085 assert_return(m, -EINVAL);
2086 assert_return(!m->sealed, -EPERM);
2087 assert_return(bus_type_is_trivial(type), -EINVAL);
2088 assert_return(ptr || size == 0, -EINVAL);
2089 assert_return(!m->poisoned, -ESTALE);
2091 align = bus_type_get_alignment(type);
2092 sz = bus_type_get_size(type);
2094 assert_se(align > 0);
2100 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
2104 a = message_extend_body(m, align, size);
2108 r = sd_bus_message_close_container(m);
2116 int sd_bus_message_append_array(sd_bus_message *m, char type, const void *ptr, size_t size) {
2120 assert_return(m, -EINVAL);
2121 assert_return(!m->sealed, -EPERM);
2122 assert_return(bus_type_is_trivial(type), -EINVAL);
2123 assert_return(ptr || size == 0, -EINVAL);
2124 assert_return(!m->poisoned, -ESTALE);
2126 r = sd_bus_message_append_array_space(m, type, size, &p);
2131 memcpy(p, ptr, size);
2136 int sd_bus_message_append_array_memfd(sd_bus_message *m, char type, sd_memfd *memfd) {
2137 _cleanup_close_ int copy_fd = -1;
2138 struct bus_body_part *part;
2150 if (!bus_type_is_trivial(type))
2155 r = sd_memfd_set_sealed(memfd, true);
2159 copy_fd = sd_memfd_dup_fd(memfd);
2163 r = sd_memfd_get_size(memfd, &size);
2167 align = bus_type_get_alignment(type);
2168 sz = bus_type_get_size(type);
2170 assert_se(align > 0);
2176 if (size > (uint64_t) (uint32_t) -1)
2179 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
2183 a = message_extend_body(m, align, 0);
2187 part = message_append_part(m);
2191 part->memfd = copy_fd;
2192 part->sealed = true;
2196 message_extend_containers(m, size);
2197 m->header->body_size += size;
2199 return sd_bus_message_close_container(m);
2202 int sd_bus_message_append_string_memfd(sd_bus_message *m, sd_memfd *memfd) {
2203 _cleanup_close_ int copy_fd = -1;
2204 struct bus_body_part *part;
2205 struct bus_container *c;
2210 assert_return(m, -EINVAL);
2211 assert_return(memfd, -EINVAL);
2212 assert_return(!m->sealed, -EPERM);
2213 assert_return(!m->poisoned, -ESTALE);
2215 r = sd_memfd_set_sealed(memfd, true);
2219 copy_fd = sd_memfd_dup_fd(memfd);
2223 r = sd_memfd_get_size(memfd, &size);
2227 /* We require this to be NUL terminated */
2231 if (size > (uint64_t) (uint32_t) -1)
2234 c = message_get_container(m);
2235 if (c->signature && c->signature[c->index]) {
2236 /* Container signature is already set */
2238 if (c->signature[c->index] != SD_BUS_TYPE_STRING)
2243 /* Maybe we can append to the signature? But only if this is the top-level container*/
2244 if (c->enclosing != 0)
2247 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRING), NULL);
2254 a = message_extend_body(m, 4, 4);
2258 *(uint32_t*) a = size - 1;
2260 part = message_append_part(m);
2264 part->memfd = copy_fd;
2265 part->sealed = true;
2269 message_extend_containers(m, size);
2270 m->header->body_size += size;
2272 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2278 int sd_bus_message_append_strv(sd_bus_message *m, char **l) {
2282 assert_return(m, -EINVAL);
2283 assert_return(!m->sealed, -EPERM);
2284 assert_return(!m->poisoned, -ESTALE);
2286 r = sd_bus_message_open_container(m, 'a', "s");
2290 STRV_FOREACH(i, l) {
2291 r = sd_bus_message_append_basic(m, 's', *i);
2296 return sd_bus_message_close_container(m);
2299 int bus_body_part_map(struct bus_body_part *part) {
2308 if (part->size <= 0)
2311 /* For smaller zero parts (as used for padding) we don't need to map anything... */
2312 if (part->memfd < 0 && part->is_zero && part->size < 8) {
2313 static const uint8_t zeroes[7] = { };
2314 part->data = (void*) zeroes;
2318 psz = PAGE_ALIGN(part->size);
2320 if (part->memfd >= 0)
2321 p = mmap(NULL, psz, PROT_READ, MAP_SHARED, part->memfd, 0);
2322 else if (part->is_zero)
2323 p = mmap(NULL, psz, PROT_READ, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
2327 if (p == MAP_FAILED)
2332 part->munmap_this = true;
2337 void bus_body_part_unmap(struct bus_body_part *part) {
2341 if (part->memfd < 0)
2347 if (!part->munmap_this)
2350 assert_se(munmap(part->data, part->mapped) == 0);
2354 part->munmap_this = false;
2359 static int buffer_peek(const void *p, uint32_t sz, size_t *rindex, size_t align, size_t nbytes, void **r) {
2360 size_t k, start, end;
2365 start = ALIGN_TO((size_t) *rindex, align);
2366 end = start + nbytes;
2371 /* Verify that padding is 0 */
2372 for (k = *rindex; k < start; k++)
2373 if (((const uint8_t*) p)[k] != 0)
2377 *r = (uint8_t*) p + start;
2384 static bool message_end_of_signature(sd_bus_message *m) {
2385 struct bus_container *c;
2389 c = message_get_container(m);
2390 return !c->signature || c->signature[c->index] == 0;
2393 static bool message_end_of_array(sd_bus_message *m, size_t index) {
2394 struct bus_container *c;
2398 c = message_get_container(m);
2402 return index >= c->begin + BUS_MESSAGE_BSWAP32(m, *c->array_size);
2405 int sd_bus_message_at_end(sd_bus_message *m, int complete) {
2406 assert_return(m, -EINVAL);
2407 assert_return(m->sealed, -EPERM);
2409 if (complete && m->n_containers > 0)
2412 if (message_end_of_signature(m))
2415 if (message_end_of_array(m, m->rindex))
2421 static struct bus_body_part* find_part(sd_bus_message *m, size_t index, size_t sz, void **p) {
2422 struct bus_body_part *part;
2428 if (m->cached_rindex_part && index >= m->cached_rindex_part_begin) {
2429 part = m->cached_rindex_part;
2430 begin = m->cached_rindex_part_begin;
2440 if (index + sz <= begin + part->size) {
2442 r = bus_body_part_map(part);
2447 *p = (uint8_t*) part->data + index - begin;
2449 m->cached_rindex_part = part;
2450 m->cached_rindex_part_begin = begin;
2455 begin += part->size;
2462 static int message_peek_body(
2469 size_t k, start, end, padding;
2470 struct bus_body_part *part;
2477 if (message_end_of_array(m, *rindex))
2480 start = ALIGN_TO((size_t) *rindex, align);
2481 padding = start - *rindex;
2482 end = start + nbytes;
2484 if (end > BUS_MESSAGE_BODY_SIZE(m))
2487 part = find_part(m, *rindex, padding, (void**) &q);
2492 /* Verify padding */
2493 for (k = 0; k < padding; k++)
2498 part = find_part(m, start, nbytes, (void**) &q);
2510 static bool validate_nul(const char *s, size_t l) {
2512 /* Check for NUL chars in the string */
2513 if (memchr(s, 0, l))
2516 /* Check for NUL termination */
2523 static bool validate_string(const char *s, size_t l) {
2525 if (!validate_nul(s, l))
2528 /* Check if valid UTF8 */
2529 if (!utf8_is_valid(s))
2535 static bool validate_signature(const char *s, size_t l) {
2537 if (!validate_nul(s, l))
2540 /* Check if valid signature */
2541 if (!signature_is_valid(s, true))
2547 static bool validate_object_path(const char *s, size_t l) {
2549 if (!validate_nul(s, l))
2552 if (!object_path_is_valid(s))
2558 int sd_bus_message_read_basic(sd_bus_message *m, char type, void *p) {
2559 struct bus_container *c;
2563 assert_return(m, -EINVAL);
2564 assert_return(m->sealed, -EPERM);
2565 assert_return(bus_type_is_basic(type), -EINVAL);
2567 if (message_end_of_signature(m))
2570 if (message_end_of_array(m, m->rindex))
2573 c = message_get_container(m);
2574 if (c->signature[c->index] != type)
2579 case SD_BUS_TYPE_STRING:
2580 case SD_BUS_TYPE_OBJECT_PATH: {
2585 r = message_peek_body(m, &rindex, 4, 4, &q);
2589 l = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2590 r = message_peek_body(m, &rindex, 1, l+1, &q);
2596 if (type == SD_BUS_TYPE_OBJECT_PATH) {
2597 if (!validate_object_path(q, l))
2600 if (!validate_string(q, l))
2606 *(const char**) p = q;
2611 case SD_BUS_TYPE_SIGNATURE: {
2616 r = message_peek_body(m, &rindex, 1, 1, &q);
2621 r = message_peek_body(m, &rindex, 1, l+1, &q);
2627 if (!validate_signature(q, l))
2633 *(const char**) p = q;
2641 align = bus_type_get_alignment(type);
2642 sz = bus_type_get_size(type);
2643 assert(align > 0 && sz > 0);
2646 r = message_peek_body(m, &rindex, align, sz, &q);
2652 case SD_BUS_TYPE_BYTE:
2654 *(uint8_t*) p = *(uint8_t*) q;
2657 case SD_BUS_TYPE_BOOLEAN:
2659 *(unsigned*) p = !!*(uint32_t*) q;
2662 case SD_BUS_TYPE_INT16:
2663 case SD_BUS_TYPE_UINT16:
2665 *(uint16_t*) p = BUS_MESSAGE_BSWAP16(m, *(uint16_t*) q);
2668 case SD_BUS_TYPE_INT32:
2669 case SD_BUS_TYPE_UINT32:
2671 *(uint32_t*) p = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2674 case SD_BUS_TYPE_INT64:
2675 case SD_BUS_TYPE_UINT64:
2676 case SD_BUS_TYPE_DOUBLE:
2678 *(uint64_t*) p = BUS_MESSAGE_BSWAP64(m, *(uint64_t*) q);
2681 case SD_BUS_TYPE_UNIX_FD: {
2684 j = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2689 *(int*) p = m->fds[j];
2694 assert_not_reached("Unknown basic type...");
2703 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2709 static int bus_message_enter_array(
2711 struct bus_container *c,
2712 const char *contents,
2713 uint32_t **array_size) {
2724 if (!signature_is_single(contents, true))
2727 alignment = bus_type_get_alignment(contents[0]);
2731 if (!c->signature || c->signature[c->index] == 0)
2734 if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
2737 if (!startswith(c->signature + c->index + 1, contents))
2741 r = message_peek_body(m, &rindex, 4, 4, &q);
2745 if (BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q) > BUS_ARRAY_MAX_SIZE)
2748 r = message_peek_body(m, &rindex, alignment, 0, NULL);
2754 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2755 c->index += 1 + strlen(contents);
2759 *array_size = (uint32_t*) q;
2764 static int bus_message_enter_variant(
2766 struct bus_container *c,
2767 const char *contents) {
2778 if (!signature_is_single(contents, false))
2781 if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
2784 if (!c->signature || c->signature[c->index] == 0)
2787 if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
2791 r = message_peek_body(m, &rindex, 1, 1, &q);
2796 r = message_peek_body(m, &rindex, 1, l+1, &q);
2802 if (!validate_signature(q, l))
2805 if (!streq(q, contents))
2808 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2816 static int bus_message_enter_struct(
2818 struct bus_container *c,
2819 const char *contents) {
2828 if (!signature_is_valid(contents, false))
2831 if (!c->signature || c->signature[c->index] == 0)
2834 l = strlen(contents);
2836 if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
2837 !startswith(c->signature + c->index + 1, contents) ||
2838 c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
2841 r = message_peek_body(m, &m->rindex, 8, 0, NULL);
2845 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2846 c->index += 1 + l + 1;
2851 static int bus_message_enter_dict_entry(
2853 struct bus_container *c,
2854 const char *contents) {
2863 if (!signature_is_pair(contents))
2866 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2869 if (!c->signature || c->signature[c->index] == 0)
2872 l = strlen(contents);
2874 if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
2875 !startswith(c->signature + c->index + 1, contents) ||
2876 c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
2879 r = message_peek_body(m, &m->rindex, 8, 0, NULL);
2883 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2884 c->index += 1 + l + 1;
2889 int sd_bus_message_enter_container(sd_bus_message *m, char type, const char *contents) {
2890 struct bus_container *c, *w;
2891 uint32_t *array_size = NULL;
2896 assert_return(m, -EINVAL);
2897 assert_return(m->sealed, -EPERM);
2898 assert_return(type != 0 || !contents, -EINVAL);
2900 if (type == 0 || !contents) {
2904 /* Allow entering into anonymous containers */
2905 r = sd_bus_message_peek_type(m, &tt, &cc);
2909 if (type != 0 && type != tt)
2912 if (contents && !streq(contents, cc))
2920 * We enforce a global limit on container depth, that is much
2921 * higher than the 32 structs and 32 arrays the specification
2922 * mandates. This is simpler to implement for us, and we need
2923 * this only to ensure our container array doesn't grow
2924 * without bounds. We are happy to return any data from a
2925 * message as long as the data itself is valid, even if the
2926 * overall message might be not.
2928 * Note that the message signature is validated when
2929 * parsing the headers, and that validation does check the
2932 * Note that the specification defines no limits on the depth
2933 * of stacked variants, but we do.
2935 if (m->n_containers >= BUS_CONTAINER_DEPTH)
2938 w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
2943 if (message_end_of_signature(m))
2946 if (message_end_of_array(m, m->rindex))
2949 c = message_get_container(m);
2951 signature = strdup(contents);
2955 c->saved_index = c->index;
2958 if (type == SD_BUS_TYPE_ARRAY)
2959 r = bus_message_enter_array(m, c, contents, &array_size);
2960 else if (type == SD_BUS_TYPE_VARIANT)
2961 r = bus_message_enter_variant(m, c, contents);
2962 else if (type == SD_BUS_TYPE_STRUCT)
2963 r = bus_message_enter_struct(m, c, contents);
2964 else if (type == SD_BUS_TYPE_DICT_ENTRY)
2965 r = bus_message_enter_dict_entry(m, c, contents);
2974 /* OK, let's fill it in */
2975 w += m->n_containers++;
2976 w->enclosing = type;
2977 w->signature = signature;
2979 w->array_size = array_size;
2981 w->begin = m->rindex;
2986 int sd_bus_message_exit_container(sd_bus_message *m) {
2987 struct bus_container *c;
2989 assert_return(m, -EINVAL);
2990 assert_return(m->sealed, -EPERM);
2991 assert_return(m->n_containers > 0, -EINVAL);
2993 c = message_get_container(m);
2994 if (c->enclosing == SD_BUS_TYPE_ARRAY) {
2997 l = BUS_MESSAGE_BSWAP32(m, *c->array_size);
2998 if (c->begin + l != m->rindex)
3002 if (c->signature && c->signature[c->index] != 0)
3012 static void message_quit_container(sd_bus_message *m) {
3013 struct bus_container *c;
3017 assert(m->n_containers > 0);
3019 c = message_get_container(m);
3022 assert(m->rindex >= c->before);
3023 m->rindex = c->before;
3025 /* Free container */
3029 /* Correct index of new top-level container */
3030 c = message_get_container(m);
3031 c->index = c->saved_index;
3034 int sd_bus_message_peek_type(sd_bus_message *m, char *type, const char **contents) {
3035 struct bus_container *c;
3038 assert_return(m, -EINVAL);
3039 assert_return(m->sealed, -EPERM);
3041 if (message_end_of_signature(m))
3044 if (message_end_of_array(m, m->rindex))
3047 c = message_get_container(m);
3049 if (bus_type_is_basic(c->signature[c->index])) {
3053 *type = c->signature[c->index];
3057 if (c->signature[c->index] == SD_BUS_TYPE_ARRAY) {
3063 r = signature_element_length(c->signature+c->index+1, &l);
3069 sig = strndup(c->signature + c->index + 1, l);
3073 free(m->peeked_signature);
3074 m->peeked_signature = sig;
3080 *type = SD_BUS_TYPE_ARRAY;
3085 if (c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ||
3086 c->signature[c->index] == SD_BUS_TYPE_DICT_ENTRY_BEGIN) {
3092 r = signature_element_length(c->signature+c->index, &l);
3097 sig = strndup(c->signature + c->index + 1, l - 2);
3101 free(m->peeked_signature);
3102 m->peeked_signature = sig;
3108 *type = c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY;
3113 if (c->signature[c->index] == SD_BUS_TYPE_VARIANT) {
3119 r = message_peek_body(m, &rindex, 1, 1, &q);
3126 r = message_peek_body(m, &rindex, 1, l+1, &q);
3132 if (!validate_signature(q, l))
3139 *type = SD_BUS_TYPE_VARIANT;
3154 int sd_bus_message_rewind(sd_bus_message *m, int complete) {
3155 struct bus_container *c;
3157 assert_return(m, -EINVAL);
3158 assert_return(m->sealed, -EPERM);
3161 message_reset_containers(m);
3163 m->root_container.index = 0;
3165 c = message_get_container(m);
3167 c = message_get_container(m);
3170 m->rindex = c->begin;
3173 return !isempty(c->signature);
3175 static int message_read_ap(
3180 unsigned n_array, n_struct;
3181 TypeStack stack[BUS_CONTAINER_DEPTH];
3182 unsigned stack_ptr = 0;
3183 unsigned n_loop = 0;
3191 /* Ideally, we'd just call ourselves recursively on every
3192 * complex type. However, the state of a va_list that is
3193 * passed to a function is undefined after that function
3194 * returns. This means we need to docode the va_list linearly
3195 * in a single stackframe. We hence implement our own
3196 * home-grown stack in an array. */
3198 n_array = (unsigned) -1; /* lenght of current array entries */
3199 n_struct = strlen(types); /* length of current struct contents signature */
3206 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
3207 r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
3213 r = sd_bus_message_exit_container(m);
3221 if (n_array != (unsigned) -1)
3230 case SD_BUS_TYPE_BYTE:
3231 case SD_BUS_TYPE_BOOLEAN:
3232 case SD_BUS_TYPE_INT16:
3233 case SD_BUS_TYPE_UINT16:
3234 case SD_BUS_TYPE_INT32:
3235 case SD_BUS_TYPE_UINT32:
3236 case SD_BUS_TYPE_INT64:
3237 case SD_BUS_TYPE_UINT64:
3238 case SD_BUS_TYPE_DOUBLE:
3239 case SD_BUS_TYPE_STRING:
3240 case SD_BUS_TYPE_OBJECT_PATH:
3241 case SD_BUS_TYPE_SIGNATURE:
3242 case SD_BUS_TYPE_UNIX_FD: {
3245 p = va_arg(ap, void*);
3246 r = sd_bus_message_read_basic(m, *t, p);
3259 case SD_BUS_TYPE_ARRAY: {
3262 r = signature_element_length(t + 1, &k);
3268 memcpy(s, t + 1, k);
3271 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, s);
3282 if (n_array == (unsigned) -1) {
3287 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
3293 n_array = va_arg(ap, unsigned);
3298 case SD_BUS_TYPE_VARIANT: {
3301 s = va_arg(ap, const char *);
3305 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, s);
3315 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
3320 n_struct = strlen(s);
3321 n_array = (unsigned) -1;
3326 case SD_BUS_TYPE_STRUCT_BEGIN:
3327 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
3330 r = signature_element_length(t, &k);
3336 memcpy(s, t + 1, k - 2);
3339 r = sd_bus_message_enter_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
3349 if (n_array == (unsigned) -1) {
3354 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
3360 n_array = (unsigned) -1;
3373 int sd_bus_message_read(sd_bus_message *m, const char *types, ...) {
3377 assert_return(m, -EINVAL);
3378 assert_return(m->sealed, -EPERM);
3379 assert_return(types, -EINVAL);
3381 va_start(ap, types);
3382 r = message_read_ap(m, types, ap);
3388 int sd_bus_message_skip(sd_bus_message *m, const char *types) {
3391 assert_return(m, -EINVAL);
3392 assert_return(m->sealed, -EPERM);
3393 assert_return(types, -EINVAL);
3400 case SD_BUS_TYPE_BYTE:
3401 case SD_BUS_TYPE_BOOLEAN:
3402 case SD_BUS_TYPE_INT16:
3403 case SD_BUS_TYPE_UINT16:
3404 case SD_BUS_TYPE_INT32:
3405 case SD_BUS_TYPE_UINT32:
3406 case SD_BUS_TYPE_INT64:
3407 case SD_BUS_TYPE_UINT64:
3408 case SD_BUS_TYPE_DOUBLE:
3409 case SD_BUS_TYPE_STRING:
3410 case SD_BUS_TYPE_OBJECT_PATH:
3411 case SD_BUS_TYPE_SIGNATURE:
3412 case SD_BUS_TYPE_UNIX_FD:
3414 r = sd_bus_message_read_basic(m, *types, NULL);
3418 r = sd_bus_message_skip(m, types + 1);
3424 case SD_BUS_TYPE_ARRAY: {
3427 r = signature_element_length(types + 1, &k);
3433 memcpy(s, types+1, k);
3436 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, s);
3441 r = sd_bus_message_skip(m, s);
3448 r = sd_bus_message_exit_container(m);
3453 r = sd_bus_message_skip(m, types + 1 + k);
3460 case SD_BUS_TYPE_VARIANT: {
3461 const char *contents;
3464 r = sd_bus_message_peek_type(m, &x, &contents);
3468 if (x != SD_BUS_TYPE_VARIANT)
3471 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, contents);
3475 r = sd_bus_message_skip(m, contents);
3480 r = sd_bus_message_exit_container(m);
3484 r = sd_bus_message_skip(m, types + 1);
3491 case SD_BUS_TYPE_STRUCT_BEGIN:
3492 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
3495 r = signature_element_length(types, &k);
3501 memcpy(s, types+1, k-2);
3504 r = sd_bus_message_enter_container(m, *types == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
3508 r = sd_bus_message_skip(m, s);
3513 r = sd_bus_message_exit_container(m);
3518 r = sd_bus_message_skip(m, types + k);
3530 int sd_bus_message_read_array(sd_bus_message *m, char type, const void **ptr, size_t *size) {
3531 struct bus_container *c;
3537 assert_return(m, -EINVAL);
3538 assert_return(m->sealed, -EPERM);
3539 assert_return(bus_type_is_trivial(type), -EINVAL);
3540 assert_return(ptr, -EINVAL);
3541 assert_return(size, -EINVAL);
3542 assert_return(!BUS_MESSAGE_NEED_BSWAP(m), -ENOTSUP);
3544 align = bus_type_get_alignment(type);
3548 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
3552 c = message_get_container(m);
3553 sz = BUS_MESSAGE_BSWAP32(m, *c->array_size);
3555 r = message_peek_body(m, &m->rindex, align, sz, &p);
3563 r = sd_bus_message_exit_container(m);
3567 *ptr = (const void*) p;
3573 message_quit_container(m);
3577 static int message_peek_fields(
3588 return buffer_peek(BUS_MESSAGE_FIELDS(m), BUS_MESSAGE_FIELDS_SIZE(m), rindex, align, nbytes, ret);
3591 static int message_peek_field_uint32(
3602 r = message_peek_fields(m, ri, 4, 4, &q);
3607 *ret = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
3612 static int message_peek_field_string(
3614 bool (*validate)(const char *p),
3625 r = message_peek_field_uint32(m, ri, &l);
3629 r = message_peek_fields(m, ri, 1, l+1, &q);
3634 if (!validate_nul(q, l))
3640 if (!validate_string(q, l))
3650 static int message_peek_field_signature(
3662 r = message_peek_fields(m, ri, 1, 1, &q);
3667 r = message_peek_fields(m, ri, 1, l+1, &q);
3671 if (!validate_signature(q, l))
3680 static int message_skip_fields(
3683 uint32_t array_size,
3684 const char **signature) {
3686 size_t original_index;
3693 original_index = *ri;
3699 if (array_size != (uint32_t) -1 &&
3700 array_size <= *ri - original_index)
3707 if (t == SD_BUS_TYPE_STRING) {
3709 r = message_peek_field_string(m, NULL, ri, NULL);
3715 } else if (t == SD_BUS_TYPE_OBJECT_PATH) {
3717 r = message_peek_field_string(m, object_path_is_valid, ri, NULL);
3723 } else if (t == SD_BUS_TYPE_SIGNATURE) {
3725 r = message_peek_field_signature(m, ri, NULL);
3731 } else if (bus_type_is_basic(t)) {
3734 align = bus_type_get_alignment(t);
3735 k = bus_type_get_size(t);
3736 assert(align > 0 && k > 0);
3738 r = message_peek_fields(m, ri, align, k, NULL);
3744 } else if (t == SD_BUS_TYPE_ARRAY) {
3746 r = signature_element_length(*signature+1, &l);
3756 strncpy(sig, *signature + 1, l-1);
3759 alignment = bus_type_get_alignment(sig[0]);
3763 r = message_peek_field_uint32(m, ri, &nas);
3766 if (nas > BUS_ARRAY_MAX_SIZE)
3769 r = message_peek_fields(m, ri, alignment, 0, NULL);
3773 r = message_skip_fields(m, ri, nas, (const char**) &s);
3778 (*signature) += 1 + l;
3780 } else if (t == SD_BUS_TYPE_VARIANT) {
3783 r = message_peek_field_signature(m, ri, &s);
3787 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
3793 } else if (t == SD_BUS_TYPE_STRUCT ||
3794 t == SD_BUS_TYPE_DICT_ENTRY) {
3796 r = signature_element_length(*signature, &l);
3803 strncpy(sig, *signature + 1, l-1);
3806 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
3817 int bus_message_parse_fields(sd_bus_message *m) {
3820 uint32_t unix_fds = 0;
3824 for (ri = 0; ri < BUS_MESSAGE_FIELDS_SIZE(m); ) {
3825 const char *signature;
3828 r = message_peek_fields(m, &ri, 8, 1, (void**) &header);
3832 r = message_peek_field_signature(m, &ri, &signature);
3837 case _SD_BUS_MESSAGE_HEADER_INVALID:
3840 case SD_BUS_MESSAGE_HEADER_PATH:
3845 if (!streq(signature, "o"))
3848 r = message_peek_field_string(m, object_path_is_valid, &ri, &m->path);
3851 case SD_BUS_MESSAGE_HEADER_INTERFACE:
3856 if (!streq(signature, "s"))
3859 r = message_peek_field_string(m, interface_name_is_valid, &ri, &m->interface);
3862 case SD_BUS_MESSAGE_HEADER_MEMBER:
3867 if (!streq(signature, "s"))
3870 r = message_peek_field_string(m, member_name_is_valid, &ri, &m->member);
3873 case SD_BUS_MESSAGE_HEADER_ERROR_NAME:
3878 if (!streq(signature, "s"))
3881 r = message_peek_field_string(m, error_name_is_valid, &ri, &m->error.name);
3884 case SD_BUS_MESSAGE_HEADER_DESTINATION:
3889 if (!streq(signature, "s"))
3892 r = message_peek_field_string(m, service_name_is_valid, &ri, &m->destination);
3895 case SD_BUS_MESSAGE_HEADER_SENDER:
3900 if (!streq(signature, "s"))
3903 r = message_peek_field_string(m, service_name_is_valid, &ri, &m->sender);
3907 case SD_BUS_MESSAGE_HEADER_SIGNATURE: {
3911 if (m->root_container.signature)
3914 if (!streq(signature, "g"))
3917 r = message_peek_field_signature(m, &ri, &s);
3925 free(m->root_container.signature);
3926 m->root_container.signature = c;
3930 case SD_BUS_MESSAGE_HEADER_REPLY_SERIAL:
3931 if (m->reply_serial != 0)
3934 if (!streq(signature, "u"))
3937 r = message_peek_field_uint32(m, &ri, &m->reply_serial);
3941 if (m->reply_serial == 0)
3946 case SD_BUS_MESSAGE_HEADER_UNIX_FDS:
3950 if (!streq(signature, "u"))
3953 r = message_peek_field_uint32(m, &ri, &unix_fds);
3963 r = message_skip_fields(m, &ri, (uint32_t) -1, (const char **) &signature);
3970 if (m->n_fds != unix_fds)
3973 if (isempty(m->root_container.signature) != (BUS_MESSAGE_BODY_SIZE(m) == 0))
3976 switch (m->header->type) {
3978 case SD_BUS_MESSAGE_SIGNAL:
3979 if (!m->path || !m->interface || !m->member)
3983 case SD_BUS_MESSAGE_METHOD_CALL:
3985 if (!m->path || !m->member)
3990 case SD_BUS_MESSAGE_METHOD_RETURN:
3992 if (m->reply_serial == 0)
3996 case SD_BUS_MESSAGE_METHOD_ERROR:
3998 if (m->reply_serial == 0 || !m->error.name)
4003 /* Try to read the error message, but if we can't it's a non-issue */
4004 if (m->header->type == SD_BUS_MESSAGE_METHOD_ERROR)
4005 sd_bus_message_read(m, "s", &m->error.message);
4010 int bus_message_seal(sd_bus_message *m, uint64_t serial) {
4011 struct bus_body_part *part;
4021 if (m->n_containers > 0)
4027 /* If there's a non-trivial signature set, then add it in here */
4028 if (!isempty(m->root_container.signature)) {
4029 r = message_append_field_signature(m, SD_BUS_MESSAGE_HEADER_SIGNATURE, m->root_container.signature, NULL);
4035 r = message_append_field_uint32(m, SD_BUS_MESSAGE_HEADER_UNIX_FDS, m->n_fds);
4040 /* Add padding at the end of the fields part, since we know
4041 * the body needs to start at an 8 byte alignment. We made
4042 * sure we allocated enough space for this, so all we need to
4043 * do here is to zero it out. */
4044 l = BUS_MESSAGE_FIELDS_SIZE(m);
4047 memset((uint8_t*) BUS_MESSAGE_FIELDS(m) + l, 0, a);
4049 /* If this is something we can send as memfd, then let's seal
4050 the memfd now. Note that we can send memfds as payload only
4051 for directed messages, and not for broadcasts. */
4052 if (m->destination && m->bus && m->bus->use_memfd) {
4053 MESSAGE_FOREACH_PART(part, i, m)
4054 if (part->memfd >= 0 && !part->sealed && (part->size > MEMFD_MIN_SIZE || m->bus->use_memfd < 0)) {
4055 bus_body_part_unmap(part);
4057 if (ioctl(part->memfd, KDBUS_CMD_MEMFD_SEAL_SET, 1) >= 0)
4058 part->sealed = true;
4062 m->header->serial = serial;
4068 int sd_bus_message_set_destination(sd_bus_message *m, const char *destination) {
4069 assert_return(m, -EINVAL);
4070 assert_return(destination, -EINVAL);
4071 assert_return(!m->sealed, -EPERM);
4072 assert_return(!m->destination, -EEXIST);
4074 return message_append_field_string(m, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &m->destination);
4077 int bus_message_dump(sd_bus_message *m, FILE *f, bool with_header) {
4078 const char *u = NULL, *uu = NULL, *s = NULL;
4079 char **cmdline = NULL;
4082 uid_t owner, audit_loginuid;
4083 uint32_t audit_sessionid;
4099 "\tfields_size=%u\n"
4104 "\tdestination=%s\n"
4107 "\treply_serial=%u\n"
4109 "\tn_body_parts=%u\n",
4116 BUS_MESSAGE_SERIAL(m),
4117 BUS_MESSAGE_FIELDS_SIZE(m),
4118 BUS_MESSAGE_BODY_SIZE(m),
4120 strna(m->interface),
4122 strna(m->destination),
4124 strna(m->root_container.signature),
4129 if (sd_bus_error_is_set(&m->error))
4132 "\terror.message=%s\n",
4133 strna(m->error.name),
4134 strna(m->error.message));
4137 fprintf(f, "\tpid=%lu\n", (unsigned long) m->pid);
4139 fprintf(f, "\ttid=%lu\n", (unsigned long) m->tid);
4141 fprintf(f, "\tuid=%lu\n", (unsigned long) m->uid);
4143 fprintf(f, "\tgid=%lu\n", (unsigned long) m->gid);
4144 if (m->pid_starttime != 0)
4145 fprintf(f, "\tpid_starttime=%llu\n", (unsigned long long) m->pid_starttime);
4146 if (m->monotonic != 0)
4147 fprintf(f, "\tmonotonic=%llu\n", (unsigned long long) m->monotonic);
4148 if (m->realtime != 0)
4149 fprintf(f, "\trealtime=%llu\n", (unsigned long long) m->realtime);
4151 fprintf(f, "\texe=[%s]\n", m->exe);
4153 fprintf(f, "\tcomm=[%s]\n", m->comm);
4155 fprintf(f, "\ttid_comm=[%s]\n", m->tid_comm);
4157 fprintf(f, "\tlabel=[%s]\n", m->label);
4159 fprintf(f, "\tcgroup=[%s]\n", m->cgroup);
4161 sd_bus_message_get_unit(m, &u);
4163 fprintf(f, "\tunit=[%s]\n", u);
4164 sd_bus_message_get_user_unit(m, &uu);
4166 fprintf(f, "\tuser_unit=[%s]\n", uu);
4167 sd_bus_message_get_session(m, &s);
4169 fprintf(f, "\tsession=[%s]\n", s);
4170 if (sd_bus_message_get_owner_uid(m, &owner) >= 0)
4171 fprintf(f, "\towner_uid=%lu\n", (unsigned long) owner);
4172 if (sd_bus_message_get_audit_loginuid(m, &audit_loginuid) >= 0)
4173 fprintf(f, "\taudit_loginuid=%lu\n", (unsigned long) audit_loginuid);
4174 if (sd_bus_message_get_audit_sessionid(m, &audit_sessionid) >= 0)
4175 fprintf(f, "\taudit_sessionid=%lu\n", (unsigned long) audit_sessionid);
4177 r = sd_bus_message_has_effective_cap(m, 5);
4179 fprintf(f, "\tCAP_KILL=%s\n", yes_no(r));
4181 if (sd_bus_message_get_cmdline(m, &cmdline) >= 0) {
4184 fputs("\tcmdline=[", f);
4185 STRV_FOREACH(c, cmdline) {
4196 r = sd_bus_message_rewind(m, true);
4198 log_error("Failed to rewind: %s", strerror(-r));
4202 fprintf(f, "BEGIN_MESSAGE \"%s\" {\n", strempty(m->root_container.signature));
4205 _cleanup_free_ char *prefix = NULL;
4206 const char *contents = NULL;
4221 r = sd_bus_message_peek_type(m, &type, &contents);
4223 log_error("Failed to peek type: %s", strerror(-r));
4230 r = sd_bus_message_exit_container(m);
4232 log_error("Failed to exit container: %s", strerror(-r));
4238 prefix = strrep("\t", level);
4242 if (type == SD_BUS_TYPE_ARRAY)
4243 fprintf(f, "%s} END_ARRAY \n", prefix);
4244 else if (type == SD_BUS_TYPE_VARIANT)
4245 fprintf(f, "%s} END_VARIANT\n", prefix);
4246 else if (type == SD_BUS_TYPE_STRUCT)
4247 fprintf(f, "%s} END_STRUCT\n", prefix);
4248 else if (type == SD_BUS_TYPE_DICT_ENTRY)
4249 fprintf(f, "%s} END_DICT_ENTRY\n", prefix);
4254 prefix = strrep("\t", level);
4258 if (bus_type_is_container(type) > 0) {
4259 r = sd_bus_message_enter_container(m, type, contents);
4261 log_error("Failed to enter container: %s", strerror(-r));
4265 if (type == SD_BUS_TYPE_ARRAY)
4266 fprintf(f, "%sBEGIN_ARRAY \"%s\" {\n", prefix, contents);
4267 else if (type == SD_BUS_TYPE_VARIANT)
4268 fprintf(f, "%sBEGIN_VARIANT \"%s\" {\n", prefix, contents);
4269 else if (type == SD_BUS_TYPE_STRUCT)
4270 fprintf(f, "%sBEGIN_STRUCT \"%s\" {\n", prefix, contents);
4271 else if (type == SD_BUS_TYPE_DICT_ENTRY)
4272 fprintf(f, "%sBEGIN_DICT_ENTRY \"%s\" {\n", prefix, contents);
4279 r = sd_bus_message_read_basic(m, type, &basic);
4281 log_error("Failed to get basic: %s", strerror(-r));
4289 case SD_BUS_TYPE_BYTE:
4290 fprintf(f, "%sBYTE: %u\n", prefix, basic.u8);
4293 case SD_BUS_TYPE_BOOLEAN:
4294 fprintf(f, "%sBOOLEAN: %s\n", prefix, yes_no(basic.i));
4297 case SD_BUS_TYPE_INT16:
4298 fprintf(f, "%sINT16: %i\n", prefix, basic.s16);
4301 case SD_BUS_TYPE_UINT16:
4302 fprintf(f, "%sUINT16: %u\n", prefix, basic.u16);
4305 case SD_BUS_TYPE_INT32:
4306 fprintf(f, "%sINT32: %i\n", prefix, basic.s32);
4309 case SD_BUS_TYPE_UINT32:
4310 fprintf(f, "%sUINT32: %u\n", prefix, basic.u32);
4313 case SD_BUS_TYPE_INT64:
4314 fprintf(f, "%sINT64: %lli\n", prefix, (long long) basic.s64);
4317 case SD_BUS_TYPE_UINT64:
4318 fprintf(f, "%sUINT64: %llu\n", prefix, (unsigned long long) basic.u64);
4321 case SD_BUS_TYPE_DOUBLE:
4322 fprintf(f, "%sDOUBLE: %g\n", prefix, basic.d64);
4325 case SD_BUS_TYPE_STRING:
4326 fprintf(f, "%sSTRING: \"%s\"\n", prefix, basic.string);
4329 case SD_BUS_TYPE_OBJECT_PATH:
4330 fprintf(f, "%sOBJECT_PATH: \"%s\"\n", prefix, basic.string);
4333 case SD_BUS_TYPE_SIGNATURE:
4334 fprintf(f, "%sSIGNATURE: \"%s\"\n", prefix, basic.string);
4337 case SD_BUS_TYPE_UNIX_FD:
4338 fprintf(f, "%sUNIX_FD: %i\n", prefix, basic.i);
4342 assert_not_reached("Unknown basic type.");
4346 fprintf(f, "} END_MESSAGE\n");
4350 int bus_message_get_blob(sd_bus_message *m, void **buffer, size_t *sz) {
4354 struct bus_body_part *part;
4360 total = BUS_MESSAGE_SIZE(m);
4366 e = mempcpy(p, m->header, BUS_MESSAGE_BODY_BEGIN(m));
4367 MESSAGE_FOREACH_PART(part, i, m)
4368 e = mempcpy(e, part->data, part->size);
4370 assert(total == (size_t) ((uint8_t*) e - (uint8_t*) p));
4378 int bus_message_read_strv_extend(sd_bus_message *m, char ***l) {
4384 r = sd_bus_message_enter_container(m, 'a', "s");
4391 r = sd_bus_message_read_basic(m, 's', &s);
4397 r = strv_extend(l, s);
4402 r = sd_bus_message_exit_container(m);
4409 int sd_bus_message_read_strv(sd_bus_message *m, char ***l) {
4413 assert_return(m, -EINVAL);
4414 assert_return(m->sealed, -EPERM);
4415 assert_return(l, -EINVAL);
4417 r = bus_message_read_strv_extend(m, &strv);
4427 const char* bus_message_get_arg(sd_bus_message *m, unsigned i) {
4429 const char *t = NULL;
4434 r = sd_bus_message_rewind(m, true);
4438 for (j = 0; j <= i; j++) {
4441 r = sd_bus_message_peek_type(m, &type, NULL);
4445 if (type != SD_BUS_TYPE_STRING &&
4446 type != SD_BUS_TYPE_OBJECT_PATH &&
4447 type != SD_BUS_TYPE_SIGNATURE)
4450 r = sd_bus_message_read_basic(m, type, &t);
4458 bool bus_header_is_complete(struct bus_header *h, size_t size) {
4464 if (size < sizeof(struct bus_header))
4467 full = sizeof(struct bus_header) +
4468 (h->endian == SD_BUS_NATIVE_ENDIAN ? h->fields_size : bswap_32(h->fields_size));
4470 return size >= full;
4473 int bus_header_message_size(struct bus_header *h, size_t *sum) {
4479 if (h->endian == SD_BUS_NATIVE_ENDIAN) {
4480 fs = h->fields_size;
4482 } else if (h->endian == SD_BUS_REVERSE_ENDIAN) {
4483 fs = bswap_32(h->fields_size);
4484 bs = bswap_32(h->body_size);
4488 *sum = sizeof(struct bus_header) + ALIGN8(fs) + bs;
4492 int sd_bus_message_get_errno(sd_bus_message *m) {
4493 assert_return(m, -EINVAL);
4495 if (m->header->type != SD_BUS_MESSAGE_METHOD_ERROR)
4498 return sd_bus_error_get_errno(&m->error);
4501 const char* sd_bus_message_get_signature(sd_bus_message *m, int complete) {
4502 struct bus_container *c;
4504 assert_return(m, NULL);
4506 c = complete ? &m->root_container : message_get_container(m);
4507 return c->signature ?: "";
4510 int sd_bus_message_copy(sd_bus_message *m, sd_bus_message *source, int all) {
4511 bool done_something = false;
4514 assert_return(m, -EINVAL);
4515 assert_return(source, -EINVAL);
4516 assert_return(!m->sealed, -EPERM);
4517 assert_return(source->sealed, -EPERM);
4520 const char *contents;
4535 r = sd_bus_message_peek_type(source, &type, &contents);
4541 done_something = true;
4543 if (bus_type_is_container(type) > 0) {
4545 r = sd_bus_message_enter_container(source, type, contents);
4549 r = sd_bus_message_open_container(m, type, contents);
4553 r = sd_bus_message_copy(m, source, true);
4557 r = sd_bus_message_close_container(m);
4561 r = sd_bus_message_exit_container(source);
4568 r = sd_bus_message_read_basic(source, type, &basic);
4574 if (type == SD_BUS_TYPE_OBJECT_PATH ||
4575 type == SD_BUS_TYPE_SIGNATURE ||
4576 type == SD_BUS_TYPE_STRING)
4577 r = sd_bus_message_append_basic(m, type, basic.string);
4579 r = sd_bus_message_append_basic(m, type, &basic);
4586 return done_something;
4589 int sd_bus_message_verify_type(sd_bus_message *m, char type, const char *contents) {
4594 assert_return(m, -EINVAL);
4595 assert_return(m->sealed, -EPERM);
4596 assert_return(!type || bus_type_is_valid(type), -EINVAL);
4597 assert_return(!contents || signature_is_valid(contents, true), -EINVAL);
4598 assert_return(type || contents, -EINVAL);
4599 assert_return(!contents || !type || bus_type_is_container(type), -EINVAL);
4601 r = sd_bus_message_peek_type(m, &t, &c);
4605 if (type != 0 && type != t)
4608 if (contents && !streq_ptr(contents, c))