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:
1389 assert_cc(sizeof(int) == sizeof(uint32_t));
1395 case SD_BUS_TYPE_UNIX_FD: {
1403 if (!m->allow_fds) {
1416 fd = fcntl(z, F_DUPFD_CLOEXEC, 3);
1422 f = realloc(m->fds, sizeof(int) * (m->n_fds + 1));
1437 align = bus_type_get_alignment(type);
1438 sz = bus_type_get_size(type);
1445 a = message_extend_body(m, align, sz);
1451 if (type == SD_BUS_TYPE_STRING || type == SD_BUS_TYPE_OBJECT_PATH) {
1452 *(uint32_t*) a = sz - 5;
1453 memcpy((uint8_t*) a + 4, p, sz - 4);
1456 *stored = (const uint8_t*) a + 4;
1458 } else if (type == SD_BUS_TYPE_SIGNATURE) {
1459 *(uint8_t*) a = sz - 1;
1460 memcpy((uint8_t*) a + 1, p, sz - 1);
1463 *stored = (const uint8_t*) a + 1;
1464 } else if (type == SD_BUS_TYPE_UNIX_FD) {
1465 *(uint32_t*) a = fdi;
1479 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1486 close_nointr_nofail(fd);
1491 _public_ int sd_bus_message_append_basic(sd_bus_message *m, char type, const void *p) {
1492 return message_append_basic(m, type, p, NULL);
1495 _public_ int sd_bus_message_append_string_space(sd_bus_message *m, size_t size, char **s) {
1496 struct bus_container *c;
1499 assert_return(m, -EINVAL);
1500 assert_return(s, -EINVAL);
1501 assert_return(!m->sealed, -EPERM);
1502 assert_return(!m->poisoned, -ESTALE);
1504 c = message_get_container(m);
1506 if (c->signature && c->signature[c->index]) {
1507 /* Container signature is already set */
1509 if (c->signature[c->index] != SD_BUS_TYPE_STRING)
1514 /* Maybe we can append to the signature? But only if this is the top-level container*/
1515 if (c->enclosing != 0)
1518 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRING), NULL);
1525 a = message_extend_body(m, 4, 4 + size + 1);
1529 *(uint32_t*) a = size;
1534 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1540 static int bus_message_open_array(
1542 struct bus_container *c,
1543 const char *contents,
1544 uint32_t **array_size) {
1550 struct bus_body_part *o;
1557 if (!signature_is_single(contents, true))
1560 alignment = bus_type_get_alignment(contents[0]);
1564 if (c->signature && c->signature[c->index]) {
1566 /* Verify the existing signature */
1568 if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
1571 if (!startswith(c->signature + c->index + 1, contents))
1574 nindex = c->index + 1 + strlen(contents);
1578 if (c->enclosing != 0)
1581 /* Extend the existing signature */
1583 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_ARRAY), contents, NULL);
1589 nindex = e - c->signature;
1592 a = message_extend_body(m, 4, 4);
1597 op = m->body_end->data;
1598 os = m->body_end->size;
1600 /* Add alignment between size and first element */
1601 if (!message_extend_body(m, alignment, 0))
1604 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1607 /* location of array size might have changed so let's readjust a */
1608 if (o == m->body_end)
1609 a = adjust_pointer(a, op, os, m->body_end->data);
1616 static int bus_message_open_variant(
1618 struct bus_container *c,
1619 const char *contents) {
1628 if (!signature_is_single(contents, false))
1631 if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
1634 if (c->signature && c->signature[c->index]) {
1636 if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
1642 if (c->enclosing != 0)
1645 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_VARIANT), NULL);
1652 l = strlen(contents);
1653 a = message_extend_body(m, 1, 1 + l + 1);
1658 memcpy((uint8_t*) a + 1, contents, l + 1);
1660 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1666 static int bus_message_open_struct(
1668 struct bus_container *c,
1669 const char *contents) {
1677 if (!signature_is_valid(contents, false))
1680 if (c->signature && c->signature[c->index]) {
1683 l = strlen(contents);
1685 if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
1686 !startswith(c->signature + c->index + 1, contents) ||
1687 c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
1690 nindex = c->index + 1 + l + 1;
1694 if (c->enclosing != 0)
1697 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_BEGIN), contents, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_END), NULL);
1703 nindex = e - c->signature;
1706 /* Align contents to 8 byte boundary */
1707 if (!message_extend_body(m, 8, 0))
1710 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1716 static int bus_message_open_dict_entry(
1718 struct bus_container *c,
1719 const char *contents) {
1727 if (!signature_is_pair(contents))
1730 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1733 if (c->signature && c->signature[c->index]) {
1736 l = strlen(contents);
1738 if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
1739 !startswith(c->signature + c->index + 1, contents) ||
1740 c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
1743 nindex = c->index + 1 + l + 1;
1747 /* Align contents to 8 byte boundary */
1748 if (!message_extend_body(m, 8, 0))
1751 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1757 _public_ int sd_bus_message_open_container(
1760 const char *contents) {
1762 struct bus_container *c, *w;
1763 uint32_t *array_size = NULL;
1768 assert_return(m, -EINVAL);
1769 assert_return(!m->sealed, -EPERM);
1770 assert_return(contents, -EINVAL);
1771 assert_return(!m->poisoned, -ESTALE);
1773 /* Make sure we have space for one more container */
1774 w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
1782 c = message_get_container(m);
1784 signature = strdup(contents);
1790 /* Save old index in the parent container, in case we have to
1791 * abort this container */
1792 c->saved_index = c->index;
1793 before = m->header->body_size;
1795 if (type == SD_BUS_TYPE_ARRAY)
1796 r = bus_message_open_array(m, c, contents, &array_size);
1797 else if (type == SD_BUS_TYPE_VARIANT)
1798 r = bus_message_open_variant(m, c, contents);
1799 else if (type == SD_BUS_TYPE_STRUCT)
1800 r = bus_message_open_struct(m, c, contents);
1801 else if (type == SD_BUS_TYPE_DICT_ENTRY)
1802 r = bus_message_open_dict_entry(m, c, contents);
1811 /* OK, let's fill it in */
1812 w += m->n_containers++;
1813 w->enclosing = type;
1814 w->signature = signature;
1816 w->array_size = array_size;
1818 w->begin = m->rindex;
1823 _public_ int sd_bus_message_close_container(sd_bus_message *m) {
1824 struct bus_container *c;
1826 assert_return(m, -EINVAL);
1827 assert_return(!m->sealed, -EPERM);
1828 assert_return(m->n_containers > 0, -EINVAL);
1829 assert_return(!m->poisoned, -ESTALE);
1831 c = message_get_container(m);
1832 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1833 if (c->signature && c->signature[c->index] != 0)
1848 static int type_stack_push(TypeStack *stack, unsigned max, unsigned *i, const char *types, unsigned n_struct, unsigned n_array) {
1855 stack[*i].types = types;
1856 stack[*i].n_struct = n_struct;
1857 stack[*i].n_array = n_array;
1863 static int type_stack_pop(TypeStack *stack, unsigned max, unsigned *i, const char **types, unsigned *n_struct, unsigned *n_array) {
1874 *types = stack[*i].types;
1875 *n_struct = stack[*i].n_struct;
1876 *n_array = stack[*i].n_array;
1881 int bus_message_append_ap(
1886 unsigned n_array, n_struct;
1887 TypeStack stack[BUS_CONTAINER_DEPTH];
1888 unsigned stack_ptr = 0;
1896 n_array = (unsigned) -1;
1897 n_struct = strlen(types);
1902 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
1903 r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
1909 r = sd_bus_message_close_container(m);
1917 if (n_array != (unsigned) -1)
1926 case SD_BUS_TYPE_BYTE: {
1929 x = (uint8_t) va_arg(ap, int);
1930 r = sd_bus_message_append_basic(m, *t, &x);
1934 case SD_BUS_TYPE_BOOLEAN:
1935 case SD_BUS_TYPE_INT32:
1936 case SD_BUS_TYPE_UINT32:
1937 case SD_BUS_TYPE_UNIX_FD: {
1940 /* We assume a boolean is the same as int32_t */
1941 assert_cc(sizeof(int32_t) == sizeof(int));
1943 x = va_arg(ap, uint32_t);
1944 r = sd_bus_message_append_basic(m, *t, &x);
1948 case SD_BUS_TYPE_INT16:
1949 case SD_BUS_TYPE_UINT16: {
1952 x = (uint16_t) va_arg(ap, int);
1953 r = sd_bus_message_append_basic(m, *t, &x);
1957 case SD_BUS_TYPE_INT64:
1958 case SD_BUS_TYPE_UINT64:
1959 case SD_BUS_TYPE_DOUBLE: {
1962 x = va_arg(ap, uint64_t);
1963 r = sd_bus_message_append_basic(m, *t, &x);
1967 case SD_BUS_TYPE_STRING:
1968 case SD_BUS_TYPE_OBJECT_PATH:
1969 case SD_BUS_TYPE_SIGNATURE: {
1972 x = va_arg(ap, const char*);
1973 r = sd_bus_message_append_basic(m, *t, x);
1977 case SD_BUS_TYPE_ARRAY: {
1980 r = signature_element_length(t + 1, &k);
1986 memcpy(s, t + 1, k);
1989 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, s);
1994 if (n_array == (unsigned) -1) {
1999 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2005 n_array = va_arg(ap, unsigned);
2010 case SD_BUS_TYPE_VARIANT: {
2013 s = va_arg(ap, const char*);
2017 r = sd_bus_message_open_container(m, SD_BUS_TYPE_VARIANT, s);
2021 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2026 n_struct = strlen(s);
2027 n_array = (unsigned) -1;
2032 case SD_BUS_TYPE_STRUCT_BEGIN:
2033 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
2036 r = signature_element_length(t, &k);
2043 memcpy(s, t + 1, k - 2);
2046 r = sd_bus_message_open_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
2051 if (n_array == (unsigned) -1) {
2056 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2062 n_array = (unsigned) -1;
2078 _public_ int sd_bus_message_append(sd_bus_message *m, const char *types, ...) {
2082 assert_return(m, -EINVAL);
2083 assert_return(types, -EINVAL);
2084 assert_return(!m->sealed, -EPERM);
2085 assert_return(!m->poisoned, -ESTALE);
2087 va_start(ap, types);
2088 r = bus_message_append_ap(m, types, ap);
2094 _public_ int sd_bus_message_append_array_space(sd_bus_message *m,
2102 assert_return(m, -EINVAL);
2103 assert_return(!m->sealed, -EPERM);
2104 assert_return(bus_type_is_trivial(type), -EINVAL);
2105 assert_return(ptr || size == 0, -EINVAL);
2106 assert_return(!m->poisoned, -ESTALE);
2108 align = bus_type_get_alignment(type);
2109 sz = bus_type_get_size(type);
2111 assert_se(align > 0);
2117 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
2121 a = message_extend_body(m, align, size);
2125 r = sd_bus_message_close_container(m);
2133 _public_ int sd_bus_message_append_array(sd_bus_message *m,
2140 assert_return(m, -EINVAL);
2141 assert_return(!m->sealed, -EPERM);
2142 assert_return(bus_type_is_trivial(type), -EINVAL);
2143 assert_return(ptr || size == 0, -EINVAL);
2144 assert_return(!m->poisoned, -ESTALE);
2146 r = sd_bus_message_append_array_space(m, type, size, &p);
2151 memcpy(p, ptr, size);
2156 _public_ int sd_bus_message_append_array_memfd(sd_bus_message *m,
2159 _cleanup_close_ int copy_fd = -1;
2160 struct bus_body_part *part;
2172 if (!bus_type_is_trivial(type))
2177 r = sd_memfd_set_sealed(memfd, true);
2181 copy_fd = sd_memfd_dup_fd(memfd);
2185 r = sd_memfd_get_size(memfd, &size);
2189 align = bus_type_get_alignment(type);
2190 sz = bus_type_get_size(type);
2192 assert_se(align > 0);
2198 if (size > (uint64_t) (uint32_t) -1)
2201 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
2205 a = message_extend_body(m, align, 0);
2209 part = message_append_part(m);
2213 part->memfd = copy_fd;
2214 part->sealed = true;
2218 message_extend_containers(m, size);
2219 m->header->body_size += size;
2221 return sd_bus_message_close_container(m);
2224 _public_ int sd_bus_message_append_string_memfd(sd_bus_message *m, sd_memfd *memfd) {
2225 _cleanup_close_ int copy_fd = -1;
2226 struct bus_body_part *part;
2227 struct bus_container *c;
2232 assert_return(m, -EINVAL);
2233 assert_return(memfd, -EINVAL);
2234 assert_return(!m->sealed, -EPERM);
2235 assert_return(!m->poisoned, -ESTALE);
2237 r = sd_memfd_set_sealed(memfd, true);
2241 copy_fd = sd_memfd_dup_fd(memfd);
2245 r = sd_memfd_get_size(memfd, &size);
2249 /* We require this to be NUL terminated */
2253 if (size > (uint64_t) (uint32_t) -1)
2256 c = message_get_container(m);
2257 if (c->signature && c->signature[c->index]) {
2258 /* Container signature is already set */
2260 if (c->signature[c->index] != SD_BUS_TYPE_STRING)
2265 /* Maybe we can append to the signature? But only if this is the top-level container*/
2266 if (c->enclosing != 0)
2269 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRING), NULL);
2276 a = message_extend_body(m, 4, 4);
2280 *(uint32_t*) a = size - 1;
2282 part = message_append_part(m);
2286 part->memfd = copy_fd;
2287 part->sealed = true;
2291 message_extend_containers(m, size);
2292 m->header->body_size += size;
2294 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2300 _public_ int sd_bus_message_append_strv(sd_bus_message *m, char **l) {
2304 assert_return(m, -EINVAL);
2305 assert_return(!m->sealed, -EPERM);
2306 assert_return(!m->poisoned, -ESTALE);
2308 r = sd_bus_message_open_container(m, 'a', "s");
2312 STRV_FOREACH(i, l) {
2313 r = sd_bus_message_append_basic(m, 's', *i);
2318 return sd_bus_message_close_container(m);
2321 int bus_body_part_map(struct bus_body_part *part) {
2330 if (part->size <= 0)
2333 /* For smaller zero parts (as used for padding) we don't need to map anything... */
2334 if (part->memfd < 0 && part->is_zero && part->size < 8) {
2335 static const uint8_t zeroes[7] = { };
2336 part->data = (void*) zeroes;
2340 psz = PAGE_ALIGN(part->size);
2342 if (part->memfd >= 0)
2343 p = mmap(NULL, psz, PROT_READ, MAP_SHARED, part->memfd, 0);
2344 else if (part->is_zero)
2345 p = mmap(NULL, psz, PROT_READ, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
2349 if (p == MAP_FAILED)
2354 part->munmap_this = true;
2359 void bus_body_part_unmap(struct bus_body_part *part) {
2363 if (part->memfd < 0)
2369 if (!part->munmap_this)
2372 assert_se(munmap(part->data, part->mapped) == 0);
2376 part->munmap_this = false;
2381 static int buffer_peek(const void *p, uint32_t sz, size_t *rindex, size_t align, size_t nbytes, void **r) {
2382 size_t k, start, end;
2387 start = ALIGN_TO((size_t) *rindex, align);
2388 end = start + nbytes;
2393 /* Verify that padding is 0 */
2394 for (k = *rindex; k < start; k++)
2395 if (((const uint8_t*) p)[k] != 0)
2399 *r = (uint8_t*) p + start;
2406 static bool message_end_of_signature(sd_bus_message *m) {
2407 struct bus_container *c;
2411 c = message_get_container(m);
2412 return !c->signature || c->signature[c->index] == 0;
2415 static bool message_end_of_array(sd_bus_message *m, size_t index) {
2416 struct bus_container *c;
2420 c = message_get_container(m);
2424 return index >= c->begin + BUS_MESSAGE_BSWAP32(m, *c->array_size);
2427 int sd_bus_message_at_end(sd_bus_message *m, int complete) {
2428 assert_return(m, -EINVAL);
2429 assert_return(m->sealed, -EPERM);
2431 if (complete && m->n_containers > 0)
2434 if (message_end_of_signature(m))
2437 if (message_end_of_array(m, m->rindex))
2443 static struct bus_body_part* find_part(sd_bus_message *m, size_t index, size_t sz, void **p) {
2444 struct bus_body_part *part;
2450 if (m->cached_rindex_part && index >= m->cached_rindex_part_begin) {
2451 part = m->cached_rindex_part;
2452 begin = m->cached_rindex_part_begin;
2462 if (index + sz <= begin + part->size) {
2464 r = bus_body_part_map(part);
2469 *p = (uint8_t*) part->data + index - begin;
2471 m->cached_rindex_part = part;
2472 m->cached_rindex_part_begin = begin;
2477 begin += part->size;
2484 static int message_peek_body(
2491 size_t k, start, end, padding;
2492 struct bus_body_part *part;
2499 if (message_end_of_array(m, *rindex))
2502 start = ALIGN_TO((size_t) *rindex, align);
2503 padding = start - *rindex;
2504 end = start + nbytes;
2506 if (end > BUS_MESSAGE_BODY_SIZE(m))
2509 part = find_part(m, *rindex, padding, (void**) &q);
2514 /* Verify padding */
2515 for (k = 0; k < padding; k++)
2520 part = find_part(m, start, nbytes, (void**) &q);
2532 static bool validate_nul(const char *s, size_t l) {
2534 /* Check for NUL chars in the string */
2535 if (memchr(s, 0, l))
2538 /* Check for NUL termination */
2545 static bool validate_string(const char *s, size_t l) {
2547 if (!validate_nul(s, l))
2550 /* Check if valid UTF8 */
2551 if (!utf8_is_valid(s))
2557 static bool validate_signature(const char *s, size_t l) {
2559 if (!validate_nul(s, l))
2562 /* Check if valid signature */
2563 if (!signature_is_valid(s, true))
2569 static bool validate_object_path(const char *s, size_t l) {
2571 if (!validate_nul(s, l))
2574 if (!object_path_is_valid(s))
2580 _public_ int sd_bus_message_read_basic(sd_bus_message *m, char type, void *p) {
2581 struct bus_container *c;
2585 assert_return(m, -EINVAL);
2586 assert_return(m->sealed, -EPERM);
2587 assert_return(bus_type_is_basic(type), -EINVAL);
2589 if (message_end_of_signature(m))
2592 if (message_end_of_array(m, m->rindex))
2595 c = message_get_container(m);
2596 if (c->signature[c->index] != type)
2601 case SD_BUS_TYPE_STRING:
2602 case SD_BUS_TYPE_OBJECT_PATH: {
2607 r = message_peek_body(m, &rindex, 4, 4, &q);
2611 l = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2612 r = message_peek_body(m, &rindex, 1, l+1, &q);
2618 if (type == SD_BUS_TYPE_OBJECT_PATH) {
2619 if (!validate_object_path(q, l))
2622 if (!validate_string(q, l))
2628 *(const char**) p = q;
2633 case SD_BUS_TYPE_SIGNATURE: {
2638 r = message_peek_body(m, &rindex, 1, 1, &q);
2643 r = message_peek_body(m, &rindex, 1, l+1, &q);
2649 if (!validate_signature(q, l))
2655 *(const char**) p = q;
2663 align = bus_type_get_alignment(type);
2664 sz = bus_type_get_size(type);
2665 assert(align > 0 && sz > 0);
2668 r = message_peek_body(m, &rindex, align, sz, &q);
2674 case SD_BUS_TYPE_BYTE:
2676 *(uint8_t*) p = *(uint8_t*) q;
2679 case SD_BUS_TYPE_BOOLEAN:
2681 *(int*) p = !!*(uint32_t*) q;
2684 case SD_BUS_TYPE_INT16:
2685 case SD_BUS_TYPE_UINT16:
2687 *(uint16_t*) p = BUS_MESSAGE_BSWAP16(m, *(uint16_t*) q);
2690 case SD_BUS_TYPE_INT32:
2691 case SD_BUS_TYPE_UINT32:
2693 *(uint32_t*) p = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2696 case SD_BUS_TYPE_INT64:
2697 case SD_BUS_TYPE_UINT64:
2698 case SD_BUS_TYPE_DOUBLE:
2700 *(uint64_t*) p = BUS_MESSAGE_BSWAP64(m, *(uint64_t*) q);
2703 case SD_BUS_TYPE_UNIX_FD: {
2706 j = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2711 *(int*) p = m->fds[j];
2716 assert_not_reached("Unknown basic type...");
2725 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2731 static int bus_message_enter_array(
2733 struct bus_container *c,
2734 const char *contents,
2735 uint32_t **array_size) {
2746 if (!signature_is_single(contents, true))
2749 alignment = bus_type_get_alignment(contents[0]);
2753 if (!c->signature || c->signature[c->index] == 0)
2756 if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
2759 if (!startswith(c->signature + c->index + 1, contents))
2763 r = message_peek_body(m, &rindex, 4, 4, &q);
2767 if (BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q) > BUS_ARRAY_MAX_SIZE)
2770 r = message_peek_body(m, &rindex, alignment, 0, NULL);
2776 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2777 c->index += 1 + strlen(contents);
2781 *array_size = (uint32_t*) q;
2786 static int bus_message_enter_variant(
2788 struct bus_container *c,
2789 const char *contents) {
2800 if (!signature_is_single(contents, false))
2803 if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
2806 if (!c->signature || c->signature[c->index] == 0)
2809 if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
2813 r = message_peek_body(m, &rindex, 1, 1, &q);
2818 r = message_peek_body(m, &rindex, 1, l+1, &q);
2824 if (!validate_signature(q, l))
2827 if (!streq(q, contents))
2830 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2838 static int bus_message_enter_struct(
2840 struct bus_container *c,
2841 const char *contents) {
2850 if (!signature_is_valid(contents, false))
2853 if (!c->signature || c->signature[c->index] == 0)
2856 l = strlen(contents);
2858 if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
2859 !startswith(c->signature + c->index + 1, contents) ||
2860 c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
2863 r = message_peek_body(m, &m->rindex, 8, 0, NULL);
2867 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2868 c->index += 1 + l + 1;
2873 static int bus_message_enter_dict_entry(
2875 struct bus_container *c,
2876 const char *contents) {
2885 if (!signature_is_pair(contents))
2888 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2891 if (!c->signature || c->signature[c->index] == 0)
2894 l = strlen(contents);
2896 if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
2897 !startswith(c->signature + c->index + 1, contents) ||
2898 c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
2901 r = message_peek_body(m, &m->rindex, 8, 0, NULL);
2905 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2906 c->index += 1 + l + 1;
2911 _public_ int sd_bus_message_enter_container(sd_bus_message *m,
2913 const char *contents) {
2914 struct bus_container *c, *w;
2915 uint32_t *array_size = NULL;
2920 assert_return(m, -EINVAL);
2921 assert_return(m->sealed, -EPERM);
2922 assert_return(type != 0 || !contents, -EINVAL);
2924 if (type == 0 || !contents) {
2928 /* Allow entering into anonymous containers */
2929 r = sd_bus_message_peek_type(m, &tt, &cc);
2933 if (type != 0 && type != tt)
2936 if (contents && !streq(contents, cc))
2944 * We enforce a global limit on container depth, that is much
2945 * higher than the 32 structs and 32 arrays the specification
2946 * mandates. This is simpler to implement for us, and we need
2947 * this only to ensure our container array doesn't grow
2948 * without bounds. We are happy to return any data from a
2949 * message as long as the data itself is valid, even if the
2950 * overall message might be not.
2952 * Note that the message signature is validated when
2953 * parsing the headers, and that validation does check the
2956 * Note that the specification defines no limits on the depth
2957 * of stacked variants, but we do.
2959 if (m->n_containers >= BUS_CONTAINER_DEPTH)
2962 w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
2967 if (message_end_of_signature(m))
2970 if (message_end_of_array(m, m->rindex))
2973 c = message_get_container(m);
2975 signature = strdup(contents);
2979 c->saved_index = c->index;
2982 if (type == SD_BUS_TYPE_ARRAY)
2983 r = bus_message_enter_array(m, c, contents, &array_size);
2984 else if (type == SD_BUS_TYPE_VARIANT)
2985 r = bus_message_enter_variant(m, c, contents);
2986 else if (type == SD_BUS_TYPE_STRUCT)
2987 r = bus_message_enter_struct(m, c, contents);
2988 else if (type == SD_BUS_TYPE_DICT_ENTRY)
2989 r = bus_message_enter_dict_entry(m, c, contents);
2998 /* OK, let's fill it in */
2999 w += m->n_containers++;
3000 w->enclosing = type;
3001 w->signature = signature;
3003 w->array_size = array_size;
3005 w->begin = m->rindex;
3010 _public_ int sd_bus_message_exit_container(sd_bus_message *m) {
3011 struct bus_container *c;
3013 assert_return(m, -EINVAL);
3014 assert_return(m->sealed, -EPERM);
3015 assert_return(m->n_containers > 0, -EINVAL);
3017 c = message_get_container(m);
3018 if (c->enclosing == SD_BUS_TYPE_ARRAY) {
3021 l = BUS_MESSAGE_BSWAP32(m, *c->array_size);
3022 if (c->begin + l != m->rindex)
3026 if (c->signature && c->signature[c->index] != 0)
3036 static void message_quit_container(sd_bus_message *m) {
3037 struct bus_container *c;
3041 assert(m->n_containers > 0);
3043 c = message_get_container(m);
3046 assert(m->rindex >= c->before);
3047 m->rindex = c->before;
3049 /* Free container */
3053 /* Correct index of new top-level container */
3054 c = message_get_container(m);
3055 c->index = c->saved_index;
3058 _public_ int sd_bus_message_peek_type(sd_bus_message *m, char *type, const char **contents) {
3059 struct bus_container *c;
3062 assert_return(m, -EINVAL);
3063 assert_return(m->sealed, -EPERM);
3065 if (message_end_of_signature(m))
3068 if (message_end_of_array(m, m->rindex))
3071 c = message_get_container(m);
3073 if (bus_type_is_basic(c->signature[c->index])) {
3077 *type = c->signature[c->index];
3081 if (c->signature[c->index] == SD_BUS_TYPE_ARRAY) {
3087 r = signature_element_length(c->signature+c->index+1, &l);
3093 sig = strndup(c->signature + c->index + 1, l);
3097 free(m->peeked_signature);
3098 m->peeked_signature = sig;
3104 *type = SD_BUS_TYPE_ARRAY;
3109 if (c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ||
3110 c->signature[c->index] == SD_BUS_TYPE_DICT_ENTRY_BEGIN) {
3116 r = signature_element_length(c->signature+c->index, &l);
3121 sig = strndup(c->signature + c->index + 1, l - 2);
3125 free(m->peeked_signature);
3126 m->peeked_signature = sig;
3132 *type = c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY;
3137 if (c->signature[c->index] == SD_BUS_TYPE_VARIANT) {
3143 r = message_peek_body(m, &rindex, 1, 1, &q);
3150 r = message_peek_body(m, &rindex, 1, l+1, &q);
3156 if (!validate_signature(q, l))
3163 *type = SD_BUS_TYPE_VARIANT;
3178 _public_ int sd_bus_message_rewind(sd_bus_message *m, int complete) {
3179 struct bus_container *c;
3181 assert_return(m, -EINVAL);
3182 assert_return(m->sealed, -EPERM);
3185 message_reset_containers(m);
3187 m->root_container.index = 0;
3189 c = message_get_container(m);
3191 c = message_get_container(m);
3194 m->rindex = c->begin;
3197 return !isempty(c->signature);
3199 static int message_read_ap(
3204 unsigned n_array, n_struct;
3205 TypeStack stack[BUS_CONTAINER_DEPTH];
3206 unsigned stack_ptr = 0;
3207 unsigned n_loop = 0;
3215 /* Ideally, we'd just call ourselves recursively on every
3216 * complex type. However, the state of a va_list that is
3217 * passed to a function is undefined after that function
3218 * returns. This means we need to docode the va_list linearly
3219 * in a single stackframe. We hence implement our own
3220 * home-grown stack in an array. */
3222 n_array = (unsigned) -1; /* lenght of current array entries */
3223 n_struct = strlen(types); /* length of current struct contents signature */
3230 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
3231 r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
3237 r = sd_bus_message_exit_container(m);
3245 if (n_array != (unsigned) -1)
3254 case SD_BUS_TYPE_BYTE:
3255 case SD_BUS_TYPE_BOOLEAN:
3256 case SD_BUS_TYPE_INT16:
3257 case SD_BUS_TYPE_UINT16:
3258 case SD_BUS_TYPE_INT32:
3259 case SD_BUS_TYPE_UINT32:
3260 case SD_BUS_TYPE_INT64:
3261 case SD_BUS_TYPE_UINT64:
3262 case SD_BUS_TYPE_DOUBLE:
3263 case SD_BUS_TYPE_STRING:
3264 case SD_BUS_TYPE_OBJECT_PATH:
3265 case SD_BUS_TYPE_SIGNATURE:
3266 case SD_BUS_TYPE_UNIX_FD: {
3269 p = va_arg(ap, void*);
3270 r = sd_bus_message_read_basic(m, *t, p);
3283 case SD_BUS_TYPE_ARRAY: {
3286 r = signature_element_length(t + 1, &k);
3292 memcpy(s, t + 1, k);
3295 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, s);
3306 if (n_array == (unsigned) -1) {
3311 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
3317 n_array = va_arg(ap, unsigned);
3322 case SD_BUS_TYPE_VARIANT: {
3325 s = va_arg(ap, const char *);
3329 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, s);
3339 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
3344 n_struct = strlen(s);
3345 n_array = (unsigned) -1;
3350 case SD_BUS_TYPE_STRUCT_BEGIN:
3351 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
3354 r = signature_element_length(t, &k);
3360 memcpy(s, t + 1, k - 2);
3363 r = sd_bus_message_enter_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
3373 if (n_array == (unsigned) -1) {
3378 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
3384 n_array = (unsigned) -1;
3397 _public_ int sd_bus_message_read(sd_bus_message *m, const char *types, ...) {
3401 assert_return(m, -EINVAL);
3402 assert_return(m->sealed, -EPERM);
3403 assert_return(types, -EINVAL);
3405 va_start(ap, types);
3406 r = message_read_ap(m, types, ap);
3412 _public_ int sd_bus_message_skip(sd_bus_message *m, const char *types) {
3415 assert_return(m, -EINVAL);
3416 assert_return(m->sealed, -EPERM);
3417 assert_return(types, -EINVAL);
3424 case SD_BUS_TYPE_BYTE:
3425 case SD_BUS_TYPE_BOOLEAN:
3426 case SD_BUS_TYPE_INT16:
3427 case SD_BUS_TYPE_UINT16:
3428 case SD_BUS_TYPE_INT32:
3429 case SD_BUS_TYPE_UINT32:
3430 case SD_BUS_TYPE_INT64:
3431 case SD_BUS_TYPE_UINT64:
3432 case SD_BUS_TYPE_DOUBLE:
3433 case SD_BUS_TYPE_STRING:
3434 case SD_BUS_TYPE_OBJECT_PATH:
3435 case SD_BUS_TYPE_SIGNATURE:
3436 case SD_BUS_TYPE_UNIX_FD:
3438 r = sd_bus_message_read_basic(m, *types, NULL);
3442 r = sd_bus_message_skip(m, types + 1);
3448 case SD_BUS_TYPE_ARRAY: {
3451 r = signature_element_length(types + 1, &k);
3457 memcpy(s, types+1, k);
3460 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, s);
3465 r = sd_bus_message_skip(m, s);
3472 r = sd_bus_message_exit_container(m);
3477 r = sd_bus_message_skip(m, types + 1 + k);
3484 case SD_BUS_TYPE_VARIANT: {
3485 const char *contents;
3488 r = sd_bus_message_peek_type(m, &x, &contents);
3492 if (x != SD_BUS_TYPE_VARIANT)
3495 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, contents);
3499 r = sd_bus_message_skip(m, contents);
3504 r = sd_bus_message_exit_container(m);
3508 r = sd_bus_message_skip(m, types + 1);
3515 case SD_BUS_TYPE_STRUCT_BEGIN:
3516 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
3519 r = signature_element_length(types, &k);
3525 memcpy(s, types+1, k-2);
3528 r = sd_bus_message_enter_container(m, *types == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
3532 r = sd_bus_message_skip(m, s);
3537 r = sd_bus_message_exit_container(m);
3542 r = sd_bus_message_skip(m, types + k);
3554 _public_ int sd_bus_message_read_array(sd_bus_message *m,
3558 struct bus_container *c;
3564 assert_return(m, -EINVAL);
3565 assert_return(m->sealed, -EPERM);
3566 assert_return(bus_type_is_trivial(type), -EINVAL);
3567 assert_return(ptr, -EINVAL);
3568 assert_return(size, -EINVAL);
3569 assert_return(!BUS_MESSAGE_NEED_BSWAP(m), -ENOTSUP);
3571 align = bus_type_get_alignment(type);
3575 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
3579 c = message_get_container(m);
3580 sz = BUS_MESSAGE_BSWAP32(m, *c->array_size);
3582 r = message_peek_body(m, &m->rindex, align, sz, &p);
3590 r = sd_bus_message_exit_container(m);
3594 *ptr = (const void*) p;
3600 message_quit_container(m);
3604 static int message_peek_fields(
3615 return buffer_peek(BUS_MESSAGE_FIELDS(m), BUS_MESSAGE_FIELDS_SIZE(m), rindex, align, nbytes, ret);
3618 static int message_peek_field_uint32(
3629 r = message_peek_fields(m, ri, 4, 4, &q);
3634 *ret = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
3639 static int message_peek_field_string(
3641 bool (*validate)(const char *p),
3652 r = message_peek_field_uint32(m, ri, &l);
3656 r = message_peek_fields(m, ri, 1, l+1, &q);
3661 if (!validate_nul(q, l))
3667 if (!validate_string(q, l))
3677 static int message_peek_field_signature(
3689 r = message_peek_fields(m, ri, 1, 1, &q);
3694 r = message_peek_fields(m, ri, 1, l+1, &q);
3698 if (!validate_signature(q, l))
3707 static int message_skip_fields(
3710 uint32_t array_size,
3711 const char **signature) {
3713 size_t original_index;
3720 original_index = *ri;
3726 if (array_size != (uint32_t) -1 &&
3727 array_size <= *ri - original_index)
3734 if (t == SD_BUS_TYPE_STRING) {
3736 r = message_peek_field_string(m, NULL, ri, NULL);
3742 } else if (t == SD_BUS_TYPE_OBJECT_PATH) {
3744 r = message_peek_field_string(m, object_path_is_valid, ri, NULL);
3750 } else if (t == SD_BUS_TYPE_SIGNATURE) {
3752 r = message_peek_field_signature(m, ri, NULL);
3758 } else if (bus_type_is_basic(t)) {
3761 align = bus_type_get_alignment(t);
3762 k = bus_type_get_size(t);
3763 assert(align > 0 && k > 0);
3765 r = message_peek_fields(m, ri, align, k, NULL);
3771 } else if (t == SD_BUS_TYPE_ARRAY) {
3773 r = signature_element_length(*signature+1, &l);
3783 strncpy(sig, *signature + 1, l-1);
3786 alignment = bus_type_get_alignment(sig[0]);
3790 r = message_peek_field_uint32(m, ri, &nas);
3793 if (nas > BUS_ARRAY_MAX_SIZE)
3796 r = message_peek_fields(m, ri, alignment, 0, NULL);
3800 r = message_skip_fields(m, ri, nas, (const char**) &s);
3805 (*signature) += 1 + l;
3807 } else if (t == SD_BUS_TYPE_VARIANT) {
3810 r = message_peek_field_signature(m, ri, &s);
3814 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
3820 } else if (t == SD_BUS_TYPE_STRUCT ||
3821 t == SD_BUS_TYPE_DICT_ENTRY) {
3823 r = signature_element_length(*signature, &l);
3830 strncpy(sig, *signature + 1, l-1);
3833 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
3844 int bus_message_parse_fields(sd_bus_message *m) {
3847 uint32_t unix_fds = 0;
3851 for (ri = 0; ri < BUS_MESSAGE_FIELDS_SIZE(m); ) {
3852 const char *signature;
3855 r = message_peek_fields(m, &ri, 8, 1, (void**) &header);
3859 r = message_peek_field_signature(m, &ri, &signature);
3864 case _SD_BUS_MESSAGE_HEADER_INVALID:
3867 case SD_BUS_MESSAGE_HEADER_PATH:
3872 if (!streq(signature, "o"))
3875 r = message_peek_field_string(m, object_path_is_valid, &ri, &m->path);
3878 case SD_BUS_MESSAGE_HEADER_INTERFACE:
3883 if (!streq(signature, "s"))
3886 r = message_peek_field_string(m, interface_name_is_valid, &ri, &m->interface);
3889 case SD_BUS_MESSAGE_HEADER_MEMBER:
3894 if (!streq(signature, "s"))
3897 r = message_peek_field_string(m, member_name_is_valid, &ri, &m->member);
3900 case SD_BUS_MESSAGE_HEADER_ERROR_NAME:
3905 if (!streq(signature, "s"))
3908 r = message_peek_field_string(m, error_name_is_valid, &ri, &m->error.name);
3911 case SD_BUS_MESSAGE_HEADER_DESTINATION:
3916 if (!streq(signature, "s"))
3919 r = message_peek_field_string(m, service_name_is_valid, &ri, &m->destination);
3922 case SD_BUS_MESSAGE_HEADER_SENDER:
3927 if (!streq(signature, "s"))
3930 r = message_peek_field_string(m, service_name_is_valid, &ri, &m->sender);
3934 case SD_BUS_MESSAGE_HEADER_SIGNATURE: {
3938 if (m->root_container.signature)
3941 if (!streq(signature, "g"))
3944 r = message_peek_field_signature(m, &ri, &s);
3952 free(m->root_container.signature);
3953 m->root_container.signature = c;
3957 case SD_BUS_MESSAGE_HEADER_REPLY_SERIAL:
3958 if (m->reply_serial != 0)
3961 if (!streq(signature, "u"))
3964 r = message_peek_field_uint32(m, &ri, &m->reply_serial);
3968 if (m->reply_serial == 0)
3973 case SD_BUS_MESSAGE_HEADER_UNIX_FDS:
3977 if (!streq(signature, "u"))
3980 r = message_peek_field_uint32(m, &ri, &unix_fds);
3990 r = message_skip_fields(m, &ri, (uint32_t) -1, (const char **) &signature);
3997 if (m->n_fds != unix_fds)
4000 if (isempty(m->root_container.signature) != (BUS_MESSAGE_BODY_SIZE(m) == 0))
4003 switch (m->header->type) {
4005 case SD_BUS_MESSAGE_SIGNAL:
4006 if (!m->path || !m->interface || !m->member)
4010 case SD_BUS_MESSAGE_METHOD_CALL:
4012 if (!m->path || !m->member)
4017 case SD_BUS_MESSAGE_METHOD_RETURN:
4019 if (m->reply_serial == 0)
4023 case SD_BUS_MESSAGE_METHOD_ERROR:
4025 if (m->reply_serial == 0 || !m->error.name)
4030 /* Try to read the error message, but if we can't it's a non-issue */
4031 if (m->header->type == SD_BUS_MESSAGE_METHOD_ERROR)
4032 sd_bus_message_read(m, "s", &m->error.message);
4037 int bus_message_seal(sd_bus_message *m, uint64_t serial) {
4038 struct bus_body_part *part;
4048 if (m->n_containers > 0)
4054 /* If there's a non-trivial signature set, then add it in here */
4055 if (!isempty(m->root_container.signature)) {
4056 r = message_append_field_signature(m, SD_BUS_MESSAGE_HEADER_SIGNATURE, m->root_container.signature, NULL);
4062 r = message_append_field_uint32(m, SD_BUS_MESSAGE_HEADER_UNIX_FDS, m->n_fds);
4067 /* Add padding at the end of the fields part, since we know
4068 * the body needs to start at an 8 byte alignment. We made
4069 * sure we allocated enough space for this, so all we need to
4070 * do here is to zero it out. */
4071 l = BUS_MESSAGE_FIELDS_SIZE(m);
4074 memset((uint8_t*) BUS_MESSAGE_FIELDS(m) + l, 0, a);
4076 /* If this is something we can send as memfd, then let's seal
4077 the memfd now. Note that we can send memfds as payload only
4078 for directed messages, and not for broadcasts. */
4079 if (m->destination && m->bus && m->bus->use_memfd) {
4080 MESSAGE_FOREACH_PART(part, i, m)
4081 if (part->memfd >= 0 && !part->sealed && (part->size > MEMFD_MIN_SIZE || m->bus->use_memfd < 0)) {
4082 bus_body_part_unmap(part);
4084 if (ioctl(part->memfd, KDBUS_CMD_MEMFD_SEAL_SET, 1) >= 0)
4085 part->sealed = true;
4089 m->header->serial = serial;
4095 _public_ int sd_bus_message_set_destination(sd_bus_message *m, const char *destination) {
4096 assert_return(m, -EINVAL);
4097 assert_return(destination, -EINVAL);
4098 assert_return(!m->sealed, -EPERM);
4099 assert_return(!m->destination, -EEXIST);
4101 return message_append_field_string(m, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &m->destination);
4104 int bus_message_dump(sd_bus_message *m, FILE *f, bool with_header) {
4105 const char *u = NULL, *uu = NULL, *s = NULL;
4106 char **cmdline = NULL;
4109 uid_t owner, audit_loginuid;
4110 uint32_t audit_sessionid;
4126 "\tfields_size=%u\n"
4131 "\tdestination=%s\n"
4134 "\treply_serial=%u\n"
4136 "\tn_body_parts=%u\n",
4143 BUS_MESSAGE_SERIAL(m),
4144 BUS_MESSAGE_FIELDS_SIZE(m),
4145 BUS_MESSAGE_BODY_SIZE(m),
4147 strna(m->interface),
4149 strna(m->destination),
4151 strna(m->root_container.signature),
4156 if (sd_bus_error_is_set(&m->error))
4159 "\terror.message=%s\n",
4160 strna(m->error.name),
4161 strna(m->error.message));
4164 fprintf(f, "\tpid=%lu\n", (unsigned long) m->pid);
4166 fprintf(f, "\ttid=%lu\n", (unsigned long) m->tid);
4168 fprintf(f, "\tuid=%lu\n", (unsigned long) m->uid);
4170 fprintf(f, "\tgid=%lu\n", (unsigned long) m->gid);
4171 if (m->pid_starttime != 0)
4172 fprintf(f, "\tpid_starttime=%llu\n", (unsigned long long) m->pid_starttime);
4173 if (m->monotonic != 0)
4174 fprintf(f, "\tmonotonic=%llu\n", (unsigned long long) m->monotonic);
4175 if (m->realtime != 0)
4176 fprintf(f, "\trealtime=%llu\n", (unsigned long long) m->realtime);
4178 fprintf(f, "\texe=[%s]\n", m->exe);
4180 fprintf(f, "\tcomm=[%s]\n", m->comm);
4182 fprintf(f, "\ttid_comm=[%s]\n", m->tid_comm);
4184 fprintf(f, "\tlabel=[%s]\n", m->label);
4186 fprintf(f, "\tcgroup=[%s]\n", m->cgroup);
4188 sd_bus_message_get_unit(m, &u);
4190 fprintf(f, "\tunit=[%s]\n", u);
4191 sd_bus_message_get_user_unit(m, &uu);
4193 fprintf(f, "\tuser_unit=[%s]\n", uu);
4194 sd_bus_message_get_session(m, &s);
4196 fprintf(f, "\tsession=[%s]\n", s);
4197 if (sd_bus_message_get_owner_uid(m, &owner) >= 0)
4198 fprintf(f, "\towner_uid=%lu\n", (unsigned long) owner);
4199 if (sd_bus_message_get_audit_loginuid(m, &audit_loginuid) >= 0)
4200 fprintf(f, "\taudit_loginuid=%lu\n", (unsigned long) audit_loginuid);
4201 if (sd_bus_message_get_audit_sessionid(m, &audit_sessionid) >= 0)
4202 fprintf(f, "\taudit_sessionid=%lu\n", (unsigned long) audit_sessionid);
4204 r = sd_bus_message_has_effective_cap(m, 5);
4206 fprintf(f, "\tCAP_KILL=%s\n", yes_no(r));
4208 if (sd_bus_message_get_cmdline(m, &cmdline) >= 0) {
4211 fputs("\tcmdline=[", f);
4212 STRV_FOREACH(c, cmdline) {
4223 r = sd_bus_message_rewind(m, true);
4225 log_error("Failed to rewind: %s", strerror(-r));
4229 fprintf(f, "BEGIN_MESSAGE \"%s\" {\n", strempty(m->root_container.signature));
4232 _cleanup_free_ char *prefix = NULL;
4233 const char *contents = NULL;
4248 r = sd_bus_message_peek_type(m, &type, &contents);
4250 log_error("Failed to peek type: %s", strerror(-r));
4257 r = sd_bus_message_exit_container(m);
4259 log_error("Failed to exit container: %s", strerror(-r));
4265 prefix = strrep("\t", level);
4269 if (type == SD_BUS_TYPE_ARRAY)
4270 fprintf(f, "%s} END_ARRAY \n", prefix);
4271 else if (type == SD_BUS_TYPE_VARIANT)
4272 fprintf(f, "%s} END_VARIANT\n", prefix);
4273 else if (type == SD_BUS_TYPE_STRUCT)
4274 fprintf(f, "%s} END_STRUCT\n", prefix);
4275 else if (type == SD_BUS_TYPE_DICT_ENTRY)
4276 fprintf(f, "%s} END_DICT_ENTRY\n", prefix);
4281 prefix = strrep("\t", level);
4285 if (bus_type_is_container(type) > 0) {
4286 r = sd_bus_message_enter_container(m, type, contents);
4288 log_error("Failed to enter container: %s", strerror(-r));
4292 if (type == SD_BUS_TYPE_ARRAY)
4293 fprintf(f, "%sBEGIN_ARRAY \"%s\" {\n", prefix, contents);
4294 else if (type == SD_BUS_TYPE_VARIANT)
4295 fprintf(f, "%sBEGIN_VARIANT \"%s\" {\n", prefix, contents);
4296 else if (type == SD_BUS_TYPE_STRUCT)
4297 fprintf(f, "%sBEGIN_STRUCT \"%s\" {\n", prefix, contents);
4298 else if (type == SD_BUS_TYPE_DICT_ENTRY)
4299 fprintf(f, "%sBEGIN_DICT_ENTRY \"%s\" {\n", prefix, contents);
4306 r = sd_bus_message_read_basic(m, type, &basic);
4308 log_error("Failed to get basic: %s", strerror(-r));
4316 case SD_BUS_TYPE_BYTE:
4317 fprintf(f, "%sBYTE: %u\n", prefix, basic.u8);
4320 case SD_BUS_TYPE_BOOLEAN:
4321 fprintf(f, "%sBOOLEAN: %s\n", prefix, yes_no(basic.i));
4324 case SD_BUS_TYPE_INT16:
4325 fprintf(f, "%sINT16: %i\n", prefix, basic.s16);
4328 case SD_BUS_TYPE_UINT16:
4329 fprintf(f, "%sUINT16: %u\n", prefix, basic.u16);
4332 case SD_BUS_TYPE_INT32:
4333 fprintf(f, "%sINT32: %i\n", prefix, basic.s32);
4336 case SD_BUS_TYPE_UINT32:
4337 fprintf(f, "%sUINT32: %u\n", prefix, basic.u32);
4340 case SD_BUS_TYPE_INT64:
4341 fprintf(f, "%sINT64: %lli\n", prefix, (long long) basic.s64);
4344 case SD_BUS_TYPE_UINT64:
4345 fprintf(f, "%sUINT64: %llu\n", prefix, (unsigned long long) basic.u64);
4348 case SD_BUS_TYPE_DOUBLE:
4349 fprintf(f, "%sDOUBLE: %g\n", prefix, basic.d64);
4352 case SD_BUS_TYPE_STRING:
4353 fprintf(f, "%sSTRING: \"%s\"\n", prefix, basic.string);
4356 case SD_BUS_TYPE_OBJECT_PATH:
4357 fprintf(f, "%sOBJECT_PATH: \"%s\"\n", prefix, basic.string);
4360 case SD_BUS_TYPE_SIGNATURE:
4361 fprintf(f, "%sSIGNATURE: \"%s\"\n", prefix, basic.string);
4364 case SD_BUS_TYPE_UNIX_FD:
4365 fprintf(f, "%sUNIX_FD: %i\n", prefix, basic.i);
4369 assert_not_reached("Unknown basic type.");
4373 fprintf(f, "} END_MESSAGE\n");
4377 int bus_message_get_blob(sd_bus_message *m, void **buffer, size_t *sz) {
4381 struct bus_body_part *part;
4387 total = BUS_MESSAGE_SIZE(m);
4393 e = mempcpy(p, m->header, BUS_MESSAGE_BODY_BEGIN(m));
4394 MESSAGE_FOREACH_PART(part, i, m)
4395 e = mempcpy(e, part->data, part->size);
4397 assert(total == (size_t) ((uint8_t*) e - (uint8_t*) p));
4405 int bus_message_read_strv_extend(sd_bus_message *m, char ***l) {
4411 r = sd_bus_message_enter_container(m, 'a', "s");
4418 r = sd_bus_message_read_basic(m, 's', &s);
4424 r = strv_extend(l, s);
4429 r = sd_bus_message_exit_container(m);
4436 _public_ int sd_bus_message_read_strv(sd_bus_message *m, char ***l) {
4440 assert_return(m, -EINVAL);
4441 assert_return(m->sealed, -EPERM);
4442 assert_return(l, -EINVAL);
4444 r = bus_message_read_strv_extend(m, &strv);
4454 const char* bus_message_get_arg(sd_bus_message *m, unsigned i) {
4456 const char *t = NULL;
4461 r = sd_bus_message_rewind(m, true);
4465 for (j = 0; j <= i; j++) {
4468 r = sd_bus_message_peek_type(m, &type, NULL);
4472 if (type != SD_BUS_TYPE_STRING &&
4473 type != SD_BUS_TYPE_OBJECT_PATH &&
4474 type != SD_BUS_TYPE_SIGNATURE)
4477 r = sd_bus_message_read_basic(m, type, &t);
4485 bool bus_header_is_complete(struct bus_header *h, size_t size) {
4491 if (size < sizeof(struct bus_header))
4494 full = sizeof(struct bus_header) +
4495 (h->endian == SD_BUS_NATIVE_ENDIAN ? h->fields_size : bswap_32(h->fields_size));
4497 return size >= full;
4500 int bus_header_message_size(struct bus_header *h, size_t *sum) {
4506 if (h->endian == SD_BUS_NATIVE_ENDIAN) {
4507 fs = h->fields_size;
4509 } else if (h->endian == SD_BUS_REVERSE_ENDIAN) {
4510 fs = bswap_32(h->fields_size);
4511 bs = bswap_32(h->body_size);
4515 *sum = sizeof(struct bus_header) + ALIGN8(fs) + bs;
4519 _public_ int sd_bus_message_get_errno(sd_bus_message *m) {
4520 assert_return(m, -EINVAL);
4522 if (m->header->type != SD_BUS_MESSAGE_METHOD_ERROR)
4525 return sd_bus_error_get_errno(&m->error);
4528 _public_ const char* sd_bus_message_get_signature(sd_bus_message *m, int complete) {
4529 struct bus_container *c;
4531 assert_return(m, NULL);
4533 c = complete ? &m->root_container : message_get_container(m);
4534 return c->signature ?: "";
4537 _public_ int sd_bus_message_copy(sd_bus_message *m, sd_bus_message *source, int all) {
4538 bool done_something = false;
4541 assert_return(m, -EINVAL);
4542 assert_return(source, -EINVAL);
4543 assert_return(!m->sealed, -EPERM);
4544 assert_return(source->sealed, -EPERM);
4547 const char *contents;
4562 r = sd_bus_message_peek_type(source, &type, &contents);
4568 done_something = true;
4570 if (bus_type_is_container(type) > 0) {
4572 r = sd_bus_message_enter_container(source, type, contents);
4576 r = sd_bus_message_open_container(m, type, contents);
4580 r = sd_bus_message_copy(m, source, true);
4584 r = sd_bus_message_close_container(m);
4588 r = sd_bus_message_exit_container(source);
4595 r = sd_bus_message_read_basic(source, type, &basic);
4601 if (type == SD_BUS_TYPE_OBJECT_PATH ||
4602 type == SD_BUS_TYPE_SIGNATURE ||
4603 type == SD_BUS_TYPE_STRING)
4604 r = sd_bus_message_append_basic(m, type, basic.string);
4606 r = sd_bus_message_append_basic(m, type, &basic);
4613 return done_something;
4616 _public_ int sd_bus_message_verify_type(sd_bus_message *m, char type, const char *contents) {
4621 assert_return(m, -EINVAL);
4622 assert_return(m->sealed, -EPERM);
4623 assert_return(!type || bus_type_is_valid(type), -EINVAL);
4624 assert_return(!contents || signature_is_valid(contents, true), -EINVAL);
4625 assert_return(type || contents, -EINVAL);
4626 assert_return(!contents || !type || bus_type_is_container(type), -EINVAL);
4628 r = sd_bus_message_peek_type(m, &t, &c);
4632 if (type != 0 && type != t)
4635 if (contents && !streq_ptr(contents, c))