1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2013 Lennart Poettering
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
29 #include "time-util.h"
30 #include "cgroup-util.h"
33 #include "bus-message.h"
34 #include "bus-internal.h"
36 #include "bus-signature.h"
38 static int message_append_basic(sd_bus_message *m, char type, const void *p, const void **stored);
40 static void *adjust_pointer(const void *p, void *old_base, size_t sz, void *new_base) {
45 if (old_base == new_base)
48 if ((uint8_t*) p < (uint8_t*) old_base)
51 if ((uint8_t*) p >= (uint8_t*) old_base + sz)
54 return (uint8_t*) new_base + ((uint8_t*) p - (uint8_t*) old_base);
57 static void message_free_part(sd_bus_message *m, struct bus_body_part *part) {
61 if (part->memfd >= 0) {
62 /* If we can reuse the memfd, try that. For that it
63 * can't be sealed yet. */
66 bus_kernel_push_memfd(m->bus, part->memfd, part->data, part->mapped);
69 assert_se(munmap(part->data, part->mapped) == 0);
71 close_nointr_nofail(part->memfd);
74 } else if (part->munmap_this)
75 munmap(part->data, part->mapped);
76 else if (part->free_this)
83 static void message_reset_parts(sd_bus_message *m) {
84 struct bus_body_part *part;
89 while (m->n_body_parts > 0) {
90 struct bus_body_part *next = part->next;
91 message_free_part(m, part);
98 m->cached_rindex_part = NULL;
99 m->cached_rindex_part_begin = 0;
102 static void message_reset_containers(sd_bus_message *m) {
107 for (i = 0; i < m->n_containers; i++)
108 free(m->containers[i].signature);
111 m->containers = NULL;
114 m->root_container.index = 0;
117 static void message_free(sd_bus_message *m) {
123 message_reset_parts(m);
128 if (m->release_kdbus) {
131 off = (uint8_t *)m->kdbus - (uint8_t *)m->bus->kdbus_buffer;
132 ioctl(m->bus->input_fd, KDBUS_CMD_MSG_RELEASE, &off);
136 sd_bus_unref(m->bus);
139 close_many(m->fds, m->n_fds);
143 if (m->iovec != m->iovec_fixed)
146 free(m->cmdline_array);
148 message_reset_containers(m);
149 free(m->root_container.signature);
151 free(m->peeked_signature);
159 static void *message_extend_fields(sd_bus_message *m, size_t align, size_t sz) {
161 size_t old_size, new_size, start;
168 old_size = sizeof(struct bus_header) + m->header->fields_size;
169 start = ALIGN_TO(old_size, align);
170 new_size = start + sz;
172 if (old_size == new_size)
173 return (uint8_t*) m->header + old_size;
175 if (new_size > (size_t) ((uint32_t) -1))
178 if (m->free_header) {
179 np = realloc(m->header, ALIGN8(new_size));
183 /* Initially, the header is allocated as part of of
184 * the sd_bus_message itself, let's replace it by
187 np = malloc(ALIGN8(new_size));
191 memcpy(np, m->header, sizeof(struct bus_header));
194 /* Zero out padding */
195 if (start > old_size)
196 memset((uint8_t*) np + old_size, 0, start - old_size);
200 m->header->fields_size = new_size - sizeof(struct bus_header);
202 /* Adjust quick access pointers */
203 m->path = adjust_pointer(m->path, op, old_size, m->header);
204 m->interface = adjust_pointer(m->interface, op, old_size, m->header);
205 m->member = adjust_pointer(m->member, op, old_size, m->header);
206 m->destination = adjust_pointer(m->destination, op, old_size, m->header);
207 m->sender = adjust_pointer(m->sender, op, old_size, m->header);
208 m->error.name = adjust_pointer(m->error.name, op, old_size, m->header);
210 m->free_header = true;
212 return (uint8_t*) np + start;
219 static int message_append_field_string(
232 if (l > (size_t) (uint32_t) -1)
235 /* field id byte + signature length + signature 's' + NUL + string length + string + NUL */
236 p = message_extend_fields(m, 8, 4 + 4 + l + 1);
245 ((uint32_t*) p)[1] = l;
246 memcpy(p + 8, s, l + 1);
249 *ret = (char*) p + 8;
254 static int message_append_field_signature(
269 /* field id byte + signature length + signature 'g' + NUL + string length + string + NUL */
270 p = message_extend_fields(m, 8, 4 + 1 + l + 1);
276 p[2] = SD_BUS_TYPE_SIGNATURE;
279 memcpy(p + 5, s, l + 1);
282 *ret = (const char*) p + 5;
287 static int message_append_field_uint32(sd_bus_message *m, uint8_t h, uint32_t x) {
292 /* field id byte + signature length + signature 'u' + NUL + value */
293 p = message_extend_fields(m, 8, 4 + 4);
299 p[2] = SD_BUS_TYPE_UINT32;
302 ((uint32_t*) p)[1] = x;
307 int bus_message_from_header(
312 const struct ucred *ucred,
315 sd_bus_message **ret) {
318 struct bus_header *h;
321 assert(buffer || length <= 0);
322 assert(fds || n_fds <= 0);
325 if (length < sizeof(struct bus_header))
335 if (h->type == _SD_BUS_MESSAGE_TYPE_INVALID)
338 if (h->endian != SD_BUS_LITTLE_ENDIAN &&
339 h->endian != SD_BUS_BIG_ENDIAN)
342 a = ALIGN(sizeof(sd_bus_message)) + ALIGN(extra);
345 label_sz = strlen(label);
363 m->uid_valid = m->gid_valid = true;
367 m->label = (char*) m + ALIGN(sizeof(sd_bus_message)) + ALIGN(extra);
368 memcpy(m->label, label, label_sz + 1);
375 int bus_message_from_malloc(
380 const struct ucred *ucred,
382 sd_bus_message **ret) {
387 r = bus_message_from_header(buffer, length, fds, n_fds, ucred, label, 0, &m);
391 if (length != BUS_MESSAGE_SIZE(m)) {
397 m->body.data = (uint8_t*) buffer + sizeof(struct bus_header) + ALIGN8(BUS_MESSAGE_FIELDS_SIZE(m));
398 m->body.size = length - sizeof(struct bus_header) - ALIGN8(BUS_MESSAGE_FIELDS_SIZE(m));
399 m->body.sealed = true;
403 m->iovec = m->iovec_fixed;
404 m->iovec[0].iov_base = buffer;
405 m->iovec[0].iov_len = length;
407 r = bus_message_parse_fields(m);
411 /* We take possession of the memory and fds now */
412 m->free_header = true;
423 static sd_bus_message *message_new(sd_bus *bus, uint8_t type) {
426 m = malloc0(ALIGN(sizeof(sd_bus_message)) + sizeof(struct bus_header));
431 m->header = (struct bus_header*) ((uint8_t*) m + ALIGN(sizeof(struct sd_bus_message)));
432 m->header->endian = SD_BUS_NATIVE_ENDIAN;
433 m->header->type = type;
434 m->header->version = bus ? bus->message_version : 1;
435 m->allow_fds = !bus || bus->can_fds || (bus->state != BUS_HELLO && bus->state != BUS_RUNNING);
438 m->bus = sd_bus_ref(bus);
443 _public_ int sd_bus_message_new_signal(
446 const char *interface,
448 sd_bus_message **m) {
453 assert_return(!bus || bus->state != BUS_UNSET, -ENOTCONN);
454 assert_return(object_path_is_valid(path), -EINVAL);
455 assert_return(interface_name_is_valid(interface), -EINVAL);
456 assert_return(member_name_is_valid(member), -EINVAL);
457 assert_return(m, -EINVAL);
459 t = message_new(bus, SD_BUS_MESSAGE_SIGNAL);
463 t->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
465 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_PATH, SD_BUS_TYPE_OBJECT_PATH, path, &t->path);
468 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_INTERFACE, SD_BUS_TYPE_STRING, interface, &t->interface);
471 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_MEMBER, SD_BUS_TYPE_STRING, member, &t->member);
479 sd_bus_message_unref(t);
483 _public_ int sd_bus_message_new_method_call(
485 const char *destination,
487 const char *interface,
489 sd_bus_message **m) {
494 assert_return(!bus || bus->state != BUS_UNSET, -ENOTCONN);
495 assert_return(!destination || service_name_is_valid(destination), -EINVAL);
496 assert_return(object_path_is_valid(path), -EINVAL);
497 assert_return(!interface || interface_name_is_valid(interface), -EINVAL);
498 assert_return(member_name_is_valid(member), -EINVAL);
499 assert_return(m, -EINVAL);
501 t = message_new(bus, SD_BUS_MESSAGE_METHOD_CALL);
505 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_PATH, SD_BUS_TYPE_OBJECT_PATH, path, &t->path);
508 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_MEMBER, SD_BUS_TYPE_STRING, member, &t->member);
513 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_INTERFACE, SD_BUS_TYPE_STRING, interface, &t->interface);
519 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &t->destination);
532 static int message_new_reply(
534 sd_bus_message *call,
536 sd_bus_message **m) {
541 assert_return(!bus || bus->state != BUS_UNSET, -ENOTCONN);
542 assert_return(call, -EINVAL);
543 assert_return(call->sealed, -EPERM);
544 assert_return(call->header->type == SD_BUS_MESSAGE_METHOD_CALL, -EINVAL);
545 assert_return(m, -EINVAL);
547 t = message_new(bus, type);
551 t->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
552 t->reply_serial = BUS_MESSAGE_SERIAL(call);
554 r = message_append_field_uint32(t, SD_BUS_MESSAGE_HEADER_REPLY_SERIAL, t->reply_serial);
559 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, call->sender, &t->destination);
564 t->dont_send = !!(call->header->flags & SD_BUS_MESSAGE_NO_REPLY_EXPECTED);
574 _public_ int sd_bus_message_new_method_return(
576 sd_bus_message *call,
577 sd_bus_message **m) {
579 return message_new_reply(bus, call, SD_BUS_MESSAGE_METHOD_RETURN, m);
582 _public_ int sd_bus_message_new_method_error(
584 sd_bus_message *call,
585 const sd_bus_error *e,
586 sd_bus_message **m) {
591 assert_return(sd_bus_error_is_set(e), -EINVAL);
592 assert_return(m, -EINVAL);
594 r = message_new_reply(bus, call, SD_BUS_MESSAGE_METHOD_ERROR, &t);
598 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_ERROR_NAME, SD_BUS_TYPE_STRING, e->name, &t->error.name);
603 r = message_append_basic(t, SD_BUS_TYPE_STRING, e->message, (const void**) &t->error.message);
616 _public_ int sd_bus_message_new_method_errorf(
618 sd_bus_message *call,
624 _cleanup_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
628 assert_return(name, -EINVAL);
629 assert_return(m, -EINVAL);
631 va_start(ap, format);
632 r = bus_error_setfv(&error, name, format, ap);
638 return sd_bus_message_new_method_error(bus, call, &error, m);
641 _public_ int sd_bus_message_new_method_errno(
643 sd_bus_message *call,
645 const sd_bus_error *p,
646 sd_bus_message **m) {
648 _cleanup_free_ sd_bus_error berror = SD_BUS_ERROR_NULL;
650 if (sd_bus_error_is_set(p))
651 return sd_bus_message_new_method_error(bus, call, p, m);
653 sd_bus_error_set_errno(&berror, error);
655 return sd_bus_message_new_method_error(bus, call, &berror, m);
658 _public_ int sd_bus_message_new_method_errnof(
660 sd_bus_message *call,
666 _cleanup_free_ sd_bus_error berror = SD_BUS_ERROR_NULL;
670 va_start(ap, format);
671 r = bus_error_set_errnofv(&berror, error, format, ap);
677 return sd_bus_message_new_method_error(bus, call, &berror, m);
680 int bus_message_new_synthetic_error(
683 const sd_bus_error *e,
684 sd_bus_message **m) {
689 assert(sd_bus_error_is_set(e));
692 t = message_new(bus, SD_BUS_MESSAGE_METHOD_ERROR);
696 t->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
697 t->reply_serial = serial;
699 r = message_append_field_uint32(t, SD_BUS_MESSAGE_HEADER_REPLY_SERIAL, t->reply_serial);
703 if (bus && bus->unique_name) {
704 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, bus->unique_name, &t->destination);
709 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_ERROR_NAME, SD_BUS_TYPE_STRING, e->name, &t->error.name);
714 r = message_append_basic(t, SD_BUS_TYPE_STRING, e->message, (const void**) &t->error.message);
727 _public_ sd_bus_message* sd_bus_message_ref(sd_bus_message *m) {
728 assert_return(m, NULL);
730 assert(m->n_ref > 0);
736 _public_ sd_bus_message* sd_bus_message_unref(sd_bus_message *m) {
737 assert_return(m, NULL);
739 assert(m->n_ref > 0);
748 _public_ int sd_bus_message_get_type(sd_bus_message *m, uint8_t *type) {
749 assert_return(m, -EINVAL);
750 assert_return(type, -EINVAL);
752 *type = m->header->type;
756 _public_ int sd_bus_message_get_serial(sd_bus_message *m, uint64_t *serial) {
757 assert_return(m, -EINVAL);
758 assert_return(serial, -EINVAL);
759 assert_return(m->header->serial != 0, -ENOENT);
761 *serial = BUS_MESSAGE_SERIAL(m);
765 _public_ int sd_bus_message_get_reply_serial(sd_bus_message *m, uint64_t *serial) {
766 assert_return(m, -EINVAL);
767 assert_return(serial, -EINVAL);
768 assert_return(m->reply_serial != 0, -ENOENT);
770 *serial = m->reply_serial;
774 _public_ int sd_bus_message_get_no_reply(sd_bus_message *m) {
775 assert_return(m, -EINVAL);
777 return m->header->type == SD_BUS_MESSAGE_METHOD_CALL ? !!(m->header->flags & SD_BUS_MESSAGE_NO_REPLY_EXPECTED) : 0;
780 _public_ const char *sd_bus_message_get_path(sd_bus_message *m) {
781 assert_return(m, NULL);
786 _public_ const char *sd_bus_message_get_interface(sd_bus_message *m) {
787 assert_return(m, NULL);
792 _public_ const char *sd_bus_message_get_member(sd_bus_message *m) {
793 assert_return(m, NULL);
798 _public_ const char *sd_bus_message_get_destination(sd_bus_message *m) {
799 assert_return(m, NULL);
801 return m->destination;
804 _public_ const char *sd_bus_message_get_sender(sd_bus_message *m) {
805 assert_return(m, NULL);
810 _public_ const sd_bus_error *sd_bus_message_get_error(sd_bus_message *m) {
811 assert_return(m, NULL);
812 assert_return(sd_bus_error_is_set(&m->error), NULL);
817 _public_ int sd_bus_message_get_uid(sd_bus_message *m, uid_t *uid) {
818 assert_return(m, -EINVAL);
819 assert_return(uid, -EINVAL);
820 assert_return(m->uid_valid, -ESRCH);
826 _public_ int sd_bus_message_get_gid(sd_bus_message *m, gid_t *gid) {
827 assert_return(m, -EINVAL);
828 assert_return(gid, -EINVAL);
829 assert_return(m->gid_valid, -ESRCH);
835 _public_ int sd_bus_message_get_pid(sd_bus_message *m, pid_t *pid) {
836 assert_return(m, -EINVAL);
837 assert_return(pid, -EINVAL);
838 assert_return(m->pid > 0, -ESRCH);
844 _public_ int sd_bus_message_get_tid(sd_bus_message *m, pid_t *tid) {
845 assert_return(m, -EINVAL);
846 assert_return(tid, -EINVAL);
847 assert_return(m->tid > 0, -ESRCH);
853 _public_ int sd_bus_message_get_pid_starttime(sd_bus_message *m, uint64_t *usec) {
854 assert_return(m, -EINVAL);
855 assert_return(usec, -EINVAL);
856 assert_return(m->pid_starttime > 0, -ESRCH);
858 *usec = m->pid_starttime;
862 _public_ int sd_bus_message_get_selinux_context(sd_bus_message *m, const char **ret) {
863 assert_return(m, -EINVAL);
864 assert_return(m->label, -ESRCH);
870 _public_ int sd_bus_message_get_monotonic_timestamp(sd_bus_message *m, uint64_t *usec) {
871 assert_return(m, -EINVAL);
872 assert_return(usec, -EINVAL);
873 assert_return(m->monotonic > 0, -ESRCH);
875 *usec = m->monotonic;
879 _public_ int sd_bus_message_get_realtime_timestamp(sd_bus_message *m, uint64_t *usec) {
880 assert_return(m, -EINVAL);
881 assert_return(usec, -EINVAL);
882 assert_return(m->realtime > 0, -ESRCH);
888 _public_ int sd_bus_message_get_comm(sd_bus_message *m, const char **ret) {
889 assert_return(m, -EINVAL);
890 assert_return(ret, -EINVAL);
891 assert_return(m->comm, -ESRCH);
897 _public_ int sd_bus_message_get_tid_comm(sd_bus_message *m, const char **ret) {
898 assert_return(m, -EINVAL);
899 assert_return(ret, -EINVAL);
900 assert_return(m->tid_comm, -ESRCH);
906 _public_ int sd_bus_message_get_exe(sd_bus_message *m, const char **ret) {
907 assert_return(m, -EINVAL);
908 assert_return(ret, -EINVAL);
909 assert_return(m->exe, -ESRCH);
915 _public_ int sd_bus_message_get_cgroup(sd_bus_message *m, const char **ret) {
916 assert_return(m, -EINVAL);
917 assert_return(ret, -EINVAL);
918 assert_return(m->cgroup, -ESRCH);
924 _public_ int sd_bus_message_get_unit(sd_bus_message *m, const char **ret) {
927 assert_return(m, -EINVAL);
928 assert_return(ret, -EINVAL);
929 assert_return(m->cgroup, -ESRCH);
932 r = cg_path_get_unit(m->cgroup, &m->unit);
941 _public_ int sd_bus_message_get_user_unit(sd_bus_message *m, const char **ret) {
944 assert_return(m, -EINVAL);
945 assert_return(ret, -EINVAL);
946 assert_return(m->cgroup, -ESRCH);
949 r = cg_path_get_user_unit(m->cgroup, &m->user_unit);
958 _public_ int sd_bus_message_get_session(sd_bus_message *m, const char **ret) {
961 assert_return(m, -EINVAL);
962 assert_return(ret, -EINVAL);
963 assert_return(m->cgroup, -ESRCH);
966 r = cg_path_get_session(m->cgroup, &m->session);
975 _public_ int sd_bus_message_get_owner_uid(sd_bus_message *m, uid_t *uid) {
976 assert_return(m, -EINVAL);
977 assert_return(uid, -EINVAL);
978 assert_return(m->cgroup, -ESRCH);
980 return cg_path_get_owner_uid(m->cgroup, uid);
983 _public_ int sd_bus_message_get_cmdline(sd_bus_message *m, char ***cmdline) {
988 assert_return(m, -EINVAL);
989 assert_return(m->cmdline, -ESRCH);
991 for (p = m->cmdline, n = 0; p < m->cmdline + m->cmdline_length; p++)
995 m->cmdline_array = new(char*, n + 1);
996 if (!m->cmdline_array)
999 for (p = m->cmdline, i = 0, first = true; p < m->cmdline + m->cmdline_length; p++) {
1001 m->cmdline_array[i++] = (char*) p;
1006 m->cmdline_array[i] = NULL;
1007 *cmdline = m->cmdline_array;
1012 _public_ int sd_bus_message_get_audit_sessionid(sd_bus_message *m, uint32_t *sessionid) {
1013 assert_return(m, -EINVAL);
1014 assert_return(sessionid, -EINVAL);
1015 assert_return(m->audit, -ESRCH);
1017 *sessionid = m->audit->sessionid;
1021 _public_ int sd_bus_message_get_audit_loginuid(sd_bus_message *m, uid_t *uid) {
1022 assert_return(m, -EINVAL);
1023 assert_return(uid, -EINVAL);
1024 assert_return(m->audit, -ESRCH);
1026 *uid = m->audit->loginuid;
1030 _public_ int sd_bus_message_has_effective_cap(sd_bus_message *m, int capability) {
1033 assert_return(m, -EINVAL);
1034 assert_return(capability < 0, -EINVAL);
1035 assert_return(!m->capability, -ESRCH);
1037 sz = m->capability_size / 4;
1038 if ((unsigned) capability >= sz*8)
1041 return !!(m->capability[2 * sz + (capability / 8)] & (1 << (capability % 8)));
1044 _public_ int sd_bus_message_is_signal(sd_bus_message *m,
1045 const char *interface,
1046 const char *member) {
1047 assert_return(m, -EINVAL);
1049 if (m->header->type != SD_BUS_MESSAGE_SIGNAL)
1052 if (interface && (!m->interface || !streq(m->interface, interface)))
1055 if (member && (!m->member || !streq(m->member, member)))
1061 _public_ int sd_bus_message_is_method_call(sd_bus_message *m,
1062 const char *interface,
1063 const char *member) {
1064 assert_return(m, -EINVAL);
1066 if (m->header->type != SD_BUS_MESSAGE_METHOD_CALL)
1069 if (interface && (!m->interface || !streq(m->interface, interface)))
1072 if (member && (!m->member || !streq(m->member, member)))
1078 _public_ int sd_bus_message_is_method_error(sd_bus_message *m, const char *name) {
1079 assert_return(m, -EINVAL);
1081 if (m->header->type != SD_BUS_MESSAGE_METHOD_ERROR)
1084 if (name && (!m->error.name || !streq(m->error.name, name)))
1090 _public_ int sd_bus_message_set_no_reply(sd_bus_message *m, int b) {
1091 assert_return(m, -EINVAL);
1092 assert_return(!m->sealed, -EPERM);
1093 assert_return(m->header->type == SD_BUS_MESSAGE_METHOD_CALL, -EPERM);
1096 m->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
1098 m->header->flags &= ~SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
1103 static struct bus_container *message_get_container(sd_bus_message *m) {
1106 if (m->n_containers == 0)
1107 return &m->root_container;
1109 assert(m->containers);
1110 return m->containers + m->n_containers - 1;
1113 struct bus_body_part *message_append_part(sd_bus_message *m) {
1114 struct bus_body_part *part;
1121 if (m->n_body_parts <= 0) {
1125 assert(m->body_end);
1127 part = new0(struct bus_body_part, 1);
1133 m->body_end->next = part;
1143 static void part_zero(struct bus_body_part *part, size_t sz) {
1148 /* All other fields can be left in their defaults */
1149 assert(!part->data);
1150 assert(part->memfd < 0);
1153 part->is_zero = true;
1154 part->sealed = true;
1157 static int part_make_space(
1158 struct sd_bus_message *m,
1159 struct bus_body_part *part,
1168 assert(!part->sealed);
1173 if (!part->data && part->memfd < 0)
1174 part->memfd = bus_kernel_pop_memfd(m->bus, &part->data, &part->mapped);
1176 if (part->memfd >= 0) {
1179 r = ioctl(part->memfd, KDBUS_CMD_MEMFD_SIZE_SET, &u);
1185 if (!part->data || sz > part->mapped) {
1186 size_t psz = PAGE_ALIGN(sz > 0 ? sz : 1);
1188 if (part->mapped <= 0)
1189 n = mmap(NULL, psz, PROT_READ|PROT_WRITE, MAP_SHARED, part->memfd, 0);
1191 n = mremap(part->data, part->mapped, psz, MREMAP_MAYMOVE);
1193 if (n == MAP_FAILED) {
1202 part->munmap_this = true;
1204 n = realloc(part->data, MAX(sz, 1u));
1211 part->free_this = true;
1215 *q = part->data ? (uint8_t*) part->data + part->size : NULL;
1221 static void message_extend_containers(sd_bus_message *m, size_t expand) {
1222 struct bus_container *c;
1229 /* Update counters */
1230 for (c = m->containers; c < m->containers + m->n_containers; c++)
1232 *c->array_size += expand;
1235 static void *message_extend_body(sd_bus_message *m, size_t align, size_t sz) {
1236 struct bus_body_part *part = NULL;
1237 size_t start_body, end_body, padding, start_part, end_part, added;
1249 start_body = ALIGN_TO((size_t) m->header->body_size, align);
1250 end_body = start_body + sz;
1252 padding = start_body - m->header->body_size;
1253 added = padding + sz;
1255 /* Check for 32bit overflows */
1256 if (end_body > (size_t) ((uint32_t) -1)) {
1262 m->n_body_parts <= 0 ||
1263 m->body_end->sealed ||
1264 padding != ALIGN_TO(m->body_end->size, align) - m->body_end->size;
1268 part = message_append_part(m);
1272 part_zero(part, padding);
1275 part = message_append_part(m);
1279 r = part_make_space(m, part, sz, &p);
1283 struct bus_container *c;
1291 start_part = ALIGN_TO(part->size, align);
1292 end_part = start_part + sz;
1294 r = part_make_space(m, part, end_part, &p);
1299 memset(p, 0, padding);
1300 p = (uint8_t*) p + padding;
1303 /* Readjust pointers */
1304 for (c = m->containers; c < m->containers + m->n_containers; c++)
1305 c->array_size = adjust_pointer(c->array_size, op, os, part->data);
1307 m->error.message = (const char*) adjust_pointer(m->error.message, op, os, part->data);
1310 m->header->body_size = end_body;
1311 message_extend_containers(m, added);
1316 int message_append_basic(sd_bus_message *m, char type, const void *p, const void **stored) {
1317 struct bus_container *c;
1325 assert_return(m, -EINVAL);
1326 assert_return(!m->sealed, -EPERM);
1327 assert_return(bus_type_is_basic(type), -EINVAL);
1328 assert_return(!m->poisoned, -ESTALE);
1330 c = message_get_container(m);
1332 if (c->signature && c->signature[c->index]) {
1333 /* Container signature is already set */
1335 if (c->signature[c->index] != type)
1340 /* Maybe we can append to the signature? But only if this is the top-level container*/
1341 if (c->enclosing != 0)
1344 e = strextend(&c->signature, CHAR_TO_STR(type), NULL);
1353 case SD_BUS_TYPE_STRING:
1354 /* To make things easy we'll serialize a NULL string
1355 * into the empty string */
1358 /* Fall through... */
1359 case SD_BUS_TYPE_OBJECT_PATH:
1367 sz = 4 + strlen(p) + 1;
1370 case SD_BUS_TYPE_SIGNATURE:
1378 sz = 1 + strlen(p) + 1;
1381 case SD_BUS_TYPE_BOOLEAN:
1390 assert_cc(sizeof(int) == sizeof(uint32_t));
1396 case SD_BUS_TYPE_UNIX_FD: {
1404 if (!m->allow_fds) {
1417 fd = fcntl(z, F_DUPFD_CLOEXEC, 3);
1423 f = realloc(m->fds, sizeof(int) * (m->n_fds + 1));
1443 align = bus_type_get_alignment(type);
1444 sz = bus_type_get_size(type);
1451 a = message_extend_body(m, align, sz);
1457 if (type == SD_BUS_TYPE_STRING || type == SD_BUS_TYPE_OBJECT_PATH) {
1458 *(uint32_t*) a = sz - 5;
1459 memcpy((uint8_t*) a + 4, p, sz - 4);
1462 *stored = (const uint8_t*) a + 4;
1464 } else if (type == SD_BUS_TYPE_SIGNATURE) {
1465 *(uint8_t*) a = sz - 1;
1466 memcpy((uint8_t*) a + 1, p, sz - 1);
1469 *stored = (const uint8_t*) a + 1;
1470 } else if (type == SD_BUS_TYPE_UNIX_FD) {
1471 *(uint32_t*) a = fdi;
1485 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1492 close_nointr_nofail(fd);
1497 _public_ int sd_bus_message_append_basic(sd_bus_message *m, char type, const void *p) {
1498 return message_append_basic(m, type, p, NULL);
1501 _public_ int sd_bus_message_append_string_space(
1506 struct bus_container *c;
1509 assert_return(m, -EINVAL);
1510 assert_return(s, -EINVAL);
1511 assert_return(!m->sealed, -EPERM);
1512 assert_return(!m->poisoned, -ESTALE);
1514 c = message_get_container(m);
1516 if (c->signature && c->signature[c->index]) {
1517 /* Container signature is already set */
1519 if (c->signature[c->index] != SD_BUS_TYPE_STRING)
1524 /* Maybe we can append to the signature? But only if this is the top-level container*/
1525 if (c->enclosing != 0)
1528 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRING), NULL);
1535 a = message_extend_body(m, 4, 4 + size + 1);
1539 *(uint32_t*) a = size;
1544 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1550 _public_ int sd_bus_message_append_string_iovec(
1552 const struct iovec *iov,
1560 assert_return(m, -EINVAL);
1561 assert_return(!m->sealed, -EPERM);
1562 assert_return(iov || n == 0, -EINVAL);
1563 assert_return(!m->poisoned, -ESTALE);
1565 size = IOVEC_TOTAL_SIZE(iov, n);
1567 r = sd_bus_message_append_string_space(m, size, &p);
1571 for (i = 0; i < n; i++) {
1573 if (iov[i].iov_base)
1574 memcpy(p, iov[i].iov_base, iov[i].iov_len);
1576 memset(p, ' ', iov[i].iov_len);
1578 p += iov[i].iov_len;
1584 static int bus_message_open_array(
1586 struct bus_container *c,
1587 const char *contents,
1588 uint32_t **array_size) {
1594 struct bus_body_part *o;
1601 if (!signature_is_single(contents, true))
1604 alignment = bus_type_get_alignment(contents[0]);
1608 if (c->signature && c->signature[c->index]) {
1610 /* Verify the existing signature */
1612 if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
1615 if (!startswith(c->signature + c->index + 1, contents))
1618 nindex = c->index + 1 + strlen(contents);
1622 if (c->enclosing != 0)
1625 /* Extend the existing signature */
1627 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_ARRAY), contents, NULL);
1633 nindex = e - c->signature;
1636 a = message_extend_body(m, 4, 4);
1641 op = m->body_end->data;
1642 os = m->body_end->size;
1644 /* Add alignment between size and first element */
1645 if (!message_extend_body(m, alignment, 0))
1648 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1651 /* location of array size might have changed so let's readjust a */
1652 if (o == m->body_end)
1653 a = adjust_pointer(a, op, os, m->body_end->data);
1660 static int bus_message_open_variant(
1662 struct bus_container *c,
1663 const char *contents) {
1672 if (!signature_is_single(contents, false))
1675 if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
1678 if (c->signature && c->signature[c->index]) {
1680 if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
1686 if (c->enclosing != 0)
1689 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_VARIANT), NULL);
1696 l = strlen(contents);
1697 a = message_extend_body(m, 1, 1 + l + 1);
1702 memcpy((uint8_t*) a + 1, contents, l + 1);
1704 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1710 static int bus_message_open_struct(
1712 struct bus_container *c,
1713 const char *contents) {
1721 if (!signature_is_valid(contents, false))
1724 if (c->signature && c->signature[c->index]) {
1727 l = strlen(contents);
1729 if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
1730 !startswith(c->signature + c->index + 1, contents) ||
1731 c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
1734 nindex = c->index + 1 + l + 1;
1738 if (c->enclosing != 0)
1741 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_BEGIN), contents, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_END), NULL);
1747 nindex = e - c->signature;
1750 /* Align contents to 8 byte boundary */
1751 if (!message_extend_body(m, 8, 0))
1754 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1760 static int bus_message_open_dict_entry(
1762 struct bus_container *c,
1763 const char *contents) {
1771 if (!signature_is_pair(contents))
1774 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1777 if (c->signature && c->signature[c->index]) {
1780 l = strlen(contents);
1782 if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
1783 !startswith(c->signature + c->index + 1, contents) ||
1784 c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
1787 nindex = c->index + 1 + l + 1;
1791 /* Align contents to 8 byte boundary */
1792 if (!message_extend_body(m, 8, 0))
1795 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1801 _public_ int sd_bus_message_open_container(
1804 const char *contents) {
1806 struct bus_container *c, *w;
1807 uint32_t *array_size = NULL;
1812 assert_return(m, -EINVAL);
1813 assert_return(!m->sealed, -EPERM);
1814 assert_return(contents, -EINVAL);
1815 assert_return(!m->poisoned, -ESTALE);
1817 /* Make sure we have space for one more container */
1818 w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
1826 c = message_get_container(m);
1828 signature = strdup(contents);
1834 /* Save old index in the parent container, in case we have to
1835 * abort this container */
1836 c->saved_index = c->index;
1837 before = m->header->body_size;
1839 if (type == SD_BUS_TYPE_ARRAY)
1840 r = bus_message_open_array(m, c, contents, &array_size);
1841 else if (type == SD_BUS_TYPE_VARIANT)
1842 r = bus_message_open_variant(m, c, contents);
1843 else if (type == SD_BUS_TYPE_STRUCT)
1844 r = bus_message_open_struct(m, c, contents);
1845 else if (type == SD_BUS_TYPE_DICT_ENTRY)
1846 r = bus_message_open_dict_entry(m, c, contents);
1855 /* OK, let's fill it in */
1856 w += m->n_containers++;
1857 w->enclosing = type;
1858 w->signature = signature;
1860 w->array_size = array_size;
1862 w->begin = m->rindex;
1867 _public_ int sd_bus_message_close_container(sd_bus_message *m) {
1868 struct bus_container *c;
1870 assert_return(m, -EINVAL);
1871 assert_return(!m->sealed, -EPERM);
1872 assert_return(m->n_containers > 0, -EINVAL);
1873 assert_return(!m->poisoned, -ESTALE);
1875 c = message_get_container(m);
1876 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1877 if (c->signature && c->signature[c->index] != 0)
1892 static int type_stack_push(TypeStack *stack, unsigned max, unsigned *i, const char *types, unsigned n_struct, unsigned n_array) {
1899 stack[*i].types = types;
1900 stack[*i].n_struct = n_struct;
1901 stack[*i].n_array = n_array;
1907 static int type_stack_pop(TypeStack *stack, unsigned max, unsigned *i, const char **types, unsigned *n_struct, unsigned *n_array) {
1918 *types = stack[*i].types;
1919 *n_struct = stack[*i].n_struct;
1920 *n_array = stack[*i].n_array;
1925 int bus_message_append_ap(
1930 unsigned n_array, n_struct;
1931 TypeStack stack[BUS_CONTAINER_DEPTH];
1932 unsigned stack_ptr = 0;
1940 n_array = (unsigned) -1;
1941 n_struct = strlen(types);
1946 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
1947 r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
1953 r = sd_bus_message_close_container(m);
1961 if (n_array != (unsigned) -1)
1970 case SD_BUS_TYPE_BYTE: {
1973 x = (uint8_t) va_arg(ap, int);
1974 r = sd_bus_message_append_basic(m, *t, &x);
1978 case SD_BUS_TYPE_BOOLEAN:
1979 case SD_BUS_TYPE_INT32:
1980 case SD_BUS_TYPE_UINT32:
1981 case SD_BUS_TYPE_UNIX_FD: {
1984 /* We assume a boolean is the same as int32_t */
1985 assert_cc(sizeof(int32_t) == sizeof(int));
1987 x = va_arg(ap, uint32_t);
1988 r = sd_bus_message_append_basic(m, *t, &x);
1992 case SD_BUS_TYPE_INT16:
1993 case SD_BUS_TYPE_UINT16: {
1996 x = (uint16_t) va_arg(ap, int);
1997 r = sd_bus_message_append_basic(m, *t, &x);
2001 case SD_BUS_TYPE_INT64:
2002 case SD_BUS_TYPE_UINT64:
2003 case SD_BUS_TYPE_DOUBLE: {
2006 x = va_arg(ap, uint64_t);
2007 r = sd_bus_message_append_basic(m, *t, &x);
2011 case SD_BUS_TYPE_STRING:
2012 case SD_BUS_TYPE_OBJECT_PATH:
2013 case SD_BUS_TYPE_SIGNATURE: {
2016 x = va_arg(ap, const char*);
2017 r = sd_bus_message_append_basic(m, *t, x);
2021 case SD_BUS_TYPE_ARRAY: {
2024 r = signature_element_length(t + 1, &k);
2030 memcpy(s, t + 1, k);
2033 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, s);
2038 if (n_array == (unsigned) -1) {
2043 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2049 n_array = va_arg(ap, unsigned);
2054 case SD_BUS_TYPE_VARIANT: {
2057 s = va_arg(ap, const char*);
2061 r = sd_bus_message_open_container(m, SD_BUS_TYPE_VARIANT, s);
2065 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2070 n_struct = strlen(s);
2071 n_array = (unsigned) -1;
2076 case SD_BUS_TYPE_STRUCT_BEGIN:
2077 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
2080 r = signature_element_length(t, &k);
2087 memcpy(s, t + 1, k - 2);
2090 r = sd_bus_message_open_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
2095 if (n_array == (unsigned) -1) {
2100 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2106 n_array = (unsigned) -1;
2122 _public_ int sd_bus_message_append(sd_bus_message *m, const char *types, ...) {
2126 assert_return(m, -EINVAL);
2127 assert_return(types, -EINVAL);
2128 assert_return(!m->sealed, -EPERM);
2129 assert_return(!m->poisoned, -ESTALE);
2131 va_start(ap, types);
2132 r = bus_message_append_ap(m, types, ap);
2138 _public_ int sd_bus_message_append_array_space(sd_bus_message *m,
2146 assert_return(m, -EINVAL);
2147 assert_return(!m->sealed, -EPERM);
2148 assert_return(bus_type_is_trivial(type), -EINVAL);
2149 assert_return(ptr || size == 0, -EINVAL);
2150 assert_return(!m->poisoned, -ESTALE);
2152 align = bus_type_get_alignment(type);
2153 sz = bus_type_get_size(type);
2155 assert_se(align > 0);
2161 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
2165 a = message_extend_body(m, align, size);
2169 r = sd_bus_message_close_container(m);
2177 _public_ int sd_bus_message_append_array(sd_bus_message *m,
2184 assert_return(m, -EINVAL);
2185 assert_return(!m->sealed, -EPERM);
2186 assert_return(bus_type_is_trivial(type), -EINVAL);
2187 assert_return(ptr || size == 0, -EINVAL);
2188 assert_return(!m->poisoned, -ESTALE);
2190 r = sd_bus_message_append_array_space(m, type, size, &p);
2195 memcpy(p, ptr, size);
2200 _public_ int sd_bus_message_append_array_iovec(
2203 const struct iovec *iov,
2211 assert_return(m, -EINVAL);
2212 assert_return(!m->sealed, -EPERM);
2213 assert_return(bus_type_is_trivial(type), -EINVAL);
2214 assert_return(iov || n == 0, -EINVAL);
2215 assert_return(!m->poisoned, -ESTALE);
2217 size = IOVEC_TOTAL_SIZE(iov, n);
2219 r = sd_bus_message_append_array_space(m, type, size, &p);
2223 for (i = 0; i < n; i++) {
2225 if (iov[i].iov_base)
2226 memcpy(p, iov[i].iov_base, iov[i].iov_len);
2228 memset(p, 0, iov[i].iov_len);
2230 p = (uint8_t*) p + iov[i].iov_len;
2236 _public_ int sd_bus_message_append_array_memfd(sd_bus_message *m,
2239 _cleanup_close_ int copy_fd = -1;
2240 struct bus_body_part *part;
2252 if (!bus_type_is_trivial(type))
2257 r = sd_memfd_set_sealed(memfd, true);
2261 copy_fd = sd_memfd_dup_fd(memfd);
2265 r = sd_memfd_get_size(memfd, &size);
2269 align = bus_type_get_alignment(type);
2270 sz = bus_type_get_size(type);
2272 assert_se(align > 0);
2278 if (size > (uint64_t) (uint32_t) -1)
2281 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
2285 a = message_extend_body(m, align, 0);
2289 part = message_append_part(m);
2293 part->memfd = copy_fd;
2294 part->sealed = true;
2298 message_extend_containers(m, size);
2299 m->header->body_size += size;
2301 return sd_bus_message_close_container(m);
2304 _public_ int sd_bus_message_append_string_memfd(sd_bus_message *m, sd_memfd *memfd) {
2305 _cleanup_close_ int copy_fd = -1;
2306 struct bus_body_part *part;
2307 struct bus_container *c;
2312 assert_return(m, -EINVAL);
2313 assert_return(memfd, -EINVAL);
2314 assert_return(!m->sealed, -EPERM);
2315 assert_return(!m->poisoned, -ESTALE);
2317 r = sd_memfd_set_sealed(memfd, true);
2321 copy_fd = sd_memfd_dup_fd(memfd);
2325 r = sd_memfd_get_size(memfd, &size);
2329 /* We require this to be NUL terminated */
2333 if (size > (uint64_t) (uint32_t) -1)
2336 c = message_get_container(m);
2337 if (c->signature && c->signature[c->index]) {
2338 /* Container signature is already set */
2340 if (c->signature[c->index] != SD_BUS_TYPE_STRING)
2345 /* Maybe we can append to the signature? But only if this is the top-level container*/
2346 if (c->enclosing != 0)
2349 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRING), NULL);
2356 a = message_extend_body(m, 4, 4);
2360 *(uint32_t*) a = size - 1;
2362 part = message_append_part(m);
2366 part->memfd = copy_fd;
2367 part->sealed = true;
2371 message_extend_containers(m, size);
2372 m->header->body_size += size;
2374 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2380 _public_ int sd_bus_message_append_strv(sd_bus_message *m, char **l) {
2384 assert_return(m, -EINVAL);
2385 assert_return(!m->sealed, -EPERM);
2386 assert_return(!m->poisoned, -ESTALE);
2388 r = sd_bus_message_open_container(m, 'a', "s");
2392 STRV_FOREACH(i, l) {
2393 r = sd_bus_message_append_basic(m, 's', *i);
2398 return sd_bus_message_close_container(m);
2401 int bus_body_part_map(struct bus_body_part *part) {
2410 if (part->size <= 0)
2413 /* For smaller zero parts (as used for padding) we don't need to map anything... */
2414 if (part->memfd < 0 && part->is_zero && part->size < 8) {
2415 static const uint8_t zeroes[7] = { };
2416 part->data = (void*) zeroes;
2420 psz = PAGE_ALIGN(part->size);
2422 if (part->memfd >= 0)
2423 p = mmap(NULL, psz, PROT_READ, MAP_SHARED, part->memfd, 0);
2424 else if (part->is_zero)
2425 p = mmap(NULL, psz, PROT_READ, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
2429 if (p == MAP_FAILED)
2434 part->munmap_this = true;
2439 void bus_body_part_unmap(struct bus_body_part *part) {
2443 if (part->memfd < 0)
2449 if (!part->munmap_this)
2452 assert_se(munmap(part->data, part->mapped) == 0);
2456 part->munmap_this = false;
2461 static int buffer_peek(const void *p, uint32_t sz, size_t *rindex, size_t align, size_t nbytes, void **r) {
2462 size_t k, start, end;
2467 start = ALIGN_TO((size_t) *rindex, align);
2468 end = start + nbytes;
2473 /* Verify that padding is 0 */
2474 for (k = *rindex; k < start; k++)
2475 if (((const uint8_t*) p)[k] != 0)
2479 *r = (uint8_t*) p + start;
2486 static bool message_end_of_signature(sd_bus_message *m) {
2487 struct bus_container *c;
2491 c = message_get_container(m);
2492 return !c->signature || c->signature[c->index] == 0;
2495 static bool message_end_of_array(sd_bus_message *m, size_t index) {
2496 struct bus_container *c;
2500 c = message_get_container(m);
2504 return index >= c->begin + BUS_MESSAGE_BSWAP32(m, *c->array_size);
2507 _public_ int sd_bus_message_at_end(sd_bus_message *m, int complete) {
2508 assert_return(m, -EINVAL);
2509 assert_return(m->sealed, -EPERM);
2511 if (complete && m->n_containers > 0)
2514 if (message_end_of_signature(m))
2517 if (message_end_of_array(m, m->rindex))
2523 static struct bus_body_part* find_part(sd_bus_message *m, size_t index, size_t sz, void **p) {
2524 struct bus_body_part *part;
2530 if (m->cached_rindex_part && index >= m->cached_rindex_part_begin) {
2531 part = m->cached_rindex_part;
2532 begin = m->cached_rindex_part_begin;
2542 if (index + sz <= begin + part->size) {
2544 r = bus_body_part_map(part);
2549 *p = (uint8_t*) part->data + index - begin;
2551 m->cached_rindex_part = part;
2552 m->cached_rindex_part_begin = begin;
2557 begin += part->size;
2564 static int message_peek_body(
2571 size_t k, start, end, padding;
2572 struct bus_body_part *part;
2579 if (message_end_of_array(m, *rindex))
2582 start = ALIGN_TO((size_t) *rindex, align);
2583 padding = start - *rindex;
2584 end = start + nbytes;
2586 if (end > BUS_MESSAGE_BODY_SIZE(m))
2589 part = find_part(m, *rindex, padding, (void**) &q);
2594 /* Verify padding */
2595 for (k = 0; k < padding; k++)
2600 part = find_part(m, start, nbytes, (void**) &q);
2612 static bool validate_nul(const char *s, size_t l) {
2614 /* Check for NUL chars in the string */
2615 if (memchr(s, 0, l))
2618 /* Check for NUL termination */
2625 static bool validate_string(const char *s, size_t l) {
2627 if (!validate_nul(s, l))
2630 /* Check if valid UTF8 */
2631 if (!utf8_is_valid(s))
2637 static bool validate_signature(const char *s, size_t l) {
2639 if (!validate_nul(s, l))
2642 /* Check if valid signature */
2643 if (!signature_is_valid(s, true))
2649 static bool validate_object_path(const char *s, size_t l) {
2651 if (!validate_nul(s, l))
2654 if (!object_path_is_valid(s))
2660 _public_ int sd_bus_message_read_basic(sd_bus_message *m, char type, void *p) {
2661 struct bus_container *c;
2665 assert_return(m, -EINVAL);
2666 assert_return(m->sealed, -EPERM);
2667 assert_return(bus_type_is_basic(type), -EINVAL);
2669 if (message_end_of_signature(m))
2672 if (message_end_of_array(m, m->rindex))
2675 c = message_get_container(m);
2676 if (c->signature[c->index] != type)
2681 case SD_BUS_TYPE_STRING:
2682 case SD_BUS_TYPE_OBJECT_PATH: {
2687 r = message_peek_body(m, &rindex, 4, 4, &q);
2691 l = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2692 r = message_peek_body(m, &rindex, 1, l+1, &q);
2698 if (type == SD_BUS_TYPE_OBJECT_PATH) {
2699 if (!validate_object_path(q, l))
2702 if (!validate_string(q, l))
2708 *(const char**) p = q;
2713 case SD_BUS_TYPE_SIGNATURE: {
2718 r = message_peek_body(m, &rindex, 1, 1, &q);
2723 r = message_peek_body(m, &rindex, 1, l+1, &q);
2729 if (!validate_signature(q, l))
2735 *(const char**) p = q;
2743 align = bus_type_get_alignment(type);
2744 sz = bus_type_get_size(type);
2745 assert(align > 0 && sz > 0);
2748 r = message_peek_body(m, &rindex, align, sz, &q);
2754 case SD_BUS_TYPE_BYTE:
2756 *(uint8_t*) p = *(uint8_t*) q;
2759 case SD_BUS_TYPE_BOOLEAN:
2761 *(int*) p = !!*(uint32_t*) q;
2764 case SD_BUS_TYPE_INT16:
2765 case SD_BUS_TYPE_UINT16:
2767 *(uint16_t*) p = BUS_MESSAGE_BSWAP16(m, *(uint16_t*) q);
2770 case SD_BUS_TYPE_INT32:
2771 case SD_BUS_TYPE_UINT32:
2773 *(uint32_t*) p = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2776 case SD_BUS_TYPE_INT64:
2777 case SD_BUS_TYPE_UINT64:
2778 case SD_BUS_TYPE_DOUBLE:
2780 *(uint64_t*) p = BUS_MESSAGE_BSWAP64(m, *(uint64_t*) q);
2783 case SD_BUS_TYPE_UNIX_FD: {
2786 j = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2791 *(int*) p = m->fds[j];
2796 assert_not_reached("Unknown basic type...");
2805 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2811 static int bus_message_enter_array(
2813 struct bus_container *c,
2814 const char *contents,
2815 uint32_t **array_size) {
2826 if (!signature_is_single(contents, true))
2829 alignment = bus_type_get_alignment(contents[0]);
2833 if (!c->signature || c->signature[c->index] == 0)
2836 if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
2839 if (!startswith(c->signature + c->index + 1, contents))
2843 r = message_peek_body(m, &rindex, 4, 4, &q);
2847 if (BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q) > BUS_ARRAY_MAX_SIZE)
2850 r = message_peek_body(m, &rindex, alignment, 0, NULL);
2856 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2857 c->index += 1 + strlen(contents);
2861 *array_size = (uint32_t*) q;
2866 static int bus_message_enter_variant(
2868 struct bus_container *c,
2869 const char *contents) {
2880 if (!signature_is_single(contents, false))
2883 if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
2886 if (!c->signature || c->signature[c->index] == 0)
2889 if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
2893 r = message_peek_body(m, &rindex, 1, 1, &q);
2898 r = message_peek_body(m, &rindex, 1, l+1, &q);
2904 if (!validate_signature(q, l))
2907 if (!streq(q, contents))
2910 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2918 static int bus_message_enter_struct(
2920 struct bus_container *c,
2921 const char *contents) {
2930 if (!signature_is_valid(contents, false))
2933 if (!c->signature || c->signature[c->index] == 0)
2936 l = strlen(contents);
2938 if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
2939 !startswith(c->signature + c->index + 1, contents) ||
2940 c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
2943 r = message_peek_body(m, &m->rindex, 8, 0, NULL);
2947 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2948 c->index += 1 + l + 1;
2953 static int bus_message_enter_dict_entry(
2955 struct bus_container *c,
2956 const char *contents) {
2965 if (!signature_is_pair(contents))
2968 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2971 if (!c->signature || c->signature[c->index] == 0)
2974 l = strlen(contents);
2976 if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
2977 !startswith(c->signature + c->index + 1, contents) ||
2978 c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
2981 r = message_peek_body(m, &m->rindex, 8, 0, NULL);
2985 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2986 c->index += 1 + l + 1;
2991 _public_ int sd_bus_message_enter_container(sd_bus_message *m,
2993 const char *contents) {
2994 struct bus_container *c, *w;
2995 uint32_t *array_size = NULL;
3000 assert_return(m, -EINVAL);
3001 assert_return(m->sealed, -EPERM);
3002 assert_return(type != 0 || !contents, -EINVAL);
3004 if (type == 0 || !contents) {
3008 /* Allow entering into anonymous containers */
3009 r = sd_bus_message_peek_type(m, &tt, &cc);
3013 if (type != 0 && type != tt)
3016 if (contents && !streq(contents, cc))
3024 * We enforce a global limit on container depth, that is much
3025 * higher than the 32 structs and 32 arrays the specification
3026 * mandates. This is simpler to implement for us, and we need
3027 * this only to ensure our container array doesn't grow
3028 * without bounds. We are happy to return any data from a
3029 * message as long as the data itself is valid, even if the
3030 * overall message might be not.
3032 * Note that the message signature is validated when
3033 * parsing the headers, and that validation does check the
3036 * Note that the specification defines no limits on the depth
3037 * of stacked variants, but we do.
3039 if (m->n_containers >= BUS_CONTAINER_DEPTH)
3042 w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
3047 if (message_end_of_signature(m))
3050 if (message_end_of_array(m, m->rindex))
3053 c = message_get_container(m);
3055 signature = strdup(contents);
3059 c->saved_index = c->index;
3062 if (type == SD_BUS_TYPE_ARRAY)
3063 r = bus_message_enter_array(m, c, contents, &array_size);
3064 else if (type == SD_BUS_TYPE_VARIANT)
3065 r = bus_message_enter_variant(m, c, contents);
3066 else if (type == SD_BUS_TYPE_STRUCT)
3067 r = bus_message_enter_struct(m, c, contents);
3068 else if (type == SD_BUS_TYPE_DICT_ENTRY)
3069 r = bus_message_enter_dict_entry(m, c, contents);
3078 /* OK, let's fill it in */
3079 w += m->n_containers++;
3080 w->enclosing = type;
3081 w->signature = signature;
3083 w->array_size = array_size;
3085 w->begin = m->rindex;
3090 _public_ int sd_bus_message_exit_container(sd_bus_message *m) {
3091 struct bus_container *c;
3093 assert_return(m, -EINVAL);
3094 assert_return(m->sealed, -EPERM);
3095 assert_return(m->n_containers > 0, -ENXIO);
3097 c = message_get_container(m);
3098 if (c->enclosing == SD_BUS_TYPE_ARRAY) {
3101 l = BUS_MESSAGE_BSWAP32(m, *c->array_size);
3102 if (c->begin + l != m->rindex)
3106 if (c->signature && c->signature[c->index] != 0)
3116 static void message_quit_container(sd_bus_message *m) {
3117 struct bus_container *c;
3121 assert(m->n_containers > 0);
3123 c = message_get_container(m);
3126 assert(m->rindex >= c->before);
3127 m->rindex = c->before;
3129 /* Free container */
3133 /* Correct index of new top-level container */
3134 c = message_get_container(m);
3135 c->index = c->saved_index;
3138 _public_ int sd_bus_message_peek_type(sd_bus_message *m, char *type, const char **contents) {
3139 struct bus_container *c;
3142 assert_return(m, -EINVAL);
3143 assert_return(m->sealed, -EPERM);
3145 if (message_end_of_signature(m))
3148 if (message_end_of_array(m, m->rindex))
3151 c = message_get_container(m);
3153 if (bus_type_is_basic(c->signature[c->index])) {
3157 *type = c->signature[c->index];
3161 if (c->signature[c->index] == SD_BUS_TYPE_ARRAY) {
3167 r = signature_element_length(c->signature+c->index+1, &l);
3173 sig = strndup(c->signature + c->index + 1, l);
3177 free(m->peeked_signature);
3178 m->peeked_signature = sig;
3184 *type = SD_BUS_TYPE_ARRAY;
3189 if (c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ||
3190 c->signature[c->index] == SD_BUS_TYPE_DICT_ENTRY_BEGIN) {
3196 r = signature_element_length(c->signature+c->index, &l);
3201 sig = strndup(c->signature + c->index + 1, l - 2);
3205 free(m->peeked_signature);
3206 m->peeked_signature = sig;
3212 *type = c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY;
3217 if (c->signature[c->index] == SD_BUS_TYPE_VARIANT) {
3223 r = message_peek_body(m, &rindex, 1, 1, &q);
3230 r = message_peek_body(m, &rindex, 1, l+1, &q);
3236 if (!validate_signature(q, l))
3243 *type = SD_BUS_TYPE_VARIANT;
3258 _public_ int sd_bus_message_rewind(sd_bus_message *m, int complete) {
3259 struct bus_container *c;
3261 assert_return(m, -EINVAL);
3262 assert_return(m->sealed, -EPERM);
3265 message_reset_containers(m);
3267 m->root_container.index = 0;
3269 c = message_get_container(m);
3271 c = message_get_container(m);
3274 m->rindex = c->begin;
3277 return !isempty(c->signature);
3279 static int message_read_ap(
3284 unsigned n_array, n_struct;
3285 TypeStack stack[BUS_CONTAINER_DEPTH];
3286 unsigned stack_ptr = 0;
3287 unsigned n_loop = 0;
3295 /* Ideally, we'd just call ourselves recursively on every
3296 * complex type. However, the state of a va_list that is
3297 * passed to a function is undefined after that function
3298 * returns. This means we need to docode the va_list linearly
3299 * in a single stackframe. We hence implement our own
3300 * home-grown stack in an array. */
3302 n_array = (unsigned) -1; /* lenght of current array entries */
3303 n_struct = strlen(types); /* length of current struct contents signature */
3310 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
3311 r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
3317 r = sd_bus_message_exit_container(m);
3325 if (n_array != (unsigned) -1)
3334 case SD_BUS_TYPE_BYTE:
3335 case SD_BUS_TYPE_BOOLEAN:
3336 case SD_BUS_TYPE_INT16:
3337 case SD_BUS_TYPE_UINT16:
3338 case SD_BUS_TYPE_INT32:
3339 case SD_BUS_TYPE_UINT32:
3340 case SD_BUS_TYPE_INT64:
3341 case SD_BUS_TYPE_UINT64:
3342 case SD_BUS_TYPE_DOUBLE:
3343 case SD_BUS_TYPE_STRING:
3344 case SD_BUS_TYPE_OBJECT_PATH:
3345 case SD_BUS_TYPE_SIGNATURE:
3346 case SD_BUS_TYPE_UNIX_FD: {
3349 p = va_arg(ap, void*);
3350 r = sd_bus_message_read_basic(m, *t, p);
3363 case SD_BUS_TYPE_ARRAY: {
3366 r = signature_element_length(t + 1, &k);
3372 memcpy(s, t + 1, k);
3375 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, s);
3386 if (n_array == (unsigned) -1) {
3391 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
3397 n_array = va_arg(ap, unsigned);
3402 case SD_BUS_TYPE_VARIANT: {
3405 s = va_arg(ap, const char *);
3409 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, s);
3419 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
3424 n_struct = strlen(s);
3425 n_array = (unsigned) -1;
3430 case SD_BUS_TYPE_STRUCT_BEGIN:
3431 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
3434 r = signature_element_length(t, &k);
3440 memcpy(s, t + 1, k - 2);
3443 r = sd_bus_message_enter_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
3453 if (n_array == (unsigned) -1) {
3458 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
3464 n_array = (unsigned) -1;
3477 _public_ int sd_bus_message_read(sd_bus_message *m, const char *types, ...) {
3481 assert_return(m, -EINVAL);
3482 assert_return(m->sealed, -EPERM);
3483 assert_return(types, -EINVAL);
3485 va_start(ap, types);
3486 r = message_read_ap(m, types, ap);
3492 _public_ int sd_bus_message_skip(sd_bus_message *m, const char *types) {
3495 assert_return(m, -EINVAL);
3496 assert_return(m->sealed, -EPERM);
3497 assert_return(types, -EINVAL);
3504 case SD_BUS_TYPE_BYTE:
3505 case SD_BUS_TYPE_BOOLEAN:
3506 case SD_BUS_TYPE_INT16:
3507 case SD_BUS_TYPE_UINT16:
3508 case SD_BUS_TYPE_INT32:
3509 case SD_BUS_TYPE_UINT32:
3510 case SD_BUS_TYPE_INT64:
3511 case SD_BUS_TYPE_UINT64:
3512 case SD_BUS_TYPE_DOUBLE:
3513 case SD_BUS_TYPE_STRING:
3514 case SD_BUS_TYPE_OBJECT_PATH:
3515 case SD_BUS_TYPE_SIGNATURE:
3516 case SD_BUS_TYPE_UNIX_FD:
3518 r = sd_bus_message_read_basic(m, *types, NULL);
3522 r = sd_bus_message_skip(m, types + 1);
3528 case SD_BUS_TYPE_ARRAY: {
3531 r = signature_element_length(types + 1, &k);
3537 memcpy(s, types+1, k);
3540 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, s);
3545 r = sd_bus_message_skip(m, s);
3552 r = sd_bus_message_exit_container(m);
3557 r = sd_bus_message_skip(m, types + 1 + k);
3564 case SD_BUS_TYPE_VARIANT: {
3565 const char *contents;
3568 r = sd_bus_message_peek_type(m, &x, &contents);
3572 if (x != SD_BUS_TYPE_VARIANT)
3575 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, contents);
3579 r = sd_bus_message_skip(m, contents);
3584 r = sd_bus_message_exit_container(m);
3588 r = sd_bus_message_skip(m, types + 1);
3595 case SD_BUS_TYPE_STRUCT_BEGIN:
3596 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
3599 r = signature_element_length(types, &k);
3605 memcpy(s, types+1, k-2);
3608 r = sd_bus_message_enter_container(m, *types == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
3612 r = sd_bus_message_skip(m, s);
3617 r = sd_bus_message_exit_container(m);
3622 r = sd_bus_message_skip(m, types + k);
3634 _public_ int sd_bus_message_read_array(sd_bus_message *m,
3638 struct bus_container *c;
3644 assert_return(m, -EINVAL);
3645 assert_return(m->sealed, -EPERM);
3646 assert_return(bus_type_is_trivial(type), -EINVAL);
3647 assert_return(ptr, -EINVAL);
3648 assert_return(size, -EINVAL);
3649 assert_return(!BUS_MESSAGE_NEED_BSWAP(m), -ENOTSUP);
3651 align = bus_type_get_alignment(type);
3655 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
3659 c = message_get_container(m);
3660 sz = BUS_MESSAGE_BSWAP32(m, *c->array_size);
3663 /* Zero length array, let's return some aligned
3664 * pointer that is not NULL */
3665 p = (uint8_t*) NULL + align;
3667 r = message_peek_body(m, &m->rindex, align, sz, &p);
3676 r = sd_bus_message_exit_container(m);
3680 *ptr = (const void*) p;
3686 message_quit_container(m);
3690 static int message_peek_fields(
3701 return buffer_peek(BUS_MESSAGE_FIELDS(m), BUS_MESSAGE_FIELDS_SIZE(m), rindex, align, nbytes, ret);
3704 static int message_peek_field_uint32(
3715 r = message_peek_fields(m, ri, 4, 4, &q);
3720 *ret = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
3725 static int message_peek_field_string(
3727 bool (*validate)(const char *p),
3738 r = message_peek_field_uint32(m, ri, &l);
3742 r = message_peek_fields(m, ri, 1, l+1, &q);
3747 if (!validate_nul(q, l))
3753 if (!validate_string(q, l))
3763 static int message_peek_field_signature(
3775 r = message_peek_fields(m, ri, 1, 1, &q);
3780 r = message_peek_fields(m, ri, 1, l+1, &q);
3784 if (!validate_signature(q, l))
3793 static int message_skip_fields(
3796 uint32_t array_size,
3797 const char **signature) {
3799 size_t original_index;
3806 original_index = *ri;
3812 if (array_size != (uint32_t) -1 &&
3813 array_size <= *ri - original_index)
3820 if (t == SD_BUS_TYPE_STRING) {
3822 r = message_peek_field_string(m, NULL, ri, NULL);
3828 } else if (t == SD_BUS_TYPE_OBJECT_PATH) {
3830 r = message_peek_field_string(m, object_path_is_valid, ri, NULL);
3836 } else if (t == SD_BUS_TYPE_SIGNATURE) {
3838 r = message_peek_field_signature(m, ri, NULL);
3844 } else if (bus_type_is_basic(t)) {
3847 align = bus_type_get_alignment(t);
3848 k = bus_type_get_size(t);
3849 assert(align > 0 && k > 0);
3851 r = message_peek_fields(m, ri, align, k, NULL);
3857 } else if (t == SD_BUS_TYPE_ARRAY) {
3859 r = signature_element_length(*signature+1, &l);
3869 strncpy(sig, *signature + 1, l-1);
3872 alignment = bus_type_get_alignment(sig[0]);
3876 r = message_peek_field_uint32(m, ri, &nas);
3879 if (nas > BUS_ARRAY_MAX_SIZE)
3882 r = message_peek_fields(m, ri, alignment, 0, NULL);
3886 r = message_skip_fields(m, ri, nas, (const char**) &s);
3891 (*signature) += 1 + l;
3893 } else if (t == SD_BUS_TYPE_VARIANT) {
3896 r = message_peek_field_signature(m, ri, &s);
3900 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
3906 } else if (t == SD_BUS_TYPE_STRUCT ||
3907 t == SD_BUS_TYPE_DICT_ENTRY) {
3909 r = signature_element_length(*signature, &l);
3916 strncpy(sig, *signature + 1, l-1);
3919 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
3930 int bus_message_parse_fields(sd_bus_message *m) {
3933 uint32_t unix_fds = 0;
3937 for (ri = 0; ri < BUS_MESSAGE_FIELDS_SIZE(m); ) {
3938 const char *signature;
3941 r = message_peek_fields(m, &ri, 8, 1, (void**) &header);
3945 r = message_peek_field_signature(m, &ri, &signature);
3950 case _SD_BUS_MESSAGE_HEADER_INVALID:
3953 case SD_BUS_MESSAGE_HEADER_PATH:
3958 if (!streq(signature, "o"))
3961 r = message_peek_field_string(m, object_path_is_valid, &ri, &m->path);
3964 case SD_BUS_MESSAGE_HEADER_INTERFACE:
3969 if (!streq(signature, "s"))
3972 r = message_peek_field_string(m, interface_name_is_valid, &ri, &m->interface);
3975 case SD_BUS_MESSAGE_HEADER_MEMBER:
3980 if (!streq(signature, "s"))
3983 r = message_peek_field_string(m, member_name_is_valid, &ri, &m->member);
3986 case SD_BUS_MESSAGE_HEADER_ERROR_NAME:
3991 if (!streq(signature, "s"))
3994 r = message_peek_field_string(m, error_name_is_valid, &ri, &m->error.name);
3997 case SD_BUS_MESSAGE_HEADER_DESTINATION:
4002 if (!streq(signature, "s"))
4005 r = message_peek_field_string(m, sender_name_is_valid, &ri, &m->destination);
4008 case SD_BUS_MESSAGE_HEADER_SENDER:
4013 if (!streq(signature, "s"))
4016 r = message_peek_field_string(m, sender_name_is_valid, &ri, &m->sender);
4020 case SD_BUS_MESSAGE_HEADER_SIGNATURE: {
4024 if (m->root_container.signature)
4027 if (!streq(signature, "g"))
4030 r = message_peek_field_signature(m, &ri, &s);
4038 free(m->root_container.signature);
4039 m->root_container.signature = c;
4043 case SD_BUS_MESSAGE_HEADER_REPLY_SERIAL:
4044 if (m->reply_serial != 0)
4047 if (!streq(signature, "u"))
4050 r = message_peek_field_uint32(m, &ri, &m->reply_serial);
4054 if (m->reply_serial == 0)
4059 case SD_BUS_MESSAGE_HEADER_UNIX_FDS:
4063 if (!streq(signature, "u"))
4066 r = message_peek_field_uint32(m, &ri, &unix_fds);
4076 r = message_skip_fields(m, &ri, (uint32_t) -1, (const char **) &signature);
4083 if (m->n_fds != unix_fds)
4086 if (isempty(m->root_container.signature) != (BUS_MESSAGE_BODY_SIZE(m) == 0))
4089 switch (m->header->type) {
4091 case SD_BUS_MESSAGE_SIGNAL:
4092 if (!m->path || !m->interface || !m->member)
4096 case SD_BUS_MESSAGE_METHOD_CALL:
4098 if (!m->path || !m->member)
4103 case SD_BUS_MESSAGE_METHOD_RETURN:
4105 if (m->reply_serial == 0)
4109 case SD_BUS_MESSAGE_METHOD_ERROR:
4111 if (m->reply_serial == 0 || !m->error.name)
4116 /* Try to read the error message, but if we can't it's a non-issue */
4117 if (m->header->type == SD_BUS_MESSAGE_METHOD_ERROR)
4118 sd_bus_message_read(m, "s", &m->error.message);
4123 int bus_message_seal(sd_bus_message *m, uint64_t serial) {
4124 struct bus_body_part *part;
4134 if (m->n_containers > 0)
4140 /* If there's a non-trivial signature set, then add it in here */
4141 if (!isempty(m->root_container.signature)) {
4142 r = message_append_field_signature(m, SD_BUS_MESSAGE_HEADER_SIGNATURE, m->root_container.signature, NULL);
4148 r = message_append_field_uint32(m, SD_BUS_MESSAGE_HEADER_UNIX_FDS, m->n_fds);
4153 /* Add padding at the end of the fields part, since we know
4154 * the body needs to start at an 8 byte alignment. We made
4155 * sure we allocated enough space for this, so all we need to
4156 * do here is to zero it out. */
4157 l = BUS_MESSAGE_FIELDS_SIZE(m);
4160 memset((uint8_t*) BUS_MESSAGE_FIELDS(m) + l, 0, a);
4162 /* If this is something we can send as memfd, then let's seal
4163 the memfd now. Note that we can send memfds as payload only
4164 for directed messages, and not for broadcasts. */
4165 if (m->destination && m->bus && m->bus->use_memfd) {
4166 MESSAGE_FOREACH_PART(part, i, m)
4167 if (part->memfd >= 0 && !part->sealed && (part->size > MEMFD_MIN_SIZE || m->bus->use_memfd < 0)) {
4168 bus_body_part_unmap(part);
4170 if (ioctl(part->memfd, KDBUS_CMD_MEMFD_SEAL_SET, 1) >= 0)
4171 part->sealed = true;
4175 m->header->serial = serial;
4181 _public_ int sd_bus_message_set_destination(sd_bus_message *m, const char *destination) {
4182 assert_return(m, -EINVAL);
4183 assert_return(destination, -EINVAL);
4184 assert_return(!m->sealed, -EPERM);
4185 assert_return(!m->destination, -EEXIST);
4187 return message_append_field_string(m, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &m->destination);
4190 int bus_message_dump(sd_bus_message *m, FILE *f, bool with_header) {
4191 const char *u = NULL, *uu = NULL, *s = NULL;
4192 char **cmdline = NULL;
4195 uid_t owner, audit_loginuid;
4196 uint32_t audit_sessionid;
4212 "\tfields_size=%u\n"
4217 "\tdestination=%s\n"
4220 "\treply_serial=%u\n"
4222 "\tn_body_parts=%u\n",
4229 BUS_MESSAGE_SERIAL(m),
4230 BUS_MESSAGE_FIELDS_SIZE(m),
4231 BUS_MESSAGE_BODY_SIZE(m),
4233 strna(m->interface),
4235 strna(m->destination),
4237 strna(m->root_container.signature),
4242 if (sd_bus_error_is_set(&m->error))
4245 "\terror.message=%s\n",
4246 strna(m->error.name),
4247 strna(m->error.message));
4250 fprintf(f, "\tpid=%lu\n", (unsigned long) m->pid);
4252 fprintf(f, "\ttid=%lu\n", (unsigned long) m->tid);
4254 fprintf(f, "\tuid=%lu\n", (unsigned long) m->uid);
4256 fprintf(f, "\tgid=%lu\n", (unsigned long) m->gid);
4257 if (m->pid_starttime != 0)
4258 fprintf(f, "\tpid_starttime=%llu\n", (unsigned long long) m->pid_starttime);
4259 if (m->monotonic != 0)
4260 fprintf(f, "\tmonotonic=%llu\n", (unsigned long long) m->monotonic);
4261 if (m->realtime != 0)
4262 fprintf(f, "\trealtime=%llu\n", (unsigned long long) m->realtime);
4264 fprintf(f, "\texe=[%s]\n", m->exe);
4266 fprintf(f, "\tcomm=[%s]\n", m->comm);
4268 fprintf(f, "\ttid_comm=[%s]\n", m->tid_comm);
4270 fprintf(f, "\tlabel=[%s]\n", m->label);
4272 fprintf(f, "\tcgroup=[%s]\n", m->cgroup);
4274 sd_bus_message_get_unit(m, &u);
4276 fprintf(f, "\tunit=[%s]\n", u);
4277 sd_bus_message_get_user_unit(m, &uu);
4279 fprintf(f, "\tuser_unit=[%s]\n", uu);
4280 sd_bus_message_get_session(m, &s);
4282 fprintf(f, "\tsession=[%s]\n", s);
4283 if (sd_bus_message_get_owner_uid(m, &owner) >= 0)
4284 fprintf(f, "\towner_uid=%lu\n", (unsigned long) owner);
4285 if (sd_bus_message_get_audit_loginuid(m, &audit_loginuid) >= 0)
4286 fprintf(f, "\taudit_loginuid=%lu\n", (unsigned long) audit_loginuid);
4287 if (sd_bus_message_get_audit_sessionid(m, &audit_sessionid) >= 0)
4288 fprintf(f, "\taudit_sessionid=%lu\n", (unsigned long) audit_sessionid);
4290 r = sd_bus_message_has_effective_cap(m, 5);
4292 fprintf(f, "\tCAP_KILL=%s\n", yes_no(r));
4294 if (sd_bus_message_get_cmdline(m, &cmdline) >= 0) {
4297 fputs("\tcmdline=[", f);
4298 STRV_FOREACH(c, cmdline) {
4309 r = sd_bus_message_rewind(m, true);
4311 log_error("Failed to rewind: %s", strerror(-r));
4315 fprintf(f, "MESSAGE \"%s\" {\n", strempty(m->root_container.signature));
4318 _cleanup_free_ char *prefix = NULL;
4319 const char *contents = NULL;
4334 r = sd_bus_message_peek_type(m, &type, &contents);
4336 log_error("Failed to peek type: %s", strerror(-r));
4344 r = sd_bus_message_exit_container(m);
4346 log_error("Failed to exit container: %s", strerror(-r));
4352 prefix = strrep("\t", level);
4356 fprintf(f, "%s};\n", prefix);
4360 prefix = strrep("\t", level);
4364 if (bus_type_is_container(type) > 0) {
4365 r = sd_bus_message_enter_container(m, type, contents);
4367 log_error("Failed to enter container: %s", strerror(-r));
4371 if (type == SD_BUS_TYPE_ARRAY)
4372 fprintf(f, "%sARRAY \"%s\" {\n", prefix, contents);
4373 else if (type == SD_BUS_TYPE_VARIANT)
4374 fprintf(f, "%sVARIANT \"%s\" {\n", prefix, contents);
4375 else if (type == SD_BUS_TYPE_STRUCT)
4376 fprintf(f, "%sSTRUCT \"%s\" {\n", prefix, contents);
4377 else if (type == SD_BUS_TYPE_DICT_ENTRY)
4378 fprintf(f, "%sDICT_ENTRY \"%s\" {\n", prefix, contents);
4385 r = sd_bus_message_read_basic(m, type, &basic);
4387 log_error("Failed to get basic: %s", strerror(-r));
4395 case SD_BUS_TYPE_BYTE:
4396 fprintf(f, "%sBYTE %u;\n", prefix, basic.u8);
4399 case SD_BUS_TYPE_BOOLEAN:
4400 fprintf(f, "%sBOOLEAN %s;\n", prefix, yes_no(basic.i));
4403 case SD_BUS_TYPE_INT16:
4404 fprintf(f, "%sINT16 %i;\n", prefix, basic.s16);
4407 case SD_BUS_TYPE_UINT16:
4408 fprintf(f, "%sUINT16 %u;\n", prefix, basic.u16);
4411 case SD_BUS_TYPE_INT32:
4412 fprintf(f, "%sINT32 %i;\n", prefix, basic.s32);
4415 case SD_BUS_TYPE_UINT32:
4416 fprintf(f, "%sUINT32 %u;\n", prefix, basic.u32);
4419 case SD_BUS_TYPE_INT64:
4420 fprintf(f, "%sINT64 %lli;\n", prefix, (long long) basic.s64);
4423 case SD_BUS_TYPE_UINT64:
4424 fprintf(f, "%sUINT64 %llu;\n", prefix, (unsigned long long) basic.u64);
4427 case SD_BUS_TYPE_DOUBLE:
4428 fprintf(f, "%sDOUBLE %g;\n", prefix, basic.d64);
4431 case SD_BUS_TYPE_STRING:
4432 fprintf(f, "%sSTRING \"%s\";\n", prefix, basic.string);
4435 case SD_BUS_TYPE_OBJECT_PATH:
4436 fprintf(f, "%sOBJECT_PATH \"%s\";\n", prefix, basic.string);
4439 case SD_BUS_TYPE_SIGNATURE:
4440 fprintf(f, "%sSIGNATURE \"%s\";\n", prefix, basic.string);
4443 case SD_BUS_TYPE_UNIX_FD:
4444 fprintf(f, "%sUNIX_FD %i;\n", prefix, basic.i);
4448 assert_not_reached("Unknown basic type.");
4456 int bus_message_get_blob(sd_bus_message *m, void **buffer, size_t *sz) {
4460 struct bus_body_part *part;
4466 total = BUS_MESSAGE_SIZE(m);
4472 e = mempcpy(p, m->header, BUS_MESSAGE_BODY_BEGIN(m));
4473 MESSAGE_FOREACH_PART(part, i, m)
4474 e = mempcpy(e, part->data, part->size);
4476 assert(total == (size_t) ((uint8_t*) e - (uint8_t*) p));
4484 int bus_message_read_strv_extend(sd_bus_message *m, char ***l) {
4490 r = sd_bus_message_enter_container(m, 'a', "s");
4497 r = sd_bus_message_read_basic(m, 's', &s);
4503 r = strv_extend(l, s);
4508 r = sd_bus_message_exit_container(m);
4515 _public_ int sd_bus_message_read_strv(sd_bus_message *m, char ***l) {
4519 assert_return(m, -EINVAL);
4520 assert_return(m->sealed, -EPERM);
4521 assert_return(l, -EINVAL);
4523 r = bus_message_read_strv_extend(m, &strv);
4533 const char* bus_message_get_arg(sd_bus_message *m, unsigned i) {
4535 const char *t = NULL;
4540 r = sd_bus_message_rewind(m, true);
4544 for (j = 0; j <= i; j++) {
4547 r = sd_bus_message_peek_type(m, &type, NULL);
4551 if (type != SD_BUS_TYPE_STRING &&
4552 type != SD_BUS_TYPE_OBJECT_PATH &&
4553 type != SD_BUS_TYPE_SIGNATURE)
4556 r = sd_bus_message_read_basic(m, type, &t);
4564 bool bus_header_is_complete(struct bus_header *h, size_t size) {
4570 if (size < sizeof(struct bus_header))
4573 full = sizeof(struct bus_header) +
4574 (h->endian == SD_BUS_NATIVE_ENDIAN ? h->fields_size : bswap_32(h->fields_size));
4576 return size >= full;
4579 int bus_header_message_size(struct bus_header *h, size_t *sum) {
4585 if (h->endian == SD_BUS_NATIVE_ENDIAN) {
4586 fs = h->fields_size;
4588 } else if (h->endian == SD_BUS_REVERSE_ENDIAN) {
4589 fs = bswap_32(h->fields_size);
4590 bs = bswap_32(h->body_size);
4594 *sum = sizeof(struct bus_header) + ALIGN8(fs) + bs;
4598 _public_ int sd_bus_message_get_errno(sd_bus_message *m) {
4599 assert_return(m, -EINVAL);
4601 if (m->header->type != SD_BUS_MESSAGE_METHOD_ERROR)
4604 return sd_bus_error_get_errno(&m->error);
4607 _public_ const char* sd_bus_message_get_signature(sd_bus_message *m, int complete) {
4608 struct bus_container *c;
4610 assert_return(m, NULL);
4612 c = complete ? &m->root_container : message_get_container(m);
4613 return c->signature ?: "";
4616 _public_ int sd_bus_message_copy(sd_bus_message *m, sd_bus_message *source, int all) {
4617 bool done_something = false;
4620 assert_return(m, -EINVAL);
4621 assert_return(source, -EINVAL);
4622 assert_return(!m->sealed, -EPERM);
4623 assert_return(source->sealed, -EPERM);
4626 const char *contents;
4641 r = sd_bus_message_peek_type(source, &type, &contents);
4647 done_something = true;
4649 if (bus_type_is_container(type) > 0) {
4651 r = sd_bus_message_enter_container(source, type, contents);
4655 r = sd_bus_message_open_container(m, type, contents);
4659 r = sd_bus_message_copy(m, source, true);
4663 r = sd_bus_message_close_container(m);
4667 r = sd_bus_message_exit_container(source);
4674 r = sd_bus_message_read_basic(source, type, &basic);
4680 if (type == SD_BUS_TYPE_OBJECT_PATH ||
4681 type == SD_BUS_TYPE_SIGNATURE ||
4682 type == SD_BUS_TYPE_STRING)
4683 r = sd_bus_message_append_basic(m, type, basic.string);
4685 r = sd_bus_message_append_basic(m, type, &basic);
4692 return done_something;
4695 _public_ int sd_bus_message_verify_type(sd_bus_message *m, char type, const char *contents) {
4700 assert_return(m, -EINVAL);
4701 assert_return(m->sealed, -EPERM);
4702 assert_return(!type || bus_type_is_valid(type), -EINVAL);
4703 assert_return(!contents || signature_is_valid(contents, true), -EINVAL);
4704 assert_return(type || contents, -EINVAL);
4705 assert_return(!contents || !type || bus_type_is_container(type), -EINVAL);
4707 r = sd_bus_message_peek_type(m, &t, &c);
4711 if (type != 0 && type != t)
4714 if (contents && !streq_ptr(contents, c))