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_array(sd_bus_message *m, size_t index) {
2370 struct bus_container *c;
2374 c = message_get_container(m);
2378 return index >= c->begin + BUS_MESSAGE_BSWAP32(m, *c->array_size);
2381 static struct bus_body_part* find_part(sd_bus_message *m, size_t index, size_t sz, void **p) {
2382 struct bus_body_part *part;
2388 if (m->cached_rindex_part && index >= m->cached_rindex_part_begin) {
2389 part = m->cached_rindex_part;
2390 begin = m->cached_rindex_part_begin;
2400 if (index + sz <= begin + part->size) {
2402 r = bus_body_part_map(part);
2407 *p = (uint8_t*) part->data + index - begin;
2409 m->cached_rindex_part = part;
2410 m->cached_rindex_part_begin = begin;
2415 begin += part->size;
2422 static int message_peek_body(
2429 size_t k, start, end, padding;
2430 struct bus_body_part *part;
2437 if (message_end_of_array(m, *rindex))
2440 start = ALIGN_TO((size_t) *rindex, align);
2441 padding = start - *rindex;
2442 end = start + nbytes;
2444 if (end > BUS_MESSAGE_BODY_SIZE(m))
2447 part = find_part(m, *rindex, padding, (void**) &q);
2452 /* Verify padding */
2453 for (k = 0; k < padding; k++)
2458 part = find_part(m, start, nbytes, (void**) &q);
2470 static bool validate_nul(const char *s, size_t l) {
2472 /* Check for NUL chars in the string */
2473 if (memchr(s, 0, l))
2476 /* Check for NUL termination */
2483 static bool validate_string(const char *s, size_t l) {
2485 if (!validate_nul(s, l))
2488 /* Check if valid UTF8 */
2489 if (!utf8_is_valid(s))
2495 static bool validate_signature(const char *s, size_t l) {
2497 if (!validate_nul(s, l))
2500 /* Check if valid signature */
2501 if (!signature_is_valid(s, true))
2507 static bool validate_object_path(const char *s, size_t l) {
2509 if (!validate_nul(s, l))
2512 if (!object_path_is_valid(s))
2518 int sd_bus_message_read_basic(sd_bus_message *m, char type, void *p) {
2519 struct bus_container *c;
2523 assert_return(m, -EINVAL);
2524 assert_return(m->sealed, -EPERM);
2525 assert_return(bus_type_is_basic(type), -EINVAL);
2527 c = message_get_container(m);
2529 if (!c->signature || c->signature[c->index] == 0)
2532 if (message_end_of_array(m, m->rindex))
2535 if (c->signature[c->index] != type)
2540 case SD_BUS_TYPE_STRING:
2541 case SD_BUS_TYPE_OBJECT_PATH: {
2546 r = message_peek_body(m, &rindex, 4, 4, &q);
2550 l = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2551 r = message_peek_body(m, &rindex, 1, l+1, &q);
2557 if (type == SD_BUS_TYPE_OBJECT_PATH) {
2558 if (!validate_object_path(q, l))
2561 if (!validate_string(q, l))
2567 *(const char**) p = q;
2572 case SD_BUS_TYPE_SIGNATURE: {
2577 r = message_peek_body(m, &rindex, 1, 1, &q);
2582 r = message_peek_body(m, &rindex, 1, l+1, &q);
2588 if (!validate_signature(q, l))
2594 *(const char**) p = q;
2602 align = bus_type_get_alignment(type);
2603 sz = bus_type_get_size(type);
2604 assert(align > 0 && sz > 0);
2607 r = message_peek_body(m, &rindex, align, sz, &q);
2613 case SD_BUS_TYPE_BYTE:
2615 *(uint8_t*) p = *(uint8_t*) q;
2618 case SD_BUS_TYPE_BOOLEAN:
2620 *(unsigned*) p = !!*(uint32_t*) q;
2623 case SD_BUS_TYPE_INT16:
2624 case SD_BUS_TYPE_UINT16:
2626 *(uint16_t*) p = BUS_MESSAGE_BSWAP16(m, *(uint16_t*) q);
2629 case SD_BUS_TYPE_INT32:
2630 case SD_BUS_TYPE_UINT32:
2632 *(uint32_t*) p = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2635 case SD_BUS_TYPE_INT64:
2636 case SD_BUS_TYPE_UINT64:
2637 case SD_BUS_TYPE_DOUBLE:
2639 *(uint64_t*) p = BUS_MESSAGE_BSWAP64(m, *(uint64_t*) q);
2642 case SD_BUS_TYPE_UNIX_FD: {
2645 j = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2650 *(int*) p = m->fds[j];
2655 assert_not_reached("Unknown basic type...");
2664 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2670 static int bus_message_enter_array(
2672 struct bus_container *c,
2673 const char *contents,
2674 uint32_t **array_size) {
2685 if (!signature_is_single(contents, true))
2688 alignment = bus_type_get_alignment(contents[0]);
2692 if (!c->signature || c->signature[c->index] == 0)
2695 if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
2698 if (!startswith(c->signature + c->index + 1, contents))
2702 r = message_peek_body(m, &rindex, 4, 4, &q);
2706 if (BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q) > BUS_ARRAY_MAX_SIZE)
2709 r = message_peek_body(m, &rindex, alignment, 0, NULL);
2715 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2716 c->index += 1 + strlen(contents);
2720 *array_size = (uint32_t*) q;
2725 static int bus_message_enter_variant(
2727 struct bus_container *c,
2728 const char *contents) {
2739 if (!signature_is_single(contents, false))
2742 if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
2745 if (!c->signature || c->signature[c->index] == 0)
2748 if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
2752 r = message_peek_body(m, &rindex, 1, 1, &q);
2757 r = message_peek_body(m, &rindex, 1, l+1, &q);
2763 if (!validate_signature(q, l))
2766 if (!streq(q, contents))
2769 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2777 static int bus_message_enter_struct(
2779 struct bus_container *c,
2780 const char *contents) {
2789 if (!signature_is_valid(contents, false))
2792 if (!c->signature || c->signature[c->index] == 0)
2795 l = strlen(contents);
2797 if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
2798 !startswith(c->signature + c->index + 1, contents) ||
2799 c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
2802 r = message_peek_body(m, &m->rindex, 8, 0, NULL);
2806 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2807 c->index += 1 + l + 1;
2812 static int bus_message_enter_dict_entry(
2814 struct bus_container *c,
2815 const char *contents) {
2824 if (!signature_is_pair(contents))
2827 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2830 if (!c->signature || c->signature[c->index] == 0)
2833 l = strlen(contents);
2835 if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
2836 !startswith(c->signature + c->index + 1, contents) ||
2837 c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
2840 r = message_peek_body(m, &m->rindex, 8, 0, NULL);
2844 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2845 c->index += 1 + l + 1;
2850 int sd_bus_message_enter_container(sd_bus_message *m, char type, const char *contents) {
2851 struct bus_container *c, *w;
2852 uint32_t *array_size = NULL;
2857 assert_return(m, -EINVAL);
2858 assert_return(m->sealed, -EPERM);
2859 assert_return(type != 0 || !contents, -EINVAL);
2861 if (type == 0 || !contents) {
2865 /* Allow entering into anonymous containers */
2866 r = sd_bus_message_peek_type(m, &tt, &cc);
2870 if (type != 0 && type != tt)
2873 if (contents && !streq(contents, cc))
2881 * We enforce a global limit on container depth, that is much
2882 * higher than the 32 structs and 32 arrays the specification
2883 * mandates. This is simpler to implement for us, and we need
2884 * this only to ensure our container array doesn't grow
2885 * without bounds. We are happy to return any data from a
2886 * message as long as the data itself is valid, even if the
2887 * overall message might be not.
2889 * Note that the message signature is validated when
2890 * parsing the headers, and that validation does check the
2893 * Note that the specification defines no limits on the depth
2894 * of stacked variants, but we do.
2896 if (m->n_containers >= BUS_CONTAINER_DEPTH)
2899 w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
2904 c = message_get_container(m);
2906 if (!c->signature || c->signature[c->index] == 0)
2909 if (message_end_of_array(m, m->rindex))
2912 signature = strdup(contents);
2916 c->saved_index = c->index;
2919 if (type == SD_BUS_TYPE_ARRAY)
2920 r = bus_message_enter_array(m, c, contents, &array_size);
2921 else if (type == SD_BUS_TYPE_VARIANT)
2922 r = bus_message_enter_variant(m, c, contents);
2923 else if (type == SD_BUS_TYPE_STRUCT)
2924 r = bus_message_enter_struct(m, c, contents);
2925 else if (type == SD_BUS_TYPE_DICT_ENTRY)
2926 r = bus_message_enter_dict_entry(m, c, contents);
2935 /* OK, let's fill it in */
2936 w += m->n_containers++;
2937 w->enclosing = type;
2938 w->signature = signature;
2940 w->array_size = array_size;
2942 w->begin = m->rindex;
2947 int sd_bus_message_exit_container(sd_bus_message *m) {
2948 struct bus_container *c;
2950 assert_return(m, -EINVAL);
2951 assert_return(m->sealed, -EPERM);
2952 assert_return(m->n_containers > 0, -EINVAL);
2954 c = message_get_container(m);
2955 if (c->enclosing == SD_BUS_TYPE_ARRAY) {
2958 l = BUS_MESSAGE_BSWAP32(m, *c->array_size);
2959 if (c->begin + l != m->rindex)
2963 if (c->signature && c->signature[c->index] != 0)
2973 static void message_quit_container(sd_bus_message *m) {
2974 struct bus_container *c;
2978 assert(m->n_containers > 0);
2980 c = message_get_container(m);
2983 assert(m->rindex >= c->before);
2984 m->rindex = c->before;
2986 /* Free container */
2990 /* Correct index of new top-level container */
2991 c = message_get_container(m);
2992 c->index = c->saved_index;
2995 int sd_bus_message_peek_type(sd_bus_message *m, char *type, const char **contents) {
2996 struct bus_container *c;
2999 assert_return(m, -EINVAL);
3000 assert_return(m->sealed, -EPERM);
3002 c = message_get_container(m);
3004 if (!c->signature || c->signature[c->index] == 0)
3007 if (message_end_of_array(m, m->rindex))
3010 if (bus_type_is_basic(c->signature[c->index])) {
3014 *type = c->signature[c->index];
3018 if (c->signature[c->index] == SD_BUS_TYPE_ARRAY) {
3024 r = signature_element_length(c->signature+c->index+1, &l);
3030 sig = strndup(c->signature + c->index + 1, l);
3034 free(m->peeked_signature);
3035 m->peeked_signature = sig;
3041 *type = SD_BUS_TYPE_ARRAY;
3046 if (c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ||
3047 c->signature[c->index] == SD_BUS_TYPE_DICT_ENTRY_BEGIN) {
3053 r = signature_element_length(c->signature+c->index, &l);
3058 sig = strndup(c->signature + c->index + 1, l - 2);
3062 free(m->peeked_signature);
3063 m->peeked_signature = sig;
3069 *type = c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY;
3074 if (c->signature[c->index] == SD_BUS_TYPE_VARIANT) {
3080 r = message_peek_body(m, &rindex, 1, 1, &q);
3087 r = message_peek_body(m, &rindex, 1, l+1, &q);
3093 if (!validate_signature(q, l))
3100 *type = SD_BUS_TYPE_VARIANT;
3109 *type = c->enclosing;
3115 int sd_bus_message_rewind(sd_bus_message *m, int complete) {
3116 struct bus_container *c;
3118 assert_return(m, -EINVAL);
3119 assert_return(m->sealed, -EPERM);
3122 message_reset_containers(m);
3124 m->root_container.index = 0;
3126 c = message_get_container(m);
3128 c = message_get_container(m);
3131 m->rindex = c->begin;
3134 return !isempty(c->signature);
3136 static int message_read_ap(
3141 unsigned n_array, n_struct;
3142 TypeStack stack[BUS_CONTAINER_DEPTH];
3143 unsigned stack_ptr = 0;
3144 unsigned n_loop = 0;
3152 /* Ideally, we'd just call ourselves recursively on every
3153 * complex type. However, the state of a va_list that is
3154 * passed to a function is undefined after that function
3155 * returns. This means we need to docode the va_list linearly
3156 * in a single stackframe. We hence implement our own
3157 * home-grown stack in an array. */
3159 n_array = (unsigned) -1; /* lenght of current array entries */
3160 n_struct = strlen(types); /* length of current struct contents signature */
3167 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
3168 r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
3174 r = sd_bus_message_exit_container(m);
3182 if (n_array != (unsigned) -1)
3191 case SD_BUS_TYPE_BYTE:
3192 case SD_BUS_TYPE_BOOLEAN:
3193 case SD_BUS_TYPE_INT16:
3194 case SD_BUS_TYPE_UINT16:
3195 case SD_BUS_TYPE_INT32:
3196 case SD_BUS_TYPE_UINT32:
3197 case SD_BUS_TYPE_INT64:
3198 case SD_BUS_TYPE_UINT64:
3199 case SD_BUS_TYPE_DOUBLE:
3200 case SD_BUS_TYPE_STRING:
3201 case SD_BUS_TYPE_OBJECT_PATH:
3202 case SD_BUS_TYPE_SIGNATURE:
3203 case SD_BUS_TYPE_UNIX_FD: {
3206 p = va_arg(ap, void*);
3207 r = sd_bus_message_read_basic(m, *t, p);
3220 case SD_BUS_TYPE_ARRAY: {
3223 r = signature_element_length(t + 1, &k);
3229 memcpy(s, t + 1, k);
3232 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, s);
3243 if (n_array == (unsigned) -1) {
3248 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
3254 n_array = va_arg(ap, unsigned);
3259 case SD_BUS_TYPE_VARIANT: {
3262 s = va_arg(ap, const char *);
3266 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, s);
3276 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
3281 n_struct = strlen(s);
3282 n_array = (unsigned) -1;
3287 case SD_BUS_TYPE_STRUCT_BEGIN:
3288 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
3291 r = signature_element_length(t, &k);
3297 memcpy(s, t + 1, k - 2);
3300 r = sd_bus_message_enter_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
3310 if (n_array == (unsigned) -1) {
3315 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
3321 n_array = (unsigned) -1;
3334 int sd_bus_message_read(sd_bus_message *m, const char *types, ...) {
3338 assert_return(m, -EINVAL);
3339 assert_return(m->sealed, -EPERM);
3340 assert_return(types, -EINVAL);
3342 va_start(ap, types);
3343 r = message_read_ap(m, types, ap);
3349 int sd_bus_message_skip(sd_bus_message *m, const char *types) {
3352 assert_return(m, -EINVAL);
3353 assert_return(m->sealed, -EPERM);
3354 assert_return(types, -EINVAL);
3361 case SD_BUS_TYPE_BYTE:
3362 case SD_BUS_TYPE_BOOLEAN:
3363 case SD_BUS_TYPE_INT16:
3364 case SD_BUS_TYPE_UINT16:
3365 case SD_BUS_TYPE_INT32:
3366 case SD_BUS_TYPE_UINT32:
3367 case SD_BUS_TYPE_INT64:
3368 case SD_BUS_TYPE_UINT64:
3369 case SD_BUS_TYPE_DOUBLE:
3370 case SD_BUS_TYPE_STRING:
3371 case SD_BUS_TYPE_OBJECT_PATH:
3372 case SD_BUS_TYPE_SIGNATURE:
3373 case SD_BUS_TYPE_UNIX_FD:
3375 r = sd_bus_message_read_basic(m, *types, NULL);
3379 r = sd_bus_message_skip(m, types + 1);
3385 case SD_BUS_TYPE_ARRAY: {
3388 r = signature_element_length(types + 1, &k);
3394 memcpy(s, types+1, k);
3397 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, s);
3402 r = sd_bus_message_skip(m, s);
3409 r = sd_bus_message_exit_container(m);
3414 r = sd_bus_message_skip(m, types + 1 + k);
3421 case SD_BUS_TYPE_VARIANT: {
3422 const char *contents;
3425 r = sd_bus_message_peek_type(m, &x, &contents);
3429 if (x != SD_BUS_TYPE_VARIANT)
3432 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, contents);
3436 r = sd_bus_message_skip(m, contents);
3441 r = sd_bus_message_exit_container(m);
3445 r = sd_bus_message_skip(m, types + 1);
3452 case SD_BUS_TYPE_STRUCT_BEGIN:
3453 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
3456 r = signature_element_length(types, &k);
3462 memcpy(s, types+1, k-2);
3465 r = sd_bus_message_enter_container(m, *types == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
3469 r = sd_bus_message_skip(m, s);
3474 r = sd_bus_message_exit_container(m);
3479 r = sd_bus_message_skip(m, types + k);
3491 int sd_bus_message_read_array(sd_bus_message *m, char type, const void **ptr, size_t *size) {
3492 struct bus_container *c;
3498 assert_return(m, -EINVAL);
3499 assert_return(m->sealed, -EPERM);
3500 assert_return(bus_type_is_trivial(type), -EINVAL);
3501 assert_return(ptr, -EINVAL);
3502 assert_return(size, -EINVAL);
3503 assert_return(!BUS_MESSAGE_NEED_BSWAP(m), -ENOTSUP);
3505 align = bus_type_get_alignment(type);
3509 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
3513 c = message_get_container(m);
3514 sz = BUS_MESSAGE_BSWAP32(m, *c->array_size);
3516 r = message_peek_body(m, &m->rindex, align, sz, &p);
3524 r = sd_bus_message_exit_container(m);
3528 *ptr = (const void*) p;
3534 message_quit_container(m);
3538 static int message_peek_fields(
3549 return buffer_peek(BUS_MESSAGE_FIELDS(m), BUS_MESSAGE_FIELDS_SIZE(m), rindex, align, nbytes, ret);
3552 static int message_peek_field_uint32(
3563 r = message_peek_fields(m, ri, 4, 4, &q);
3568 *ret = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
3573 static int message_peek_field_string(
3575 bool (*validate)(const char *p),
3586 r = message_peek_field_uint32(m, ri, &l);
3590 r = message_peek_fields(m, ri, 1, l+1, &q);
3595 if (!validate_nul(q, l))
3601 if (!validate_string(q, l))
3611 static int message_peek_field_signature(
3623 r = message_peek_fields(m, ri, 1, 1, &q);
3628 r = message_peek_fields(m, ri, 1, l+1, &q);
3632 if (!validate_signature(q, l))
3641 static int message_skip_fields(
3644 uint32_t array_size,
3645 const char **signature) {
3647 size_t original_index;
3654 original_index = *ri;
3660 if (array_size != (uint32_t) -1 &&
3661 array_size <= *ri - original_index)
3668 if (t == SD_BUS_TYPE_STRING) {
3670 r = message_peek_field_string(m, NULL, ri, NULL);
3676 } else if (t == SD_BUS_TYPE_OBJECT_PATH) {
3678 r = message_peek_field_string(m, object_path_is_valid, ri, NULL);
3684 } else if (t == SD_BUS_TYPE_SIGNATURE) {
3686 r = message_peek_field_signature(m, ri, NULL);
3692 } else if (bus_type_is_basic(t)) {
3695 align = bus_type_get_alignment(t);
3696 k = bus_type_get_size(t);
3697 assert(align > 0 && k > 0);
3699 r = message_peek_fields(m, ri, align, k, NULL);
3705 } else if (t == SD_BUS_TYPE_ARRAY) {
3707 r = signature_element_length(*signature+1, &l);
3717 strncpy(sig, *signature + 1, l-1);
3720 alignment = bus_type_get_alignment(sig[0]);
3724 r = message_peek_field_uint32(m, ri, &nas);
3727 if (nas > BUS_ARRAY_MAX_SIZE)
3730 r = message_peek_fields(m, ri, alignment, 0, NULL);
3734 r = message_skip_fields(m, ri, nas, (const char**) &s);
3739 (*signature) += 1 + l;
3741 } else if (t == SD_BUS_TYPE_VARIANT) {
3744 r = message_peek_field_signature(m, ri, &s);
3748 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
3754 } else if (t == SD_BUS_TYPE_STRUCT ||
3755 t == SD_BUS_TYPE_DICT_ENTRY) {
3757 r = signature_element_length(*signature, &l);
3764 strncpy(sig, *signature + 1, l-1);
3767 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
3778 int bus_message_parse_fields(sd_bus_message *m) {
3781 uint32_t unix_fds = 0;
3785 for (ri = 0; ri < BUS_MESSAGE_FIELDS_SIZE(m); ) {
3786 const char *signature;
3789 r = message_peek_fields(m, &ri, 8, 1, (void**) &header);
3793 r = message_peek_field_signature(m, &ri, &signature);
3798 case _SD_BUS_MESSAGE_HEADER_INVALID:
3801 case SD_BUS_MESSAGE_HEADER_PATH:
3806 if (!streq(signature, "o"))
3809 r = message_peek_field_string(m, object_path_is_valid, &ri, &m->path);
3812 case SD_BUS_MESSAGE_HEADER_INTERFACE:
3817 if (!streq(signature, "s"))
3820 r = message_peek_field_string(m, interface_name_is_valid, &ri, &m->interface);
3823 case SD_BUS_MESSAGE_HEADER_MEMBER:
3828 if (!streq(signature, "s"))
3831 r = message_peek_field_string(m, member_name_is_valid, &ri, &m->member);
3834 case SD_BUS_MESSAGE_HEADER_ERROR_NAME:
3839 if (!streq(signature, "s"))
3842 r = message_peek_field_string(m, error_name_is_valid, &ri, &m->error.name);
3845 case SD_BUS_MESSAGE_HEADER_DESTINATION:
3850 if (!streq(signature, "s"))
3853 r = message_peek_field_string(m, service_name_is_valid, &ri, &m->destination);
3856 case SD_BUS_MESSAGE_HEADER_SENDER:
3861 if (!streq(signature, "s"))
3864 r = message_peek_field_string(m, service_name_is_valid, &ri, &m->sender);
3868 case SD_BUS_MESSAGE_HEADER_SIGNATURE: {
3872 if (m->root_container.signature)
3875 if (!streq(signature, "g"))
3878 r = message_peek_field_signature(m, &ri, &s);
3886 free(m->root_container.signature);
3887 m->root_container.signature = c;
3891 case SD_BUS_MESSAGE_HEADER_REPLY_SERIAL:
3892 if (m->reply_serial != 0)
3895 if (!streq(signature, "u"))
3898 r = message_peek_field_uint32(m, &ri, &m->reply_serial);
3902 if (m->reply_serial == 0)
3907 case SD_BUS_MESSAGE_HEADER_UNIX_FDS:
3911 if (!streq(signature, "u"))
3914 r = message_peek_field_uint32(m, &ri, &unix_fds);
3924 r = message_skip_fields(m, &ri, (uint32_t) -1, (const char **) &signature);
3931 if (m->n_fds != unix_fds)
3934 if (isempty(m->root_container.signature) != (BUS_MESSAGE_BODY_SIZE(m) == 0))
3937 switch (m->header->type) {
3939 case SD_BUS_MESSAGE_SIGNAL:
3940 if (!m->path || !m->interface || !m->member)
3944 case SD_BUS_MESSAGE_METHOD_CALL:
3946 if (!m->path || !m->member)
3951 case SD_BUS_MESSAGE_METHOD_RETURN:
3953 if (m->reply_serial == 0)
3957 case SD_BUS_MESSAGE_METHOD_ERROR:
3959 if (m->reply_serial == 0 || !m->error.name)
3964 /* Try to read the error message, but if we can't it's a non-issue */
3965 if (m->header->type == SD_BUS_MESSAGE_METHOD_ERROR)
3966 sd_bus_message_read(m, "s", &m->error.message);
3971 int bus_message_seal(sd_bus_message *m, uint64_t serial) {
3972 struct bus_body_part *part;
3982 if (m->n_containers > 0)
3988 /* If there's a non-trivial signature set, then add it in here */
3989 if (!isempty(m->root_container.signature)) {
3990 r = message_append_field_signature(m, SD_BUS_MESSAGE_HEADER_SIGNATURE, m->root_container.signature, NULL);
3996 r = message_append_field_uint32(m, SD_BUS_MESSAGE_HEADER_UNIX_FDS, m->n_fds);
4001 /* Add padding at the end of the fields part, since we know
4002 * the body needs to start at an 8 byte alignment. We made
4003 * sure we allocated enough space for this, so all we need to
4004 * do here is to zero it out. */
4005 l = BUS_MESSAGE_FIELDS_SIZE(m);
4008 memset((uint8_t*) BUS_MESSAGE_FIELDS(m) + l, 0, a);
4010 /* If this is something we can send as memfd, then let's seal
4011 the memfd now. Note that we can send memfds as payload only
4012 for directed messages, and not for broadcasts. */
4013 if (m->destination && m->bus && m->bus->use_memfd) {
4014 MESSAGE_FOREACH_PART(part, i, m)
4015 if (part->memfd >= 0 && !part->sealed && (part->size > MEMFD_MIN_SIZE || m->bus->use_memfd < 0)) {
4016 bus_body_part_unmap(part);
4018 if (ioctl(part->memfd, KDBUS_CMD_MEMFD_SEAL_SET, 1) >= 0)
4019 part->sealed = true;
4023 m->header->serial = serial;
4029 int sd_bus_message_set_destination(sd_bus_message *m, const char *destination) {
4030 assert_return(m, -EINVAL);
4031 assert_return(destination, -EINVAL);
4032 assert_return(!m->sealed, -EPERM);
4033 assert_return(!m->destination, -EEXIST);
4035 return message_append_field_string(m, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &m->destination);
4038 int bus_message_dump(sd_bus_message *m, FILE *f, bool with_header) {
4039 const char *u = NULL, *uu = NULL, *s = NULL;
4040 char **cmdline = NULL;
4043 uid_t owner, audit_loginuid;
4044 uint32_t audit_sessionid;
4060 "\tfields_size=%u\n"
4065 "\tdestination=%s\n"
4068 "\treply_serial=%u\n"
4070 "\tn_body_parts=%u\n",
4077 BUS_MESSAGE_SERIAL(m),
4078 BUS_MESSAGE_FIELDS_SIZE(m),
4079 BUS_MESSAGE_BODY_SIZE(m),
4081 strna(m->interface),
4083 strna(m->destination),
4085 strna(m->root_container.signature),
4090 if (sd_bus_error_is_set(&m->error))
4093 "\terror.message=%s\n",
4094 strna(m->error.name),
4095 strna(m->error.message));
4098 fprintf(f, "\tpid=%lu\n", (unsigned long) m->pid);
4100 fprintf(f, "\ttid=%lu\n", (unsigned long) m->tid);
4102 fprintf(f, "\tuid=%lu\n", (unsigned long) m->uid);
4104 fprintf(f, "\tgid=%lu\n", (unsigned long) m->gid);
4105 if (m->pid_starttime != 0)
4106 fprintf(f, "\tpid_starttime=%llu\n", (unsigned long long) m->pid_starttime);
4107 if (m->monotonic != 0)
4108 fprintf(f, "\tmonotonic=%llu\n", (unsigned long long) m->monotonic);
4109 if (m->realtime != 0)
4110 fprintf(f, "\trealtime=%llu\n", (unsigned long long) m->realtime);
4112 fprintf(f, "\texe=[%s]\n", m->exe);
4114 fprintf(f, "\tcomm=[%s]\n", m->comm);
4116 fprintf(f, "\ttid_comm=[%s]\n", m->tid_comm);
4118 fprintf(f, "\tlabel=[%s]\n", m->label);
4120 fprintf(f, "\tcgroup=[%s]\n", m->cgroup);
4122 sd_bus_message_get_unit(m, &u);
4124 fprintf(f, "\tunit=[%s]\n", u);
4125 sd_bus_message_get_user_unit(m, &uu);
4127 fprintf(f, "\tuser_unit=[%s]\n", uu);
4128 sd_bus_message_get_session(m, &s);
4130 fprintf(f, "\tsession=[%s]\n", s);
4131 if (sd_bus_message_get_owner_uid(m, &owner) >= 0)
4132 fprintf(f, "\towner_uid=%lu\n", (unsigned long) owner);
4133 if (sd_bus_message_get_audit_loginuid(m, &audit_loginuid) >= 0)
4134 fprintf(f, "\taudit_loginuid=%lu\n", (unsigned long) audit_loginuid);
4135 if (sd_bus_message_get_audit_sessionid(m, &audit_sessionid) >= 0)
4136 fprintf(f, "\taudit_sessionid=%lu\n", (unsigned long) audit_sessionid);
4138 r = sd_bus_message_has_effective_cap(m, 5);
4140 fprintf(f, "\tCAP_KILL=%s\n", yes_no(r));
4142 if (sd_bus_message_get_cmdline(m, &cmdline) >= 0) {
4145 fputs("\tcmdline=[", f);
4146 STRV_FOREACH(c, cmdline) {
4157 r = sd_bus_message_rewind(m, true);
4159 log_error("Failed to rewind: %s", strerror(-r));
4163 fprintf(f, "BEGIN_MESSAGE \"%s\" {\n", strempty(m->root_container.signature));
4166 _cleanup_free_ char *prefix = NULL;
4167 const char *contents = NULL;
4182 r = sd_bus_message_peek_type(m, &type, &contents);
4184 log_error("Failed to peek type: %s", strerror(-r));
4191 r = sd_bus_message_exit_container(m);
4193 log_error("Failed to exit container: %s", strerror(-r));
4199 prefix = strrep("\t", level);
4203 if (type == SD_BUS_TYPE_ARRAY)
4204 fprintf(f, "%s} END_ARRAY \n", prefix);
4205 else if (type == SD_BUS_TYPE_VARIANT)
4206 fprintf(f, "%s} END_VARIANT\n", prefix);
4207 else if (type == SD_BUS_TYPE_STRUCT)
4208 fprintf(f, "%s} END_STRUCT\n", prefix);
4209 else if (type == SD_BUS_TYPE_DICT_ENTRY)
4210 fprintf(f, "%s} END_DICT_ENTRY\n", prefix);
4215 prefix = strrep("\t", level);
4219 if (bus_type_is_container(type) > 0) {
4220 r = sd_bus_message_enter_container(m, type, contents);
4222 log_error("Failed to enter container: %s", strerror(-r));
4226 if (type == SD_BUS_TYPE_ARRAY)
4227 fprintf(f, "%sBEGIN_ARRAY \"%s\" {\n", prefix, contents);
4228 else if (type == SD_BUS_TYPE_VARIANT)
4229 fprintf(f, "%sBEGIN_VARIANT \"%s\" {\n", prefix, contents);
4230 else if (type == SD_BUS_TYPE_STRUCT)
4231 fprintf(f, "%sBEGIN_STRUCT \"%s\" {\n", prefix, contents);
4232 else if (type == SD_BUS_TYPE_DICT_ENTRY)
4233 fprintf(f, "%sBEGIN_DICT_ENTRY \"%s\" {\n", prefix, contents);
4240 r = sd_bus_message_read_basic(m, type, &basic);
4242 log_error("Failed to get basic: %s", strerror(-r));
4250 case SD_BUS_TYPE_BYTE:
4251 fprintf(f, "%sBYTE: %u\n", prefix, basic.u8);
4254 case SD_BUS_TYPE_BOOLEAN:
4255 fprintf(f, "%sBOOLEAN: %s\n", prefix, yes_no(basic.i));
4258 case SD_BUS_TYPE_INT16:
4259 fprintf(f, "%sINT16: %i\n", prefix, basic.s16);
4262 case SD_BUS_TYPE_UINT16:
4263 fprintf(f, "%sUINT16: %u\n", prefix, basic.u16);
4266 case SD_BUS_TYPE_INT32:
4267 fprintf(f, "%sINT32: %i\n", prefix, basic.s32);
4270 case SD_BUS_TYPE_UINT32:
4271 fprintf(f, "%sUINT32: %u\n", prefix, basic.u32);
4274 case SD_BUS_TYPE_INT64:
4275 fprintf(f, "%sINT64: %lli\n", prefix, (long long) basic.s64);
4278 case SD_BUS_TYPE_UINT64:
4279 fprintf(f, "%sUINT64: %llu\n", prefix, (unsigned long long) basic.u64);
4282 case SD_BUS_TYPE_DOUBLE:
4283 fprintf(f, "%sDOUBLE: %g\n", prefix, basic.d64);
4286 case SD_BUS_TYPE_STRING:
4287 fprintf(f, "%sSTRING: \"%s\"\n", prefix, basic.string);
4290 case SD_BUS_TYPE_OBJECT_PATH:
4291 fprintf(f, "%sOBJECT_PATH: \"%s\"\n", prefix, basic.string);
4294 case SD_BUS_TYPE_SIGNATURE:
4295 fprintf(f, "%sSIGNATURE: \"%s\"\n", prefix, basic.string);
4298 case SD_BUS_TYPE_UNIX_FD:
4299 fprintf(f, "%sUNIX_FD: %i\n", prefix, basic.i);
4303 assert_not_reached("Unknown basic type.");
4307 fprintf(f, "} END_MESSAGE\n");
4311 int bus_message_get_blob(sd_bus_message *m, void **buffer, size_t *sz) {
4315 struct bus_body_part *part;
4321 total = BUS_MESSAGE_SIZE(m);
4327 e = mempcpy(p, m->header, BUS_MESSAGE_BODY_BEGIN(m));
4328 MESSAGE_FOREACH_PART(part, i, m)
4329 e = mempcpy(e, part->data, part->size);
4331 assert(total == (size_t) ((uint8_t*) e - (uint8_t*) p));
4339 int bus_message_read_strv_extend(sd_bus_message *m, char ***l) {
4345 r = sd_bus_message_enter_container(m, 'a', "s");
4352 r = sd_bus_message_read_basic(m, 's', &s);
4358 r = strv_extend(l, s);
4363 r = sd_bus_message_exit_container(m);
4370 int sd_bus_message_read_strv(sd_bus_message *m, char ***l) {
4374 assert_return(m, -EINVAL);
4375 assert_return(m->sealed, -EPERM);
4376 assert_return(l, -EINVAL);
4378 r = bus_message_read_strv_extend(m, &strv);
4388 const char* bus_message_get_arg(sd_bus_message *m, unsigned i) {
4390 const char *t = NULL;
4395 r = sd_bus_message_rewind(m, true);
4399 for (j = 0; j <= i; j++) {
4402 r = sd_bus_message_peek_type(m, &type, NULL);
4406 if (type != SD_BUS_TYPE_STRING &&
4407 type != SD_BUS_TYPE_OBJECT_PATH &&
4408 type != SD_BUS_TYPE_SIGNATURE)
4411 r = sd_bus_message_read_basic(m, type, &t);
4419 bool bus_header_is_complete(struct bus_header *h, size_t size) {
4425 if (size < sizeof(struct bus_header))
4428 full = sizeof(struct bus_header) +
4429 (h->endian == SD_BUS_NATIVE_ENDIAN ? h->fields_size : bswap_32(h->fields_size));
4431 return size >= full;
4434 int bus_header_message_size(struct bus_header *h, size_t *sum) {
4440 if (h->endian == SD_BUS_NATIVE_ENDIAN) {
4441 fs = h->fields_size;
4443 } else if (h->endian == SD_BUS_REVERSE_ENDIAN) {
4444 fs = bswap_32(h->fields_size);
4445 bs = bswap_32(h->body_size);
4449 *sum = sizeof(struct bus_header) + ALIGN8(fs) + bs;
4453 int sd_bus_message_get_errno(sd_bus_message *m) {
4454 assert_return(m, -EINVAL);
4456 if (m->header->type != SD_BUS_MESSAGE_METHOD_ERROR)
4459 return sd_bus_error_get_errno(&m->error);
4462 const char* sd_bus_message_get_signature(sd_bus_message *m, int complete) {
4463 struct bus_container *c;
4465 assert_return(m, NULL);
4467 c = complete ? &m->root_container : message_get_container(m);
4468 return c->signature ?: "";
4471 int sd_bus_message_copy(sd_bus_message *m, sd_bus_message *source, int all) {
4472 bool done_something = false;
4475 assert_return(m, -EINVAL);
4476 assert_return(source, -EINVAL);
4477 assert_return(!m->sealed, -EPERM);
4478 assert_return(source->sealed, -EPERM);
4481 const char *contents;
4496 r = sd_bus_message_peek_type(source, &type, &contents);
4502 done_something = true;
4504 if (bus_type_is_container(type) > 0) {
4506 r = sd_bus_message_enter_container(source, type, contents);
4510 r = sd_bus_message_open_container(m, type, contents);
4514 r = sd_bus_message_copy(m, source, true);
4518 r = sd_bus_message_close_container(m);
4522 r = sd_bus_message_exit_container(source);
4529 r = sd_bus_message_read_basic(source, type, &basic);
4535 if (type == SD_BUS_TYPE_OBJECT_PATH ||
4536 type == SD_BUS_TYPE_SIGNATURE ||
4537 type == SD_BUS_TYPE_STRING)
4538 r = sd_bus_message_append_basic(m, type, basic.string);
4540 r = sd_bus_message_append_basic(m, type, &basic);
4547 return done_something;
4550 int sd_bus_message_verify_type(sd_bus_message *m, char type, const char *contents) {
4555 assert_return(m, -EINVAL);
4556 assert_return(m->sealed, -EPERM);
4557 assert_return(!type || bus_type_is_valid(type), -EINVAL);
4558 assert_return(!contents || signature_is_valid(contents, true), -EINVAL);
4559 assert_return(type || contents, -EINVAL);
4560 assert_return(!contents || !type || bus_type_is_container(type), -EINVAL);
4562 r = sd_bus_message_peek_type(m, &t, &c);
4566 if (type != 0 && type != t)
4569 if (contents && !streq_ptr(contents, c))