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(p, -EINVAL);
1327 assert_return(!m->sealed, -EPERM);
1328 assert_return(bus_type_is_basic(type), -EINVAL);
1329 assert_return(!m->poisoned, -ESTALE);
1331 c = message_get_container(m);
1333 if (c->signature && c->signature[c->index]) {
1334 /* Container signature is already set */
1336 if (c->signature[c->index] != type)
1341 /* Maybe we can append to the signature? But only if this is the top-level container*/
1342 if (c->enclosing != 0)
1345 e = strextend(&c->signature, CHAR_TO_STR(type), NULL);
1354 case SD_BUS_TYPE_STRING:
1355 /* To make things easy we'll serialize a NULL string
1356 * into the empty string */
1359 /* Fall through... */
1360 case SD_BUS_TYPE_OBJECT_PATH:
1368 sz = 4 + strlen(p) + 1;
1371 case SD_BUS_TYPE_SIGNATURE:
1379 sz = 1 + strlen(p) + 1;
1382 case SD_BUS_TYPE_BOOLEAN:
1385 assert_cc(sizeof(int) == sizeof(uint32_t));
1391 case SD_BUS_TYPE_UNIX_FD: {
1394 if (!m->allow_fds) {
1407 fd = fcntl(z, F_DUPFD_CLOEXEC, 3);
1413 f = realloc(m->fds, sizeof(int) * (m->n_fds + 1));
1428 align = bus_type_get_alignment(type);
1429 sz = bus_type_get_size(type);
1436 a = message_extend_body(m, align, sz);
1442 if (type == SD_BUS_TYPE_STRING || type == SD_BUS_TYPE_OBJECT_PATH) {
1443 *(uint32_t*) a = sz - 5;
1444 memcpy((uint8_t*) a + 4, p, sz - 4);
1447 *stored = (const uint8_t*) a + 4;
1449 } else if (type == SD_BUS_TYPE_SIGNATURE) {
1450 *(uint8_t*) a = sz - 1;
1451 memcpy((uint8_t*) a + 1, p, sz - 1);
1454 *stored = (const uint8_t*) a + 1;
1455 } else if (type == SD_BUS_TYPE_UNIX_FD) {
1456 *(uint32_t*) a = fdi;
1470 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1477 close_nointr_nofail(fd);
1482 _public_ int sd_bus_message_append_basic(sd_bus_message *m, char type, const void *p) {
1483 return message_append_basic(m, type, p, NULL);
1486 _public_ int sd_bus_message_append_string_space(sd_bus_message *m, size_t size, char **s) {
1487 struct bus_container *c;
1490 assert_return(m, -EINVAL);
1491 assert_return(s, -EINVAL);
1492 assert_return(!m->sealed, -EPERM);
1493 assert_return(!m->poisoned, -ESTALE);
1495 c = message_get_container(m);
1497 if (c->signature && c->signature[c->index]) {
1498 /* Container signature is already set */
1500 if (c->signature[c->index] != SD_BUS_TYPE_STRING)
1505 /* Maybe we can append to the signature? But only if this is the top-level container*/
1506 if (c->enclosing != 0)
1509 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRING), NULL);
1516 a = message_extend_body(m, 4, 4 + size + 1);
1520 *(uint32_t*) a = size;
1525 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1531 static int bus_message_open_array(
1533 struct bus_container *c,
1534 const char *contents,
1535 uint32_t **array_size) {
1541 struct bus_body_part *o;
1548 if (!signature_is_single(contents, true))
1551 alignment = bus_type_get_alignment(contents[0]);
1555 if (c->signature && c->signature[c->index]) {
1557 /* Verify the existing signature */
1559 if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
1562 if (!startswith(c->signature + c->index + 1, contents))
1565 nindex = c->index + 1 + strlen(contents);
1569 if (c->enclosing != 0)
1572 /* Extend the existing signature */
1574 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_ARRAY), contents, NULL);
1580 nindex = e - c->signature;
1583 a = message_extend_body(m, 4, 4);
1588 op = m->body_end->data;
1589 os = m->body_end->size;
1591 /* Add alignment between size and first element */
1592 if (!message_extend_body(m, alignment, 0))
1595 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1598 /* location of array size might have changed so let's readjust a */
1599 if (o == m->body_end)
1600 a = adjust_pointer(a, op, os, m->body_end->data);
1607 static int bus_message_open_variant(
1609 struct bus_container *c,
1610 const char *contents) {
1619 if (!signature_is_single(contents, false))
1622 if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
1625 if (c->signature && c->signature[c->index]) {
1627 if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
1633 if (c->enclosing != 0)
1636 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_VARIANT), NULL);
1643 l = strlen(contents);
1644 a = message_extend_body(m, 1, 1 + l + 1);
1649 memcpy((uint8_t*) a + 1, contents, l + 1);
1651 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1657 static int bus_message_open_struct(
1659 struct bus_container *c,
1660 const char *contents) {
1668 if (!signature_is_valid(contents, false))
1671 if (c->signature && c->signature[c->index]) {
1674 l = strlen(contents);
1676 if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
1677 !startswith(c->signature + c->index + 1, contents) ||
1678 c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
1681 nindex = c->index + 1 + l + 1;
1685 if (c->enclosing != 0)
1688 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_BEGIN), contents, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_END), NULL);
1694 nindex = e - c->signature;
1697 /* Align contents to 8 byte boundary */
1698 if (!message_extend_body(m, 8, 0))
1701 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1707 static int bus_message_open_dict_entry(
1709 struct bus_container *c,
1710 const char *contents) {
1718 if (!signature_is_pair(contents))
1721 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1724 if (c->signature && c->signature[c->index]) {
1727 l = strlen(contents);
1729 if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
1730 !startswith(c->signature + c->index + 1, contents) ||
1731 c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
1734 nindex = c->index + 1 + l + 1;
1738 /* Align contents to 8 byte boundary */
1739 if (!message_extend_body(m, 8, 0))
1742 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1748 _public_ int sd_bus_message_open_container(
1751 const char *contents) {
1753 struct bus_container *c, *w;
1754 uint32_t *array_size = NULL;
1759 assert_return(m, -EINVAL);
1760 assert_return(!m->sealed, -EPERM);
1761 assert_return(contents, -EINVAL);
1762 assert_return(!m->poisoned, -ESTALE);
1764 /* Make sure we have space for one more container */
1765 w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
1773 c = message_get_container(m);
1775 signature = strdup(contents);
1781 /* Save old index in the parent container, in case we have to
1782 * abort this container */
1783 c->saved_index = c->index;
1784 before = m->header->body_size;
1786 if (type == SD_BUS_TYPE_ARRAY)
1787 r = bus_message_open_array(m, c, contents, &array_size);
1788 else if (type == SD_BUS_TYPE_VARIANT)
1789 r = bus_message_open_variant(m, c, contents);
1790 else if (type == SD_BUS_TYPE_STRUCT)
1791 r = bus_message_open_struct(m, c, contents);
1792 else if (type == SD_BUS_TYPE_DICT_ENTRY)
1793 r = bus_message_open_dict_entry(m, c, contents);
1802 /* OK, let's fill it in */
1803 w += m->n_containers++;
1804 w->enclosing = type;
1805 w->signature = signature;
1807 w->array_size = array_size;
1809 w->begin = m->rindex;
1814 _public_ int sd_bus_message_close_container(sd_bus_message *m) {
1815 struct bus_container *c;
1817 assert_return(m, -EINVAL);
1818 assert_return(!m->sealed, -EPERM);
1819 assert_return(m->n_containers > 0, -EINVAL);
1820 assert_return(!m->poisoned, -ESTALE);
1822 c = message_get_container(m);
1823 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1824 if (c->signature && c->signature[c->index] != 0)
1839 static int type_stack_push(TypeStack *stack, unsigned max, unsigned *i, const char *types, unsigned n_struct, unsigned n_array) {
1846 stack[*i].types = types;
1847 stack[*i].n_struct = n_struct;
1848 stack[*i].n_array = n_array;
1854 static int type_stack_pop(TypeStack *stack, unsigned max, unsigned *i, const char **types, unsigned *n_struct, unsigned *n_array) {
1865 *types = stack[*i].types;
1866 *n_struct = stack[*i].n_struct;
1867 *n_array = stack[*i].n_array;
1872 int bus_message_append_ap(
1877 unsigned n_array, n_struct;
1878 TypeStack stack[BUS_CONTAINER_DEPTH];
1879 unsigned stack_ptr = 0;
1887 n_array = (unsigned) -1;
1888 n_struct = strlen(types);
1893 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
1894 r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
1900 r = sd_bus_message_close_container(m);
1908 if (n_array != (unsigned) -1)
1917 case SD_BUS_TYPE_BYTE: {
1920 x = (uint8_t) va_arg(ap, int);
1921 r = sd_bus_message_append_basic(m, *t, &x);
1925 case SD_BUS_TYPE_BOOLEAN:
1926 case SD_BUS_TYPE_INT32:
1927 case SD_BUS_TYPE_UINT32:
1928 case SD_BUS_TYPE_UNIX_FD: {
1931 /* We assume a boolean is the same as int32_t */
1932 assert_cc(sizeof(int32_t) == sizeof(int));
1934 x = va_arg(ap, uint32_t);
1935 r = sd_bus_message_append_basic(m, *t, &x);
1939 case SD_BUS_TYPE_INT16:
1940 case SD_BUS_TYPE_UINT16: {
1943 x = (uint16_t) va_arg(ap, int);
1944 r = sd_bus_message_append_basic(m, *t, &x);
1948 case SD_BUS_TYPE_INT64:
1949 case SD_BUS_TYPE_UINT64:
1950 case SD_BUS_TYPE_DOUBLE: {
1953 x = va_arg(ap, uint64_t);
1954 r = sd_bus_message_append_basic(m, *t, &x);
1958 case SD_BUS_TYPE_STRING:
1959 case SD_BUS_TYPE_OBJECT_PATH:
1960 case SD_BUS_TYPE_SIGNATURE: {
1963 x = va_arg(ap, const char*);
1964 r = sd_bus_message_append_basic(m, *t, x);
1968 case SD_BUS_TYPE_ARRAY: {
1971 r = signature_element_length(t + 1, &k);
1977 memcpy(s, t + 1, k);
1980 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, s);
1985 if (n_array == (unsigned) -1) {
1990 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
1996 n_array = va_arg(ap, unsigned);
2001 case SD_BUS_TYPE_VARIANT: {
2004 s = va_arg(ap, const char*);
2008 r = sd_bus_message_open_container(m, SD_BUS_TYPE_VARIANT, s);
2012 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2017 n_struct = strlen(s);
2018 n_array = (unsigned) -1;
2023 case SD_BUS_TYPE_STRUCT_BEGIN:
2024 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
2027 r = signature_element_length(t, &k);
2034 memcpy(s, t + 1, k - 2);
2037 r = sd_bus_message_open_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
2042 if (n_array == (unsigned) -1) {
2047 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2053 n_array = (unsigned) -1;
2069 _public_ int sd_bus_message_append(sd_bus_message *m, const char *types, ...) {
2073 assert_return(m, -EINVAL);
2074 assert_return(types, -EINVAL);
2075 assert_return(!m->sealed, -EPERM);
2076 assert_return(!m->poisoned, -ESTALE);
2078 va_start(ap, types);
2079 r = bus_message_append_ap(m, types, ap);
2085 _public_ int sd_bus_message_append_array_space(sd_bus_message *m,
2093 assert_return(m, -EINVAL);
2094 assert_return(!m->sealed, -EPERM);
2095 assert_return(bus_type_is_trivial(type), -EINVAL);
2096 assert_return(ptr || size == 0, -EINVAL);
2097 assert_return(!m->poisoned, -ESTALE);
2099 align = bus_type_get_alignment(type);
2100 sz = bus_type_get_size(type);
2102 assert_se(align > 0);
2108 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
2112 a = message_extend_body(m, align, size);
2116 r = sd_bus_message_close_container(m);
2124 _public_ int sd_bus_message_append_array(sd_bus_message *m,
2131 assert_return(m, -EINVAL);
2132 assert_return(!m->sealed, -EPERM);
2133 assert_return(bus_type_is_trivial(type), -EINVAL);
2134 assert_return(ptr || size == 0, -EINVAL);
2135 assert_return(!m->poisoned, -ESTALE);
2137 r = sd_bus_message_append_array_space(m, type, size, &p);
2142 memcpy(p, ptr, size);
2147 _public_ int sd_bus_message_append_array_memfd(sd_bus_message *m,
2150 _cleanup_close_ int copy_fd = -1;
2151 struct bus_body_part *part;
2163 if (!bus_type_is_trivial(type))
2168 r = sd_memfd_set_sealed(memfd, true);
2172 copy_fd = sd_memfd_dup_fd(memfd);
2176 r = sd_memfd_get_size(memfd, &size);
2180 align = bus_type_get_alignment(type);
2181 sz = bus_type_get_size(type);
2183 assert_se(align > 0);
2189 if (size > (uint64_t) (uint32_t) -1)
2192 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
2196 a = message_extend_body(m, align, 0);
2200 part = message_append_part(m);
2204 part->memfd = copy_fd;
2205 part->sealed = true;
2209 message_extend_containers(m, size);
2210 m->header->body_size += size;
2212 return sd_bus_message_close_container(m);
2215 _public_ int sd_bus_message_append_string_memfd(sd_bus_message *m, sd_memfd *memfd) {
2216 _cleanup_close_ int copy_fd = -1;
2217 struct bus_body_part *part;
2218 struct bus_container *c;
2223 assert_return(m, -EINVAL);
2224 assert_return(memfd, -EINVAL);
2225 assert_return(!m->sealed, -EPERM);
2226 assert_return(!m->poisoned, -ESTALE);
2228 r = sd_memfd_set_sealed(memfd, true);
2232 copy_fd = sd_memfd_dup_fd(memfd);
2236 r = sd_memfd_get_size(memfd, &size);
2240 /* We require this to be NUL terminated */
2244 if (size > (uint64_t) (uint32_t) -1)
2247 c = message_get_container(m);
2248 if (c->signature && c->signature[c->index]) {
2249 /* Container signature is already set */
2251 if (c->signature[c->index] != SD_BUS_TYPE_STRING)
2256 /* Maybe we can append to the signature? But only if this is the top-level container*/
2257 if (c->enclosing != 0)
2260 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRING), NULL);
2267 a = message_extend_body(m, 4, 4);
2271 *(uint32_t*) a = size - 1;
2273 part = message_append_part(m);
2277 part->memfd = copy_fd;
2278 part->sealed = true;
2282 message_extend_containers(m, size);
2283 m->header->body_size += size;
2285 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2291 _public_ int sd_bus_message_append_strv(sd_bus_message *m, char **l) {
2295 assert_return(m, -EINVAL);
2296 assert_return(!m->sealed, -EPERM);
2297 assert_return(!m->poisoned, -ESTALE);
2299 r = sd_bus_message_open_container(m, 'a', "s");
2303 STRV_FOREACH(i, l) {
2304 r = sd_bus_message_append_basic(m, 's', *i);
2309 return sd_bus_message_close_container(m);
2312 int bus_body_part_map(struct bus_body_part *part) {
2321 if (part->size <= 0)
2324 /* For smaller zero parts (as used for padding) we don't need to map anything... */
2325 if (part->memfd < 0 && part->is_zero && part->size < 8) {
2326 static const uint8_t zeroes[7] = { };
2327 part->data = (void*) zeroes;
2331 psz = PAGE_ALIGN(part->size);
2333 if (part->memfd >= 0)
2334 p = mmap(NULL, psz, PROT_READ, MAP_SHARED, part->memfd, 0);
2335 else if (part->is_zero)
2336 p = mmap(NULL, psz, PROT_READ, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
2340 if (p == MAP_FAILED)
2345 part->munmap_this = true;
2350 void bus_body_part_unmap(struct bus_body_part *part) {
2354 if (part->memfd < 0)
2360 if (!part->munmap_this)
2363 assert_se(munmap(part->data, part->mapped) == 0);
2367 part->munmap_this = false;
2372 static int buffer_peek(const void *p, uint32_t sz, size_t *rindex, size_t align, size_t nbytes, void **r) {
2373 size_t k, start, end;
2378 start = ALIGN_TO((size_t) *rindex, align);
2379 end = start + nbytes;
2384 /* Verify that padding is 0 */
2385 for (k = *rindex; k < start; k++)
2386 if (((const uint8_t*) p)[k] != 0)
2390 *r = (uint8_t*) p + start;
2397 static bool message_end_of_signature(sd_bus_message *m) {
2398 struct bus_container *c;
2402 c = message_get_container(m);
2403 return !c->signature || c->signature[c->index] == 0;
2406 static bool message_end_of_array(sd_bus_message *m, size_t index) {
2407 struct bus_container *c;
2411 c = message_get_container(m);
2415 return index >= c->begin + BUS_MESSAGE_BSWAP32(m, *c->array_size);
2418 int sd_bus_message_at_end(sd_bus_message *m, int complete) {
2419 assert_return(m, -EINVAL);
2420 assert_return(m->sealed, -EPERM);
2422 if (complete && m->n_containers > 0)
2425 if (message_end_of_signature(m))
2428 if (message_end_of_array(m, m->rindex))
2434 static struct bus_body_part* find_part(sd_bus_message *m, size_t index, size_t sz, void **p) {
2435 struct bus_body_part *part;
2441 if (m->cached_rindex_part && index >= m->cached_rindex_part_begin) {
2442 part = m->cached_rindex_part;
2443 begin = m->cached_rindex_part_begin;
2453 if (index + sz <= begin + part->size) {
2455 r = bus_body_part_map(part);
2460 *p = (uint8_t*) part->data + index - begin;
2462 m->cached_rindex_part = part;
2463 m->cached_rindex_part_begin = begin;
2468 begin += part->size;
2475 static int message_peek_body(
2482 size_t k, start, end, padding;
2483 struct bus_body_part *part;
2490 if (message_end_of_array(m, *rindex))
2493 start = ALIGN_TO((size_t) *rindex, align);
2494 padding = start - *rindex;
2495 end = start + nbytes;
2497 if (end > BUS_MESSAGE_BODY_SIZE(m))
2500 part = find_part(m, *rindex, padding, (void**) &q);
2505 /* Verify padding */
2506 for (k = 0; k < padding; k++)
2511 part = find_part(m, start, nbytes, (void**) &q);
2523 static bool validate_nul(const char *s, size_t l) {
2525 /* Check for NUL chars in the string */
2526 if (memchr(s, 0, l))
2529 /* Check for NUL termination */
2536 static bool validate_string(const char *s, size_t l) {
2538 if (!validate_nul(s, l))
2541 /* Check if valid UTF8 */
2542 if (!utf8_is_valid(s))
2548 static bool validate_signature(const char *s, size_t l) {
2550 if (!validate_nul(s, l))
2553 /* Check if valid signature */
2554 if (!signature_is_valid(s, true))
2560 static bool validate_object_path(const char *s, size_t l) {
2562 if (!validate_nul(s, l))
2565 if (!object_path_is_valid(s))
2571 _public_ int sd_bus_message_read_basic(sd_bus_message *m, char type, void *p) {
2572 struct bus_container *c;
2576 assert_return(m, -EINVAL);
2577 assert_return(m->sealed, -EPERM);
2578 assert_return(bus_type_is_basic(type), -EINVAL);
2580 if (message_end_of_signature(m))
2583 if (message_end_of_array(m, m->rindex))
2586 c = message_get_container(m);
2587 if (c->signature[c->index] != type)
2592 case SD_BUS_TYPE_STRING:
2593 case SD_BUS_TYPE_OBJECT_PATH: {
2598 r = message_peek_body(m, &rindex, 4, 4, &q);
2602 l = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2603 r = message_peek_body(m, &rindex, 1, l+1, &q);
2609 if (type == SD_BUS_TYPE_OBJECT_PATH) {
2610 if (!validate_object_path(q, l))
2613 if (!validate_string(q, l))
2619 *(const char**) p = q;
2624 case SD_BUS_TYPE_SIGNATURE: {
2629 r = message_peek_body(m, &rindex, 1, 1, &q);
2634 r = message_peek_body(m, &rindex, 1, l+1, &q);
2640 if (!validate_signature(q, l))
2646 *(const char**) p = q;
2654 align = bus_type_get_alignment(type);
2655 sz = bus_type_get_size(type);
2656 assert(align > 0 && sz > 0);
2659 r = message_peek_body(m, &rindex, align, sz, &q);
2665 case SD_BUS_TYPE_BYTE:
2667 *(uint8_t*) p = *(uint8_t*) q;
2670 case SD_BUS_TYPE_BOOLEAN:
2672 *(unsigned*) p = !!*(uint32_t*) q;
2675 case SD_BUS_TYPE_INT16:
2676 case SD_BUS_TYPE_UINT16:
2678 *(uint16_t*) p = BUS_MESSAGE_BSWAP16(m, *(uint16_t*) q);
2681 case SD_BUS_TYPE_INT32:
2682 case SD_BUS_TYPE_UINT32:
2684 *(uint32_t*) p = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2687 case SD_BUS_TYPE_INT64:
2688 case SD_BUS_TYPE_UINT64:
2689 case SD_BUS_TYPE_DOUBLE:
2691 *(uint64_t*) p = BUS_MESSAGE_BSWAP64(m, *(uint64_t*) q);
2694 case SD_BUS_TYPE_UNIX_FD: {
2697 j = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2702 *(int*) p = m->fds[j];
2707 assert_not_reached("Unknown basic type...");
2716 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2722 static int bus_message_enter_array(
2724 struct bus_container *c,
2725 const char *contents,
2726 uint32_t **array_size) {
2737 if (!signature_is_single(contents, true))
2740 alignment = bus_type_get_alignment(contents[0]);
2744 if (!c->signature || c->signature[c->index] == 0)
2747 if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
2750 if (!startswith(c->signature + c->index + 1, contents))
2754 r = message_peek_body(m, &rindex, 4, 4, &q);
2758 if (BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q) > BUS_ARRAY_MAX_SIZE)
2761 r = message_peek_body(m, &rindex, alignment, 0, NULL);
2767 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2768 c->index += 1 + strlen(contents);
2772 *array_size = (uint32_t*) q;
2777 static int bus_message_enter_variant(
2779 struct bus_container *c,
2780 const char *contents) {
2791 if (!signature_is_single(contents, false))
2794 if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
2797 if (!c->signature || c->signature[c->index] == 0)
2800 if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
2804 r = message_peek_body(m, &rindex, 1, 1, &q);
2809 r = message_peek_body(m, &rindex, 1, l+1, &q);
2815 if (!validate_signature(q, l))
2818 if (!streq(q, contents))
2821 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2829 static int bus_message_enter_struct(
2831 struct bus_container *c,
2832 const char *contents) {
2841 if (!signature_is_valid(contents, false))
2844 if (!c->signature || c->signature[c->index] == 0)
2847 l = strlen(contents);
2849 if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
2850 !startswith(c->signature + c->index + 1, contents) ||
2851 c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
2854 r = message_peek_body(m, &m->rindex, 8, 0, NULL);
2858 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2859 c->index += 1 + l + 1;
2864 static int bus_message_enter_dict_entry(
2866 struct bus_container *c,
2867 const char *contents) {
2876 if (!signature_is_pair(contents))
2879 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2882 if (!c->signature || c->signature[c->index] == 0)
2885 l = strlen(contents);
2887 if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
2888 !startswith(c->signature + c->index + 1, contents) ||
2889 c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
2892 r = message_peek_body(m, &m->rindex, 8, 0, NULL);
2896 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2897 c->index += 1 + l + 1;
2902 _public_ int sd_bus_message_enter_container(sd_bus_message *m,
2904 const char *contents) {
2905 struct bus_container *c, *w;
2906 uint32_t *array_size = NULL;
2911 assert_return(m, -EINVAL);
2912 assert_return(m->sealed, -EPERM);
2913 assert_return(type != 0 || !contents, -EINVAL);
2915 if (type == 0 || !contents) {
2919 /* Allow entering into anonymous containers */
2920 r = sd_bus_message_peek_type(m, &tt, &cc);
2924 if (type != 0 && type != tt)
2927 if (contents && !streq(contents, cc))
2935 * We enforce a global limit on container depth, that is much
2936 * higher than the 32 structs and 32 arrays the specification
2937 * mandates. This is simpler to implement for us, and we need
2938 * this only to ensure our container array doesn't grow
2939 * without bounds. We are happy to return any data from a
2940 * message as long as the data itself is valid, even if the
2941 * overall message might be not.
2943 * Note that the message signature is validated when
2944 * parsing the headers, and that validation does check the
2947 * Note that the specification defines no limits on the depth
2948 * of stacked variants, but we do.
2950 if (m->n_containers >= BUS_CONTAINER_DEPTH)
2953 w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
2958 if (message_end_of_signature(m))
2961 if (message_end_of_array(m, m->rindex))
2964 c = message_get_container(m);
2966 signature = strdup(contents);
2970 c->saved_index = c->index;
2973 if (type == SD_BUS_TYPE_ARRAY)
2974 r = bus_message_enter_array(m, c, contents, &array_size);
2975 else if (type == SD_BUS_TYPE_VARIANT)
2976 r = bus_message_enter_variant(m, c, contents);
2977 else if (type == SD_BUS_TYPE_STRUCT)
2978 r = bus_message_enter_struct(m, c, contents);
2979 else if (type == SD_BUS_TYPE_DICT_ENTRY)
2980 r = bus_message_enter_dict_entry(m, c, contents);
2989 /* OK, let's fill it in */
2990 w += m->n_containers++;
2991 w->enclosing = type;
2992 w->signature = signature;
2994 w->array_size = array_size;
2996 w->begin = m->rindex;
3001 _public_ int sd_bus_message_exit_container(sd_bus_message *m) {
3002 struct bus_container *c;
3004 assert_return(m, -EINVAL);
3005 assert_return(m->sealed, -EPERM);
3006 assert_return(m->n_containers > 0, -EINVAL);
3008 c = message_get_container(m);
3009 if (c->enclosing == SD_BUS_TYPE_ARRAY) {
3012 l = BUS_MESSAGE_BSWAP32(m, *c->array_size);
3013 if (c->begin + l != m->rindex)
3017 if (c->signature && c->signature[c->index] != 0)
3027 static void message_quit_container(sd_bus_message *m) {
3028 struct bus_container *c;
3032 assert(m->n_containers > 0);
3034 c = message_get_container(m);
3037 assert(m->rindex >= c->before);
3038 m->rindex = c->before;
3040 /* Free container */
3044 /* Correct index of new top-level container */
3045 c = message_get_container(m);
3046 c->index = c->saved_index;
3049 _public_ int sd_bus_message_peek_type(sd_bus_message *m, char *type, const char **contents) {
3050 struct bus_container *c;
3053 assert_return(m, -EINVAL);
3054 assert_return(m->sealed, -EPERM);
3056 if (message_end_of_signature(m))
3059 if (message_end_of_array(m, m->rindex))
3062 c = message_get_container(m);
3064 if (bus_type_is_basic(c->signature[c->index])) {
3068 *type = c->signature[c->index];
3072 if (c->signature[c->index] == SD_BUS_TYPE_ARRAY) {
3078 r = signature_element_length(c->signature+c->index+1, &l);
3084 sig = strndup(c->signature + c->index + 1, l);
3088 free(m->peeked_signature);
3089 m->peeked_signature = sig;
3095 *type = SD_BUS_TYPE_ARRAY;
3100 if (c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ||
3101 c->signature[c->index] == SD_BUS_TYPE_DICT_ENTRY_BEGIN) {
3107 r = signature_element_length(c->signature+c->index, &l);
3112 sig = strndup(c->signature + c->index + 1, l - 2);
3116 free(m->peeked_signature);
3117 m->peeked_signature = sig;
3123 *type = c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY;
3128 if (c->signature[c->index] == SD_BUS_TYPE_VARIANT) {
3134 r = message_peek_body(m, &rindex, 1, 1, &q);
3141 r = message_peek_body(m, &rindex, 1, l+1, &q);
3147 if (!validate_signature(q, l))
3154 *type = SD_BUS_TYPE_VARIANT;
3169 _public_ int sd_bus_message_rewind(sd_bus_message *m, int complete) {
3170 struct bus_container *c;
3172 assert_return(m, -EINVAL);
3173 assert_return(m->sealed, -EPERM);
3176 message_reset_containers(m);
3178 m->root_container.index = 0;
3180 c = message_get_container(m);
3182 c = message_get_container(m);
3185 m->rindex = c->begin;
3188 return !isempty(c->signature);
3190 static int message_read_ap(
3195 unsigned n_array, n_struct;
3196 TypeStack stack[BUS_CONTAINER_DEPTH];
3197 unsigned stack_ptr = 0;
3198 unsigned n_loop = 0;
3206 /* Ideally, we'd just call ourselves recursively on every
3207 * complex type. However, the state of a va_list that is
3208 * passed to a function is undefined after that function
3209 * returns. This means we need to docode the va_list linearly
3210 * in a single stackframe. We hence implement our own
3211 * home-grown stack in an array. */
3213 n_array = (unsigned) -1; /* lenght of current array entries */
3214 n_struct = strlen(types); /* length of current struct contents signature */
3221 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
3222 r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
3228 r = sd_bus_message_exit_container(m);
3236 if (n_array != (unsigned) -1)
3245 case SD_BUS_TYPE_BYTE:
3246 case SD_BUS_TYPE_BOOLEAN:
3247 case SD_BUS_TYPE_INT16:
3248 case SD_BUS_TYPE_UINT16:
3249 case SD_BUS_TYPE_INT32:
3250 case SD_BUS_TYPE_UINT32:
3251 case SD_BUS_TYPE_INT64:
3252 case SD_BUS_TYPE_UINT64:
3253 case SD_BUS_TYPE_DOUBLE:
3254 case SD_BUS_TYPE_STRING:
3255 case SD_BUS_TYPE_OBJECT_PATH:
3256 case SD_BUS_TYPE_SIGNATURE:
3257 case SD_BUS_TYPE_UNIX_FD: {
3260 p = va_arg(ap, void*);
3261 r = sd_bus_message_read_basic(m, *t, p);
3274 case SD_BUS_TYPE_ARRAY: {
3277 r = signature_element_length(t + 1, &k);
3283 memcpy(s, t + 1, k);
3286 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, s);
3297 if (n_array == (unsigned) -1) {
3302 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
3308 n_array = va_arg(ap, unsigned);
3313 case SD_BUS_TYPE_VARIANT: {
3316 s = va_arg(ap, const char *);
3320 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, s);
3330 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
3335 n_struct = strlen(s);
3336 n_array = (unsigned) -1;
3341 case SD_BUS_TYPE_STRUCT_BEGIN:
3342 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
3345 r = signature_element_length(t, &k);
3351 memcpy(s, t + 1, k - 2);
3354 r = sd_bus_message_enter_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
3364 if (n_array == (unsigned) -1) {
3369 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
3375 n_array = (unsigned) -1;
3388 _public_ int sd_bus_message_read(sd_bus_message *m, const char *types, ...) {
3392 assert_return(m, -EINVAL);
3393 assert_return(m->sealed, -EPERM);
3394 assert_return(types, -EINVAL);
3396 va_start(ap, types);
3397 r = message_read_ap(m, types, ap);
3403 _public_ int sd_bus_message_skip(sd_bus_message *m, const char *types) {
3406 assert_return(m, -EINVAL);
3407 assert_return(m->sealed, -EPERM);
3408 assert_return(types, -EINVAL);
3415 case SD_BUS_TYPE_BYTE:
3416 case SD_BUS_TYPE_BOOLEAN:
3417 case SD_BUS_TYPE_INT16:
3418 case SD_BUS_TYPE_UINT16:
3419 case SD_BUS_TYPE_INT32:
3420 case SD_BUS_TYPE_UINT32:
3421 case SD_BUS_TYPE_INT64:
3422 case SD_BUS_TYPE_UINT64:
3423 case SD_BUS_TYPE_DOUBLE:
3424 case SD_BUS_TYPE_STRING:
3425 case SD_BUS_TYPE_OBJECT_PATH:
3426 case SD_BUS_TYPE_SIGNATURE:
3427 case SD_BUS_TYPE_UNIX_FD:
3429 r = sd_bus_message_read_basic(m, *types, NULL);
3433 r = sd_bus_message_skip(m, types + 1);
3439 case SD_BUS_TYPE_ARRAY: {
3442 r = signature_element_length(types + 1, &k);
3448 memcpy(s, types+1, k);
3451 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, s);
3456 r = sd_bus_message_skip(m, s);
3463 r = sd_bus_message_exit_container(m);
3468 r = sd_bus_message_skip(m, types + 1 + k);
3475 case SD_BUS_TYPE_VARIANT: {
3476 const char *contents;
3479 r = sd_bus_message_peek_type(m, &x, &contents);
3483 if (x != SD_BUS_TYPE_VARIANT)
3486 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, contents);
3490 r = sd_bus_message_skip(m, contents);
3495 r = sd_bus_message_exit_container(m);
3499 r = sd_bus_message_skip(m, types + 1);
3506 case SD_BUS_TYPE_STRUCT_BEGIN:
3507 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
3510 r = signature_element_length(types, &k);
3516 memcpy(s, types+1, k-2);
3519 r = sd_bus_message_enter_container(m, *types == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
3523 r = sd_bus_message_skip(m, s);
3528 r = sd_bus_message_exit_container(m);
3533 r = sd_bus_message_skip(m, types + k);
3545 _public_ int sd_bus_message_read_array(sd_bus_message *m,
3549 struct bus_container *c;
3555 assert_return(m, -EINVAL);
3556 assert_return(m->sealed, -EPERM);
3557 assert_return(bus_type_is_trivial(type), -EINVAL);
3558 assert_return(ptr, -EINVAL);
3559 assert_return(size, -EINVAL);
3560 assert_return(!BUS_MESSAGE_NEED_BSWAP(m), -ENOTSUP);
3562 align = bus_type_get_alignment(type);
3566 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
3570 c = message_get_container(m);
3571 sz = BUS_MESSAGE_BSWAP32(m, *c->array_size);
3573 r = message_peek_body(m, &m->rindex, align, sz, &p);
3581 r = sd_bus_message_exit_container(m);
3585 *ptr = (const void*) p;
3591 message_quit_container(m);
3595 static int message_peek_fields(
3606 return buffer_peek(BUS_MESSAGE_FIELDS(m), BUS_MESSAGE_FIELDS_SIZE(m), rindex, align, nbytes, ret);
3609 static int message_peek_field_uint32(
3620 r = message_peek_fields(m, ri, 4, 4, &q);
3625 *ret = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
3630 static int message_peek_field_string(
3632 bool (*validate)(const char *p),
3643 r = message_peek_field_uint32(m, ri, &l);
3647 r = message_peek_fields(m, ri, 1, l+1, &q);
3652 if (!validate_nul(q, l))
3658 if (!validate_string(q, l))
3668 static int message_peek_field_signature(
3680 r = message_peek_fields(m, ri, 1, 1, &q);
3685 r = message_peek_fields(m, ri, 1, l+1, &q);
3689 if (!validate_signature(q, l))
3698 static int message_skip_fields(
3701 uint32_t array_size,
3702 const char **signature) {
3704 size_t original_index;
3711 original_index = *ri;
3717 if (array_size != (uint32_t) -1 &&
3718 array_size <= *ri - original_index)
3725 if (t == SD_BUS_TYPE_STRING) {
3727 r = message_peek_field_string(m, NULL, ri, NULL);
3733 } else if (t == SD_BUS_TYPE_OBJECT_PATH) {
3735 r = message_peek_field_string(m, object_path_is_valid, ri, NULL);
3741 } else if (t == SD_BUS_TYPE_SIGNATURE) {
3743 r = message_peek_field_signature(m, ri, NULL);
3749 } else if (bus_type_is_basic(t)) {
3752 align = bus_type_get_alignment(t);
3753 k = bus_type_get_size(t);
3754 assert(align > 0 && k > 0);
3756 r = message_peek_fields(m, ri, align, k, NULL);
3762 } else if (t == SD_BUS_TYPE_ARRAY) {
3764 r = signature_element_length(*signature+1, &l);
3774 strncpy(sig, *signature + 1, l-1);
3777 alignment = bus_type_get_alignment(sig[0]);
3781 r = message_peek_field_uint32(m, ri, &nas);
3784 if (nas > BUS_ARRAY_MAX_SIZE)
3787 r = message_peek_fields(m, ri, alignment, 0, NULL);
3791 r = message_skip_fields(m, ri, nas, (const char**) &s);
3796 (*signature) += 1 + l;
3798 } else if (t == SD_BUS_TYPE_VARIANT) {
3801 r = message_peek_field_signature(m, ri, &s);
3805 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
3811 } else if (t == SD_BUS_TYPE_STRUCT ||
3812 t == SD_BUS_TYPE_DICT_ENTRY) {
3814 r = signature_element_length(*signature, &l);
3821 strncpy(sig, *signature + 1, l-1);
3824 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
3835 int bus_message_parse_fields(sd_bus_message *m) {
3838 uint32_t unix_fds = 0;
3842 for (ri = 0; ri < BUS_MESSAGE_FIELDS_SIZE(m); ) {
3843 const char *signature;
3846 r = message_peek_fields(m, &ri, 8, 1, (void**) &header);
3850 r = message_peek_field_signature(m, &ri, &signature);
3855 case _SD_BUS_MESSAGE_HEADER_INVALID:
3858 case SD_BUS_MESSAGE_HEADER_PATH:
3863 if (!streq(signature, "o"))
3866 r = message_peek_field_string(m, object_path_is_valid, &ri, &m->path);
3869 case SD_BUS_MESSAGE_HEADER_INTERFACE:
3874 if (!streq(signature, "s"))
3877 r = message_peek_field_string(m, interface_name_is_valid, &ri, &m->interface);
3880 case SD_BUS_MESSAGE_HEADER_MEMBER:
3885 if (!streq(signature, "s"))
3888 r = message_peek_field_string(m, member_name_is_valid, &ri, &m->member);
3891 case SD_BUS_MESSAGE_HEADER_ERROR_NAME:
3896 if (!streq(signature, "s"))
3899 r = message_peek_field_string(m, error_name_is_valid, &ri, &m->error.name);
3902 case SD_BUS_MESSAGE_HEADER_DESTINATION:
3907 if (!streq(signature, "s"))
3910 r = message_peek_field_string(m, service_name_is_valid, &ri, &m->destination);
3913 case SD_BUS_MESSAGE_HEADER_SENDER:
3918 if (!streq(signature, "s"))
3921 r = message_peek_field_string(m, service_name_is_valid, &ri, &m->sender);
3925 case SD_BUS_MESSAGE_HEADER_SIGNATURE: {
3929 if (m->root_container.signature)
3932 if (!streq(signature, "g"))
3935 r = message_peek_field_signature(m, &ri, &s);
3943 free(m->root_container.signature);
3944 m->root_container.signature = c;
3948 case SD_BUS_MESSAGE_HEADER_REPLY_SERIAL:
3949 if (m->reply_serial != 0)
3952 if (!streq(signature, "u"))
3955 r = message_peek_field_uint32(m, &ri, &m->reply_serial);
3959 if (m->reply_serial == 0)
3964 case SD_BUS_MESSAGE_HEADER_UNIX_FDS:
3968 if (!streq(signature, "u"))
3971 r = message_peek_field_uint32(m, &ri, &unix_fds);
3981 r = message_skip_fields(m, &ri, (uint32_t) -1, (const char **) &signature);
3988 if (m->n_fds != unix_fds)
3991 if (isempty(m->root_container.signature) != (BUS_MESSAGE_BODY_SIZE(m) == 0))
3994 switch (m->header->type) {
3996 case SD_BUS_MESSAGE_SIGNAL:
3997 if (!m->path || !m->interface || !m->member)
4001 case SD_BUS_MESSAGE_METHOD_CALL:
4003 if (!m->path || !m->member)
4008 case SD_BUS_MESSAGE_METHOD_RETURN:
4010 if (m->reply_serial == 0)
4014 case SD_BUS_MESSAGE_METHOD_ERROR:
4016 if (m->reply_serial == 0 || !m->error.name)
4021 /* Try to read the error message, but if we can't it's a non-issue */
4022 if (m->header->type == SD_BUS_MESSAGE_METHOD_ERROR)
4023 sd_bus_message_read(m, "s", &m->error.message);
4028 int bus_message_seal(sd_bus_message *m, uint64_t serial) {
4029 struct bus_body_part *part;
4039 if (m->n_containers > 0)
4045 /* If there's a non-trivial signature set, then add it in here */
4046 if (!isempty(m->root_container.signature)) {
4047 r = message_append_field_signature(m, SD_BUS_MESSAGE_HEADER_SIGNATURE, m->root_container.signature, NULL);
4053 r = message_append_field_uint32(m, SD_BUS_MESSAGE_HEADER_UNIX_FDS, m->n_fds);
4058 /* Add padding at the end of the fields part, since we know
4059 * the body needs to start at an 8 byte alignment. We made
4060 * sure we allocated enough space for this, so all we need to
4061 * do here is to zero it out. */
4062 l = BUS_MESSAGE_FIELDS_SIZE(m);
4065 memset((uint8_t*) BUS_MESSAGE_FIELDS(m) + l, 0, a);
4067 /* If this is something we can send as memfd, then let's seal
4068 the memfd now. Note that we can send memfds as payload only
4069 for directed messages, and not for broadcasts. */
4070 if (m->destination && m->bus && m->bus->use_memfd) {
4071 MESSAGE_FOREACH_PART(part, i, m)
4072 if (part->memfd >= 0 && !part->sealed && (part->size > MEMFD_MIN_SIZE || m->bus->use_memfd < 0)) {
4073 bus_body_part_unmap(part);
4075 if (ioctl(part->memfd, KDBUS_CMD_MEMFD_SEAL_SET, 1) >= 0)
4076 part->sealed = true;
4080 m->header->serial = serial;
4086 _public_ int sd_bus_message_set_destination(sd_bus_message *m, const char *destination) {
4087 assert_return(m, -EINVAL);
4088 assert_return(destination, -EINVAL);
4089 assert_return(!m->sealed, -EPERM);
4090 assert_return(!m->destination, -EEXIST);
4092 return message_append_field_string(m, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &m->destination);
4095 int bus_message_dump(sd_bus_message *m, FILE *f, bool with_header) {
4096 const char *u = NULL, *uu = NULL, *s = NULL;
4097 char **cmdline = NULL;
4100 uid_t owner, audit_loginuid;
4101 uint32_t audit_sessionid;
4117 "\tfields_size=%u\n"
4122 "\tdestination=%s\n"
4125 "\treply_serial=%u\n"
4127 "\tn_body_parts=%u\n",
4134 BUS_MESSAGE_SERIAL(m),
4135 BUS_MESSAGE_FIELDS_SIZE(m),
4136 BUS_MESSAGE_BODY_SIZE(m),
4138 strna(m->interface),
4140 strna(m->destination),
4142 strna(m->root_container.signature),
4147 if (sd_bus_error_is_set(&m->error))
4150 "\terror.message=%s\n",
4151 strna(m->error.name),
4152 strna(m->error.message));
4155 fprintf(f, "\tpid=%lu\n", (unsigned long) m->pid);
4157 fprintf(f, "\ttid=%lu\n", (unsigned long) m->tid);
4159 fprintf(f, "\tuid=%lu\n", (unsigned long) m->uid);
4161 fprintf(f, "\tgid=%lu\n", (unsigned long) m->gid);
4162 if (m->pid_starttime != 0)
4163 fprintf(f, "\tpid_starttime=%llu\n", (unsigned long long) m->pid_starttime);
4164 if (m->monotonic != 0)
4165 fprintf(f, "\tmonotonic=%llu\n", (unsigned long long) m->monotonic);
4166 if (m->realtime != 0)
4167 fprintf(f, "\trealtime=%llu\n", (unsigned long long) m->realtime);
4169 fprintf(f, "\texe=[%s]\n", m->exe);
4171 fprintf(f, "\tcomm=[%s]\n", m->comm);
4173 fprintf(f, "\ttid_comm=[%s]\n", m->tid_comm);
4175 fprintf(f, "\tlabel=[%s]\n", m->label);
4177 fprintf(f, "\tcgroup=[%s]\n", m->cgroup);
4179 sd_bus_message_get_unit(m, &u);
4181 fprintf(f, "\tunit=[%s]\n", u);
4182 sd_bus_message_get_user_unit(m, &uu);
4184 fprintf(f, "\tuser_unit=[%s]\n", uu);
4185 sd_bus_message_get_session(m, &s);
4187 fprintf(f, "\tsession=[%s]\n", s);
4188 if (sd_bus_message_get_owner_uid(m, &owner) >= 0)
4189 fprintf(f, "\towner_uid=%lu\n", (unsigned long) owner);
4190 if (sd_bus_message_get_audit_loginuid(m, &audit_loginuid) >= 0)
4191 fprintf(f, "\taudit_loginuid=%lu\n", (unsigned long) audit_loginuid);
4192 if (sd_bus_message_get_audit_sessionid(m, &audit_sessionid) >= 0)
4193 fprintf(f, "\taudit_sessionid=%lu\n", (unsigned long) audit_sessionid);
4195 r = sd_bus_message_has_effective_cap(m, 5);
4197 fprintf(f, "\tCAP_KILL=%s\n", yes_no(r));
4199 if (sd_bus_message_get_cmdline(m, &cmdline) >= 0) {
4202 fputs("\tcmdline=[", f);
4203 STRV_FOREACH(c, cmdline) {
4214 r = sd_bus_message_rewind(m, true);
4216 log_error("Failed to rewind: %s", strerror(-r));
4220 fprintf(f, "BEGIN_MESSAGE \"%s\" {\n", strempty(m->root_container.signature));
4223 _cleanup_free_ char *prefix = NULL;
4224 const char *contents = NULL;
4239 r = sd_bus_message_peek_type(m, &type, &contents);
4241 log_error("Failed to peek type: %s", strerror(-r));
4248 r = sd_bus_message_exit_container(m);
4250 log_error("Failed to exit container: %s", strerror(-r));
4256 prefix = strrep("\t", level);
4260 if (type == SD_BUS_TYPE_ARRAY)
4261 fprintf(f, "%s} END_ARRAY \n", prefix);
4262 else if (type == SD_BUS_TYPE_VARIANT)
4263 fprintf(f, "%s} END_VARIANT\n", prefix);
4264 else if (type == SD_BUS_TYPE_STRUCT)
4265 fprintf(f, "%s} END_STRUCT\n", prefix);
4266 else if (type == SD_BUS_TYPE_DICT_ENTRY)
4267 fprintf(f, "%s} END_DICT_ENTRY\n", prefix);
4272 prefix = strrep("\t", level);
4276 if (bus_type_is_container(type) > 0) {
4277 r = sd_bus_message_enter_container(m, type, contents);
4279 log_error("Failed to enter container: %s", strerror(-r));
4283 if (type == SD_BUS_TYPE_ARRAY)
4284 fprintf(f, "%sBEGIN_ARRAY \"%s\" {\n", prefix, contents);
4285 else if (type == SD_BUS_TYPE_VARIANT)
4286 fprintf(f, "%sBEGIN_VARIANT \"%s\" {\n", prefix, contents);
4287 else if (type == SD_BUS_TYPE_STRUCT)
4288 fprintf(f, "%sBEGIN_STRUCT \"%s\" {\n", prefix, contents);
4289 else if (type == SD_BUS_TYPE_DICT_ENTRY)
4290 fprintf(f, "%sBEGIN_DICT_ENTRY \"%s\" {\n", prefix, contents);
4297 r = sd_bus_message_read_basic(m, type, &basic);
4299 log_error("Failed to get basic: %s", strerror(-r));
4307 case SD_BUS_TYPE_BYTE:
4308 fprintf(f, "%sBYTE: %u\n", prefix, basic.u8);
4311 case SD_BUS_TYPE_BOOLEAN:
4312 fprintf(f, "%sBOOLEAN: %s\n", prefix, yes_no(basic.i));
4315 case SD_BUS_TYPE_INT16:
4316 fprintf(f, "%sINT16: %i\n", prefix, basic.s16);
4319 case SD_BUS_TYPE_UINT16:
4320 fprintf(f, "%sUINT16: %u\n", prefix, basic.u16);
4323 case SD_BUS_TYPE_INT32:
4324 fprintf(f, "%sINT32: %i\n", prefix, basic.s32);
4327 case SD_BUS_TYPE_UINT32:
4328 fprintf(f, "%sUINT32: %u\n", prefix, basic.u32);
4331 case SD_BUS_TYPE_INT64:
4332 fprintf(f, "%sINT64: %lli\n", prefix, (long long) basic.s64);
4335 case SD_BUS_TYPE_UINT64:
4336 fprintf(f, "%sUINT64: %llu\n", prefix, (unsigned long long) basic.u64);
4339 case SD_BUS_TYPE_DOUBLE:
4340 fprintf(f, "%sDOUBLE: %g\n", prefix, basic.d64);
4343 case SD_BUS_TYPE_STRING:
4344 fprintf(f, "%sSTRING: \"%s\"\n", prefix, basic.string);
4347 case SD_BUS_TYPE_OBJECT_PATH:
4348 fprintf(f, "%sOBJECT_PATH: \"%s\"\n", prefix, basic.string);
4351 case SD_BUS_TYPE_SIGNATURE:
4352 fprintf(f, "%sSIGNATURE: \"%s\"\n", prefix, basic.string);
4355 case SD_BUS_TYPE_UNIX_FD:
4356 fprintf(f, "%sUNIX_FD: %i\n", prefix, basic.i);
4360 assert_not_reached("Unknown basic type.");
4364 fprintf(f, "} END_MESSAGE\n");
4368 int bus_message_get_blob(sd_bus_message *m, void **buffer, size_t *sz) {
4372 struct bus_body_part *part;
4378 total = BUS_MESSAGE_SIZE(m);
4384 e = mempcpy(p, m->header, BUS_MESSAGE_BODY_BEGIN(m));
4385 MESSAGE_FOREACH_PART(part, i, m)
4386 e = mempcpy(e, part->data, part->size);
4388 assert(total == (size_t) ((uint8_t*) e - (uint8_t*) p));
4396 int bus_message_read_strv_extend(sd_bus_message *m, char ***l) {
4402 r = sd_bus_message_enter_container(m, 'a', "s");
4409 r = sd_bus_message_read_basic(m, 's', &s);
4415 r = strv_extend(l, s);
4420 r = sd_bus_message_exit_container(m);
4427 int sd_bus_message_read_strv(sd_bus_message *m, char ***l) {
4431 assert_return(m, -EINVAL);
4432 assert_return(m->sealed, -EPERM);
4433 assert_return(l, -EINVAL);
4435 r = bus_message_read_strv_extend(m, &strv);
4445 const char* bus_message_get_arg(sd_bus_message *m, unsigned i) {
4447 const char *t = NULL;
4452 r = sd_bus_message_rewind(m, true);
4456 for (j = 0; j <= i; j++) {
4459 r = sd_bus_message_peek_type(m, &type, NULL);
4463 if (type != SD_BUS_TYPE_STRING &&
4464 type != SD_BUS_TYPE_OBJECT_PATH &&
4465 type != SD_BUS_TYPE_SIGNATURE)
4468 r = sd_bus_message_read_basic(m, type, &t);
4476 bool bus_header_is_complete(struct bus_header *h, size_t size) {
4482 if (size < sizeof(struct bus_header))
4485 full = sizeof(struct bus_header) +
4486 (h->endian == SD_BUS_NATIVE_ENDIAN ? h->fields_size : bswap_32(h->fields_size));
4488 return size >= full;
4491 int bus_header_message_size(struct bus_header *h, size_t *sum) {
4497 if (h->endian == SD_BUS_NATIVE_ENDIAN) {
4498 fs = h->fields_size;
4500 } else if (h->endian == SD_BUS_REVERSE_ENDIAN) {
4501 fs = bswap_32(h->fields_size);
4502 bs = bswap_32(h->body_size);
4506 *sum = sizeof(struct bus_header) + ALIGN8(fs) + bs;
4510 _public_ int sd_bus_message_get_errno(sd_bus_message *m) {
4511 assert_return(m, -EINVAL);
4513 if (m->header->type != SD_BUS_MESSAGE_METHOD_ERROR)
4516 return sd_bus_error_get_errno(&m->error);
4519 _public_ const char* sd_bus_message_get_signature(sd_bus_message *m, int complete) {
4520 struct bus_container *c;
4522 assert_return(m, NULL);
4524 c = complete ? &m->root_container : message_get_container(m);
4525 return c->signature ?: "";
4528 _public_ int sd_bus_message_copy(sd_bus_message *m, sd_bus_message *source, int all) {
4529 bool done_something = false;
4532 assert_return(m, -EINVAL);
4533 assert_return(source, -EINVAL);
4534 assert_return(!m->sealed, -EPERM);
4535 assert_return(source->sealed, -EPERM);
4538 const char *contents;
4553 r = sd_bus_message_peek_type(source, &type, &contents);
4559 done_something = true;
4561 if (bus_type_is_container(type) > 0) {
4563 r = sd_bus_message_enter_container(source, type, contents);
4567 r = sd_bus_message_open_container(m, type, contents);
4571 r = sd_bus_message_copy(m, source, true);
4575 r = sd_bus_message_close_container(m);
4579 r = sd_bus_message_exit_container(source);
4586 r = sd_bus_message_read_basic(source, type, &basic);
4592 if (type == SD_BUS_TYPE_OBJECT_PATH ||
4593 type == SD_BUS_TYPE_SIGNATURE ||
4594 type == SD_BUS_TYPE_STRING)
4595 r = sd_bus_message_append_basic(m, type, basic.string);
4597 r = sd_bus_message_append_basic(m, type, &basic);
4604 return done_something;
4607 _public_ int sd_bus_message_verify_type(sd_bus_message *m, char type, const char *contents) {
4612 assert_return(m, -EINVAL);
4613 assert_return(m->sealed, -EPERM);
4614 assert_return(!type || bus_type_is_valid(type), -EINVAL);
4615 assert_return(!contents || signature_is_valid(contents, true), -EINVAL);
4616 assert_return(type || contents, -EINVAL);
4617 assert_return(!contents || !type || bus_type_is_container(type), -EINVAL);
4619 r = sd_bus_message_peek_type(m, &t, &c);
4623 if (type != 0 && type != t)
4626 if (contents && !streq_ptr(contents, c))