1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2013 Lennart Poettering
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
29 #include "time-util.h"
30 #include "cgroup-util.h"
33 #include "bus-message.h"
34 #include "bus-internal.h"
36 #include "bus-signature.h"
38 static int message_append_basic(sd_bus_message *m, char type, const void *p, const void **stored);
40 static void *adjust_pointer(const void *p, void *old_base, size_t sz, void *new_base) {
45 if (old_base == new_base)
48 if ((uint8_t*) p < (uint8_t*) old_base)
51 if ((uint8_t*) p >= (uint8_t*) old_base + sz)
54 return (uint8_t*) new_base + ((uint8_t*) p - (uint8_t*) old_base);
57 static void message_free_part(sd_bus_message *m, struct bus_body_part *part) {
61 if (part->memfd >= 0) {
62 /* If we can reuse the memfd, try that. For that it
63 * can't be sealed yet. */
66 bus_kernel_push_memfd(m->bus, part->memfd, part->data, part->mapped);
69 assert_se(munmap(part->data, part->mapped) == 0);
71 close_nointr_nofail(part->memfd);
74 } else if (part->munmap_this)
75 munmap(part->data, part->mapped);
76 else if (part->free_this)
83 static void message_reset_parts(sd_bus_message *m) {
84 struct bus_body_part *part;
89 while (m->n_body_parts > 0) {
90 struct bus_body_part *next = part->next;
91 message_free_part(m, part);
98 m->cached_rindex_part = NULL;
99 m->cached_rindex_part_begin = 0;
102 static void message_reset_containers(sd_bus_message *m) {
107 for (i = 0; i < m->n_containers; i++)
108 free(m->containers[i].signature);
111 m->containers = NULL;
114 m->root_container.index = 0;
117 static void message_free(sd_bus_message *m) {
123 message_reset_parts(m);
128 if (m->release_kdbus) {
131 off = (uint8_t *)m->kdbus - (uint8_t *)m->bus->kdbus_buffer;
132 ioctl(m->bus->input_fd, KDBUS_CMD_MSG_RELEASE, &off);
136 sd_bus_unref(m->bus);
139 close_many(m->fds, m->n_fds);
143 if (m->iovec != m->iovec_fixed)
146 free(m->cmdline_array);
148 message_reset_containers(m);
149 free(m->root_container.signature);
151 free(m->peeked_signature);
159 static void *message_extend_fields(sd_bus_message *m, size_t align, size_t sz) {
161 size_t old_size, new_size, start;
168 old_size = sizeof(struct bus_header) + m->header->fields_size;
169 start = ALIGN_TO(old_size, align);
170 new_size = start + sz;
172 if (old_size == new_size)
173 return (uint8_t*) m->header + old_size;
175 if (new_size > (size_t) ((uint32_t) -1))
178 if (m->free_header) {
179 np = realloc(m->header, ALIGN8(new_size));
183 /* Initially, the header is allocated as part of of
184 * the sd_bus_message itself, let's replace it by
187 np = malloc(ALIGN8(new_size));
191 memcpy(np, m->header, sizeof(struct bus_header));
194 /* Zero out padding */
195 if (start > old_size)
196 memset((uint8_t*) np + old_size, 0, start - old_size);
200 m->header->fields_size = new_size - sizeof(struct bus_header);
202 /* Adjust quick access pointers */
203 m->path = adjust_pointer(m->path, op, old_size, m->header);
204 m->interface = adjust_pointer(m->interface, op, old_size, m->header);
205 m->member = adjust_pointer(m->member, op, old_size, m->header);
206 m->destination = adjust_pointer(m->destination, op, old_size, m->header);
207 m->sender = adjust_pointer(m->sender, op, old_size, m->header);
208 m->error.name = adjust_pointer(m->error.name, op, old_size, m->header);
210 m->free_header = true;
212 return (uint8_t*) np + start;
219 static int message_append_field_string(
232 if (l > (size_t) (uint32_t) -1)
235 /* field id byte + signature length + signature 's' + NUL + string length + string + NUL */
236 p = message_extend_fields(m, 8, 4 + 4 + l + 1);
245 ((uint32_t*) p)[1] = l;
246 memcpy(p + 8, s, l + 1);
249 *ret = (char*) p + 8;
254 static int message_append_field_signature(
269 /* field id byte + signature length + signature 'g' + NUL + string length + string + NUL */
270 p = message_extend_fields(m, 8, 4 + 1 + l + 1);
276 p[2] = SD_BUS_TYPE_SIGNATURE;
279 memcpy(p + 5, s, l + 1);
282 *ret = (const char*) p + 5;
287 static int message_append_field_uint32(sd_bus_message *m, uint8_t h, uint32_t x) {
292 /* field id byte + signature length + signature 'u' + NUL + value */
293 p = message_extend_fields(m, 8, 4 + 4);
299 p[2] = SD_BUS_TYPE_UINT32;
302 ((uint32_t*) p)[1] = x;
307 int bus_message_from_header(
312 const struct ucred *ucred,
315 sd_bus_message **ret) {
318 struct bus_header *h;
321 assert(buffer || length <= 0);
322 assert(fds || n_fds <= 0);
325 if (length < sizeof(struct bus_header))
335 if (h->type == _SD_BUS_MESSAGE_TYPE_INVALID)
338 if (h->endian != SD_BUS_LITTLE_ENDIAN &&
339 h->endian != SD_BUS_BIG_ENDIAN)
342 a = ALIGN(sizeof(sd_bus_message)) + ALIGN(extra);
345 label_sz = strlen(label);
363 m->uid_valid = m->gid_valid = true;
367 m->label = (char*) m + ALIGN(sizeof(sd_bus_message)) + ALIGN(extra);
368 memcpy(m->label, label, label_sz + 1);
375 int bus_message_from_malloc(
380 const struct ucred *ucred,
382 sd_bus_message **ret) {
387 r = bus_message_from_header(buffer, length, fds, n_fds, ucred, label, 0, &m);
391 if (length != BUS_MESSAGE_SIZE(m)) {
397 m->body.data = (uint8_t*) buffer + sizeof(struct bus_header) + ALIGN8(BUS_MESSAGE_FIELDS_SIZE(m));
398 m->body.size = length - sizeof(struct bus_header) - ALIGN8(BUS_MESSAGE_FIELDS_SIZE(m));
399 m->body.sealed = true;
403 m->iovec = m->iovec_fixed;
404 m->iovec[0].iov_base = buffer;
405 m->iovec[0].iov_len = length;
407 r = bus_message_parse_fields(m);
411 /* We take possession of the memory and fds now */
412 m->free_header = true;
423 static sd_bus_message *message_new(sd_bus *bus, uint8_t type) {
426 m = malloc0(ALIGN(sizeof(sd_bus_message)) + sizeof(struct bus_header));
431 m->header = (struct bus_header*) ((uint8_t*) m + ALIGN(sizeof(struct sd_bus_message)));
432 m->header->endian = SD_BUS_NATIVE_ENDIAN;
433 m->header->type = type;
434 m->header->version = bus ? bus->message_version : 1;
435 m->allow_fds = !bus || bus->can_fds || (bus->state != BUS_HELLO && bus->state != BUS_RUNNING);
438 m->bus = sd_bus_ref(bus);
443 _public_ int sd_bus_message_new_signal(
446 const char *interface,
448 sd_bus_message **m) {
453 assert_return(!bus || bus->state != BUS_UNSET, -ENOTCONN);
454 assert_return(object_path_is_valid(path), -EINVAL);
455 assert_return(interface_name_is_valid(interface), -EINVAL);
456 assert_return(member_name_is_valid(member), -EINVAL);
457 assert_return(m, -EINVAL);
459 t = message_new(bus, SD_BUS_MESSAGE_SIGNAL);
463 t->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
465 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_PATH, SD_BUS_TYPE_OBJECT_PATH, path, &t->path);
468 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_INTERFACE, SD_BUS_TYPE_STRING, interface, &t->interface);
471 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_MEMBER, SD_BUS_TYPE_STRING, member, &t->member);
479 sd_bus_message_unref(t);
483 _public_ int sd_bus_message_new_method_call(
485 const char *destination,
487 const char *interface,
489 sd_bus_message **m) {
494 assert_return(!bus || bus->state != BUS_UNSET, -ENOTCONN);
495 assert_return(!destination || service_name_is_valid(destination), -EINVAL);
496 assert_return(object_path_is_valid(path), -EINVAL);
497 assert_return(!interface || interface_name_is_valid(interface), -EINVAL);
498 assert_return(member_name_is_valid(member), -EINVAL);
499 assert_return(m, -EINVAL);
501 t = message_new(bus, SD_BUS_MESSAGE_METHOD_CALL);
505 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_PATH, SD_BUS_TYPE_OBJECT_PATH, path, &t->path);
508 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_MEMBER, SD_BUS_TYPE_STRING, member, &t->member);
513 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_INTERFACE, SD_BUS_TYPE_STRING, interface, &t->interface);
519 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &t->destination);
532 static int message_new_reply(
534 sd_bus_message *call,
536 sd_bus_message **m) {
541 assert_return(!bus || bus->state != BUS_UNSET, -ENOTCONN);
542 assert_return(call, -EINVAL);
543 assert_return(call->sealed, -EPERM);
544 assert_return(call->header->type == SD_BUS_MESSAGE_METHOD_CALL, -EINVAL);
545 assert_return(m, -EINVAL);
547 t = message_new(bus, type);
551 t->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
552 t->reply_serial = BUS_MESSAGE_SERIAL(call);
554 r = message_append_field_uint32(t, SD_BUS_MESSAGE_HEADER_REPLY_SERIAL, t->reply_serial);
559 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, call->sender, &t->destination);
564 t->dont_send = !!(call->header->flags & SD_BUS_MESSAGE_NO_REPLY_EXPECTED);
574 _public_ int sd_bus_message_new_method_return(
576 sd_bus_message *call,
577 sd_bus_message **m) {
579 return message_new_reply(bus, call, SD_BUS_MESSAGE_METHOD_RETURN, m);
582 _public_ int sd_bus_message_new_method_error(
584 sd_bus_message *call,
585 const sd_bus_error *e,
586 sd_bus_message **m) {
591 assert_return(sd_bus_error_is_set(e), -EINVAL);
592 assert_return(m, -EINVAL);
594 r = message_new_reply(bus, call, SD_BUS_MESSAGE_METHOD_ERROR, &t);
598 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_ERROR_NAME, SD_BUS_TYPE_STRING, e->name, &t->error.name);
603 r = message_append_basic(t, SD_BUS_TYPE_STRING, e->message, (const void**) &t->error.message);
616 _public_ int sd_bus_message_new_method_errorf(
618 sd_bus_message *call,
624 _cleanup_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
628 assert_return(name, -EINVAL);
629 assert_return(m, -EINVAL);
631 va_start(ap, format);
632 r = bus_error_setfv(&error, name, format, ap);
638 return sd_bus_message_new_method_error(bus, call, &error, m);
641 _public_ int sd_bus_message_new_method_errno(
643 sd_bus_message *call,
645 const sd_bus_error *p,
646 sd_bus_message **m) {
648 _cleanup_free_ sd_bus_error berror = SD_BUS_ERROR_NULL;
650 if (sd_bus_error_is_set(p))
651 return sd_bus_message_new_method_error(bus, call, p, m);
653 sd_bus_error_set_errno(&berror, error);
655 return sd_bus_message_new_method_error(bus, call, &berror, m);
658 _public_ int sd_bus_message_new_method_errnof(
660 sd_bus_message *call,
666 _cleanup_free_ sd_bus_error berror = SD_BUS_ERROR_NULL;
670 va_start(ap, format);
671 r = bus_error_set_errnofv(&berror, error, format, ap);
677 return sd_bus_message_new_method_error(bus, call, &berror, m);
680 int bus_message_new_synthetic_error(
683 const sd_bus_error *e,
684 sd_bus_message **m) {
689 assert(sd_bus_error_is_set(e));
692 t = message_new(bus, SD_BUS_MESSAGE_METHOD_ERROR);
696 t->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
697 t->reply_serial = serial;
699 r = message_append_field_uint32(t, SD_BUS_MESSAGE_HEADER_REPLY_SERIAL, t->reply_serial);
703 if (bus && bus->unique_name) {
704 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, bus->unique_name, &t->destination);
709 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_ERROR_NAME, SD_BUS_TYPE_STRING, e->name, &t->error.name);
714 r = message_append_basic(t, SD_BUS_TYPE_STRING, e->message, (const void**) &t->error.message);
727 _public_ sd_bus_message* sd_bus_message_ref(sd_bus_message *m) {
728 assert_return(m, NULL);
730 assert(m->n_ref > 0);
736 _public_ sd_bus_message* sd_bus_message_unref(sd_bus_message *m) {
737 assert_return(m, NULL);
739 assert(m->n_ref > 0);
748 _public_ int sd_bus_message_get_type(sd_bus_message *m, uint8_t *type) {
749 assert_return(m, -EINVAL);
750 assert_return(type, -EINVAL);
752 *type = m->header->type;
756 _public_ int sd_bus_message_get_serial(sd_bus_message *m, uint64_t *serial) {
757 assert_return(m, -EINVAL);
758 assert_return(serial, -EINVAL);
759 assert_return(m->header->serial != 0, -ENOENT);
761 *serial = BUS_MESSAGE_SERIAL(m);
765 _public_ int sd_bus_message_get_reply_serial(sd_bus_message *m, uint64_t *serial) {
766 assert_return(m, -EINVAL);
767 assert_return(serial, -EINVAL);
768 assert_return(m->reply_serial != 0, -ENOENT);
770 *serial = m->reply_serial;
774 _public_ int sd_bus_message_get_no_reply(sd_bus_message *m) {
775 assert_return(m, -EINVAL);
777 return m->header->type == SD_BUS_MESSAGE_METHOD_CALL ? !!(m->header->flags & SD_BUS_MESSAGE_NO_REPLY_EXPECTED) : 0;
780 _public_ const char *sd_bus_message_get_path(sd_bus_message *m) {
781 assert_return(m, NULL);
786 _public_ const char *sd_bus_message_get_interface(sd_bus_message *m) {
787 assert_return(m, NULL);
792 _public_ const char *sd_bus_message_get_member(sd_bus_message *m) {
793 assert_return(m, NULL);
798 _public_ const char *sd_bus_message_get_destination(sd_bus_message *m) {
799 assert_return(m, NULL);
801 return m->destination;
804 _public_ const char *sd_bus_message_get_sender(sd_bus_message *m) {
805 assert_return(m, NULL);
810 _public_ const sd_bus_error *sd_bus_message_get_error(sd_bus_message *m) {
811 assert_return(m, NULL);
812 assert_return(sd_bus_error_is_set(&m->error), NULL);
817 _public_ int sd_bus_message_get_uid(sd_bus_message *m, uid_t *uid) {
818 assert_return(m, -EINVAL);
819 assert_return(uid, -EINVAL);
820 assert_return(m->uid_valid, -ESRCH);
826 _public_ int sd_bus_message_get_gid(sd_bus_message *m, gid_t *gid) {
827 assert_return(m, -EINVAL);
828 assert_return(gid, -EINVAL);
829 assert_return(m->gid_valid, -ESRCH);
835 _public_ int sd_bus_message_get_pid(sd_bus_message *m, pid_t *pid) {
836 assert_return(m, -EINVAL);
837 assert_return(pid, -EINVAL);
838 assert_return(m->pid > 0, -ESRCH);
844 _public_ int sd_bus_message_get_tid(sd_bus_message *m, pid_t *tid) {
845 assert_return(m, -EINVAL);
846 assert_return(tid, -EINVAL);
847 assert_return(m->tid > 0, -ESRCH);
853 _public_ int sd_bus_message_get_pid_starttime(sd_bus_message *m, uint64_t *usec) {
854 assert_return(m, -EINVAL);
855 assert_return(usec, -EINVAL);
856 assert_return(m->pid_starttime > 0, -ESRCH);
858 *usec = m->pid_starttime;
862 _public_ int sd_bus_message_get_selinux_context(sd_bus_message *m, const char **ret) {
863 assert_return(m, -EINVAL);
864 assert_return(m->label, -ESRCH);
870 _public_ int sd_bus_message_get_monotonic_timestamp(sd_bus_message *m, uint64_t *usec) {
871 assert_return(m, -EINVAL);
872 assert_return(usec, -EINVAL);
873 assert_return(m->monotonic > 0, -ESRCH);
875 *usec = m->monotonic;
879 _public_ int sd_bus_message_get_realtime_timestamp(sd_bus_message *m, uint64_t *usec) {
880 assert_return(m, -EINVAL);
881 assert_return(usec, -EINVAL);
882 assert_return(m->realtime > 0, -ESRCH);
888 _public_ int sd_bus_message_get_comm(sd_bus_message *m, const char **ret) {
889 assert_return(m, -EINVAL);
890 assert_return(ret, -EINVAL);
891 assert_return(m->comm, -ESRCH);
897 _public_ int sd_bus_message_get_tid_comm(sd_bus_message *m, const char **ret) {
898 assert_return(m, -EINVAL);
899 assert_return(ret, -EINVAL);
900 assert_return(m->tid_comm, -ESRCH);
906 _public_ int sd_bus_message_get_exe(sd_bus_message *m, const char **ret) {
907 assert_return(m, -EINVAL);
908 assert_return(ret, -EINVAL);
909 assert_return(m->exe, -ESRCH);
915 _public_ int sd_bus_message_get_cgroup(sd_bus_message *m, const char **ret) {
916 assert_return(m, -EINVAL);
917 assert_return(ret, -EINVAL);
918 assert_return(m->cgroup, -ESRCH);
924 _public_ int sd_bus_message_get_unit(sd_bus_message *m, const char **ret) {
927 assert_return(m, -EINVAL);
928 assert_return(ret, -EINVAL);
929 assert_return(m->cgroup, -ESRCH);
932 r = cg_path_get_unit(m->cgroup, &m->unit);
941 _public_ int sd_bus_message_get_user_unit(sd_bus_message *m, const char **ret) {
944 assert_return(m, -EINVAL);
945 assert_return(ret, -EINVAL);
946 assert_return(m->cgroup, -ESRCH);
949 r = cg_path_get_user_unit(m->cgroup, &m->user_unit);
958 _public_ int sd_bus_message_get_session(sd_bus_message *m, const char **ret) {
961 assert_return(m, -EINVAL);
962 assert_return(ret, -EINVAL);
963 assert_return(m->cgroup, -ESRCH);
966 r = cg_path_get_session(m->cgroup, &m->session);
975 _public_ int sd_bus_message_get_owner_uid(sd_bus_message *m, uid_t *uid) {
976 assert_return(m, -EINVAL);
977 assert_return(uid, -EINVAL);
978 assert_return(m->cgroup, -ESRCH);
980 return cg_path_get_owner_uid(m->cgroup, uid);
983 _public_ int sd_bus_message_get_cmdline(sd_bus_message *m, char ***cmdline) {
988 assert_return(m, -EINVAL);
989 assert_return(m->cmdline, -ESRCH);
991 for (p = m->cmdline, n = 0; p < m->cmdline + m->cmdline_length; p++)
995 m->cmdline_array = new(char*, n + 1);
996 if (!m->cmdline_array)
999 for (p = m->cmdline, i = 0, first = true; p < m->cmdline + m->cmdline_length; p++) {
1001 m->cmdline_array[i++] = (char*) p;
1006 m->cmdline_array[i] = NULL;
1007 *cmdline = m->cmdline_array;
1012 _public_ int sd_bus_message_get_audit_sessionid(sd_bus_message *m, uint32_t *sessionid) {
1013 assert_return(m, -EINVAL);
1014 assert_return(sessionid, -EINVAL);
1015 assert_return(m->audit, -ESRCH);
1017 *sessionid = m->audit->sessionid;
1021 _public_ int sd_bus_message_get_audit_loginuid(sd_bus_message *m, uid_t *uid) {
1022 assert_return(m, -EINVAL);
1023 assert_return(uid, -EINVAL);
1024 assert_return(m->audit, -ESRCH);
1026 *uid = m->audit->loginuid;
1030 _public_ int sd_bus_message_has_effective_cap(sd_bus_message *m, int capability) {
1033 assert_return(m, -EINVAL);
1034 assert_return(capability < 0, -EINVAL);
1035 assert_return(!m->capability, -ESRCH);
1037 sz = m->capability_size / 4;
1038 if ((unsigned) capability >= sz*8)
1041 return !!(m->capability[2 * sz + (capability / 8)] & (1 << (capability % 8)));
1044 _public_ int sd_bus_message_is_signal(sd_bus_message *m,
1045 const char *interface,
1046 const char *member) {
1047 assert_return(m, -EINVAL);
1049 if (m->header->type != SD_BUS_MESSAGE_SIGNAL)
1052 if (interface && (!m->interface || !streq(m->interface, interface)))
1055 if (member && (!m->member || !streq(m->member, member)))
1061 _public_ int sd_bus_message_is_method_call(sd_bus_message *m,
1062 const char *interface,
1063 const char *member) {
1064 assert_return(m, -EINVAL);
1066 if (m->header->type != SD_BUS_MESSAGE_METHOD_CALL)
1069 if (interface && (!m->interface || !streq(m->interface, interface)))
1072 if (member && (!m->member || !streq(m->member, member)))
1078 _public_ int sd_bus_message_is_method_error(sd_bus_message *m, const char *name) {
1079 assert_return(m, -EINVAL);
1081 if (m->header->type != SD_BUS_MESSAGE_METHOD_ERROR)
1084 if (name && (!m->error.name || !streq(m->error.name, name)))
1090 _public_ int sd_bus_message_set_no_reply(sd_bus_message *m, int b) {
1091 assert_return(m, -EINVAL);
1092 assert_return(!m->sealed, -EPERM);
1093 assert_return(m->header->type == SD_BUS_MESSAGE_METHOD_CALL, -EPERM);
1096 m->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
1098 m->header->flags &= ~SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
1103 static struct bus_container *message_get_container(sd_bus_message *m) {
1106 if (m->n_containers == 0)
1107 return &m->root_container;
1109 assert(m->containers);
1110 return m->containers + m->n_containers - 1;
1113 struct bus_body_part *message_append_part(sd_bus_message *m) {
1114 struct bus_body_part *part;
1121 if (m->n_body_parts <= 0) {
1125 assert(m->body_end);
1127 part = new0(struct bus_body_part, 1);
1133 m->body_end->next = part;
1143 static void part_zero(struct bus_body_part *part, size_t sz) {
1148 /* All other fields can be left in their defaults */
1149 assert(!part->data);
1150 assert(part->memfd < 0);
1153 part->is_zero = true;
1154 part->sealed = true;
1157 static int part_make_space(
1158 struct sd_bus_message *m,
1159 struct bus_body_part *part,
1168 assert(!part->sealed);
1173 if (!part->data && part->memfd < 0)
1174 part->memfd = bus_kernel_pop_memfd(m->bus, &part->data, &part->mapped);
1176 if (part->memfd >= 0) {
1179 r = ioctl(part->memfd, KDBUS_CMD_MEMFD_SIZE_SET, &u);
1185 if (!part->data || sz > part->mapped) {
1186 size_t psz = PAGE_ALIGN(sz > 0 ? sz : 1);
1188 if (part->mapped <= 0)
1189 n = mmap(NULL, psz, PROT_READ|PROT_WRITE, MAP_SHARED, part->memfd, 0);
1191 n = mremap(part->data, part->mapped, psz, MREMAP_MAYMOVE);
1193 if (n == MAP_FAILED) {
1202 part->munmap_this = true;
1204 n = realloc(part->data, MAX(sz, 1u));
1211 part->free_this = true;
1215 *q = part->data ? (uint8_t*) part->data + part->size : NULL;
1221 static void message_extend_containers(sd_bus_message *m, size_t expand) {
1222 struct bus_container *c;
1229 /* Update counters */
1230 for (c = m->containers; c < m->containers + m->n_containers; c++)
1232 *c->array_size += expand;
1235 static void *message_extend_body(sd_bus_message *m, size_t align, size_t sz) {
1236 struct bus_body_part *part = NULL;
1237 size_t start_body, end_body, padding, start_part, end_part, added;
1249 start_body = ALIGN_TO((size_t) m->header->body_size, align);
1250 end_body = start_body + sz;
1252 padding = start_body - m->header->body_size;
1253 added = padding + sz;
1255 /* Check for 32bit overflows */
1256 if (end_body > (size_t) ((uint32_t) -1)) {
1262 m->n_body_parts <= 0 ||
1263 m->body_end->sealed ||
1264 padding != ALIGN_TO(m->body_end->size, align) - m->body_end->size;
1268 part = message_append_part(m);
1272 part_zero(part, padding);
1275 part = message_append_part(m);
1279 r = part_make_space(m, part, sz, &p);
1283 struct bus_container *c;
1291 start_part = ALIGN_TO(part->size, align);
1292 end_part = start_part + sz;
1294 r = part_make_space(m, part, end_part, &p);
1299 memset(p, 0, padding);
1300 p = (uint8_t*) p + padding;
1303 /* Readjust pointers */
1304 for (c = m->containers; c < m->containers + m->n_containers; c++)
1305 c->array_size = adjust_pointer(c->array_size, op, os, part->data);
1307 m->error.message = (const char*) adjust_pointer(m->error.message, op, os, part->data);
1310 m->header->body_size = end_body;
1311 message_extend_containers(m, added);
1316 int message_append_basic(sd_bus_message *m, char type, const void *p, const void **stored) {
1317 struct bus_container *c;
1325 assert_return(m, -EINVAL);
1326 assert_return(!m->sealed, -EPERM);
1327 assert_return(bus_type_is_basic(type), -EINVAL);
1328 assert_return(!m->poisoned, -ESTALE);
1330 c = message_get_container(m);
1332 if (c->signature && c->signature[c->index]) {
1333 /* Container signature is already set */
1335 if (c->signature[c->index] != type)
1340 /* Maybe we can append to the signature? But only if this is the top-level container*/
1341 if (c->enclosing != 0)
1344 e = strextend(&c->signature, CHAR_TO_STR(type), NULL);
1353 case SD_BUS_TYPE_STRING:
1354 /* To make things easy we'll serialize a NULL string
1355 * into the empty string */
1358 /* Fall through... */
1359 case SD_BUS_TYPE_OBJECT_PATH:
1367 sz = 4 + strlen(p) + 1;
1370 case SD_BUS_TYPE_SIGNATURE:
1378 sz = 1 + strlen(p) + 1;
1381 case SD_BUS_TYPE_BOOLEAN:
1390 assert_cc(sizeof(int) == sizeof(uint32_t));
1396 case SD_BUS_TYPE_UNIX_FD: {
1404 if (!m->allow_fds) {
1417 fd = fcntl(z, F_DUPFD_CLOEXEC, 3);
1423 f = realloc(m->fds, sizeof(int) * (m->n_fds + 1));
1443 align = bus_type_get_alignment(type);
1444 sz = bus_type_get_size(type);
1451 a = message_extend_body(m, align, sz);
1457 if (type == SD_BUS_TYPE_STRING || type == SD_BUS_TYPE_OBJECT_PATH) {
1458 *(uint32_t*) a = sz - 5;
1459 memcpy((uint8_t*) a + 4, p, sz - 4);
1462 *stored = (const uint8_t*) a + 4;
1464 } else if (type == SD_BUS_TYPE_SIGNATURE) {
1465 *(uint8_t*) a = sz - 1;
1466 memcpy((uint8_t*) a + 1, p, sz - 1);
1469 *stored = (const uint8_t*) a + 1;
1470 } else if (type == SD_BUS_TYPE_UNIX_FD) {
1471 *(uint32_t*) a = fdi;
1485 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1492 close_nointr_nofail(fd);
1497 _public_ int sd_bus_message_append_basic(sd_bus_message *m, char type, const void *p) {
1498 return message_append_basic(m, type, p, NULL);
1501 _public_ int sd_bus_message_append_string_space(sd_bus_message *m, size_t size, char **s) {
1502 struct bus_container *c;
1505 assert_return(m, -EINVAL);
1506 assert_return(s, -EINVAL);
1507 assert_return(!m->sealed, -EPERM);
1508 assert_return(!m->poisoned, -ESTALE);
1510 c = message_get_container(m);
1512 if (c->signature && c->signature[c->index]) {
1513 /* Container signature is already set */
1515 if (c->signature[c->index] != SD_BUS_TYPE_STRING)
1520 /* Maybe we can append to the signature? But only if this is the top-level container*/
1521 if (c->enclosing != 0)
1524 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRING), NULL);
1531 a = message_extend_body(m, 4, 4 + size + 1);
1535 *(uint32_t*) a = size;
1540 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1546 static int bus_message_open_array(
1548 struct bus_container *c,
1549 const char *contents,
1550 uint32_t **array_size) {
1556 struct bus_body_part *o;
1563 if (!signature_is_single(contents, true))
1566 alignment = bus_type_get_alignment(contents[0]);
1570 if (c->signature && c->signature[c->index]) {
1572 /* Verify the existing signature */
1574 if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
1577 if (!startswith(c->signature + c->index + 1, contents))
1580 nindex = c->index + 1 + strlen(contents);
1584 if (c->enclosing != 0)
1587 /* Extend the existing signature */
1589 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_ARRAY), contents, NULL);
1595 nindex = e - c->signature;
1598 a = message_extend_body(m, 4, 4);
1603 op = m->body_end->data;
1604 os = m->body_end->size;
1606 /* Add alignment between size and first element */
1607 if (!message_extend_body(m, alignment, 0))
1610 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1613 /* location of array size might have changed so let's readjust a */
1614 if (o == m->body_end)
1615 a = adjust_pointer(a, op, os, m->body_end->data);
1622 static int bus_message_open_variant(
1624 struct bus_container *c,
1625 const char *contents) {
1634 if (!signature_is_single(contents, false))
1637 if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
1640 if (c->signature && c->signature[c->index]) {
1642 if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
1648 if (c->enclosing != 0)
1651 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_VARIANT), NULL);
1658 l = strlen(contents);
1659 a = message_extend_body(m, 1, 1 + l + 1);
1664 memcpy((uint8_t*) a + 1, contents, l + 1);
1666 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1672 static int bus_message_open_struct(
1674 struct bus_container *c,
1675 const char *contents) {
1683 if (!signature_is_valid(contents, false))
1686 if (c->signature && c->signature[c->index]) {
1689 l = strlen(contents);
1691 if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
1692 !startswith(c->signature + c->index + 1, contents) ||
1693 c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
1696 nindex = c->index + 1 + l + 1;
1700 if (c->enclosing != 0)
1703 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_BEGIN), contents, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_END), NULL);
1709 nindex = e - c->signature;
1712 /* Align contents to 8 byte boundary */
1713 if (!message_extend_body(m, 8, 0))
1716 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1722 static int bus_message_open_dict_entry(
1724 struct bus_container *c,
1725 const char *contents) {
1733 if (!signature_is_pair(contents))
1736 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1739 if (c->signature && c->signature[c->index]) {
1742 l = strlen(contents);
1744 if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
1745 !startswith(c->signature + c->index + 1, contents) ||
1746 c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
1749 nindex = c->index + 1 + l + 1;
1753 /* Align contents to 8 byte boundary */
1754 if (!message_extend_body(m, 8, 0))
1757 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1763 _public_ int sd_bus_message_open_container(
1766 const char *contents) {
1768 struct bus_container *c, *w;
1769 uint32_t *array_size = NULL;
1774 assert_return(m, -EINVAL);
1775 assert_return(!m->sealed, -EPERM);
1776 assert_return(contents, -EINVAL);
1777 assert_return(!m->poisoned, -ESTALE);
1779 /* Make sure we have space for one more container */
1780 w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
1788 c = message_get_container(m);
1790 signature = strdup(contents);
1796 /* Save old index in the parent container, in case we have to
1797 * abort this container */
1798 c->saved_index = c->index;
1799 before = m->header->body_size;
1801 if (type == SD_BUS_TYPE_ARRAY)
1802 r = bus_message_open_array(m, c, contents, &array_size);
1803 else if (type == SD_BUS_TYPE_VARIANT)
1804 r = bus_message_open_variant(m, c, contents);
1805 else if (type == SD_BUS_TYPE_STRUCT)
1806 r = bus_message_open_struct(m, c, contents);
1807 else if (type == SD_BUS_TYPE_DICT_ENTRY)
1808 r = bus_message_open_dict_entry(m, c, contents);
1817 /* OK, let's fill it in */
1818 w += m->n_containers++;
1819 w->enclosing = type;
1820 w->signature = signature;
1822 w->array_size = array_size;
1824 w->begin = m->rindex;
1829 _public_ int sd_bus_message_close_container(sd_bus_message *m) {
1830 struct bus_container *c;
1832 assert_return(m, -EINVAL);
1833 assert_return(!m->sealed, -EPERM);
1834 assert_return(m->n_containers > 0, -EINVAL);
1835 assert_return(!m->poisoned, -ESTALE);
1837 c = message_get_container(m);
1838 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1839 if (c->signature && c->signature[c->index] != 0)
1854 static int type_stack_push(TypeStack *stack, unsigned max, unsigned *i, const char *types, unsigned n_struct, unsigned n_array) {
1861 stack[*i].types = types;
1862 stack[*i].n_struct = n_struct;
1863 stack[*i].n_array = n_array;
1869 static int type_stack_pop(TypeStack *stack, unsigned max, unsigned *i, const char **types, unsigned *n_struct, unsigned *n_array) {
1880 *types = stack[*i].types;
1881 *n_struct = stack[*i].n_struct;
1882 *n_array = stack[*i].n_array;
1887 int bus_message_append_ap(
1892 unsigned n_array, n_struct;
1893 TypeStack stack[BUS_CONTAINER_DEPTH];
1894 unsigned stack_ptr = 0;
1902 n_array = (unsigned) -1;
1903 n_struct = strlen(types);
1908 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
1909 r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
1915 r = sd_bus_message_close_container(m);
1923 if (n_array != (unsigned) -1)
1932 case SD_BUS_TYPE_BYTE: {
1935 x = (uint8_t) va_arg(ap, int);
1936 r = sd_bus_message_append_basic(m, *t, &x);
1940 case SD_BUS_TYPE_BOOLEAN:
1941 case SD_BUS_TYPE_INT32:
1942 case SD_BUS_TYPE_UINT32:
1943 case SD_BUS_TYPE_UNIX_FD: {
1946 /* We assume a boolean is the same as int32_t */
1947 assert_cc(sizeof(int32_t) == sizeof(int));
1949 x = va_arg(ap, uint32_t);
1950 r = sd_bus_message_append_basic(m, *t, &x);
1954 case SD_BUS_TYPE_INT16:
1955 case SD_BUS_TYPE_UINT16: {
1958 x = (uint16_t) va_arg(ap, int);
1959 r = sd_bus_message_append_basic(m, *t, &x);
1963 case SD_BUS_TYPE_INT64:
1964 case SD_BUS_TYPE_UINT64:
1965 case SD_BUS_TYPE_DOUBLE: {
1968 x = va_arg(ap, uint64_t);
1969 r = sd_bus_message_append_basic(m, *t, &x);
1973 case SD_BUS_TYPE_STRING:
1974 case SD_BUS_TYPE_OBJECT_PATH:
1975 case SD_BUS_TYPE_SIGNATURE: {
1978 x = va_arg(ap, const char*);
1979 r = sd_bus_message_append_basic(m, *t, x);
1983 case SD_BUS_TYPE_ARRAY: {
1986 r = signature_element_length(t + 1, &k);
1992 memcpy(s, t + 1, k);
1995 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, s);
2000 if (n_array == (unsigned) -1) {
2005 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2011 n_array = va_arg(ap, unsigned);
2016 case SD_BUS_TYPE_VARIANT: {
2019 s = va_arg(ap, const char*);
2023 r = sd_bus_message_open_container(m, SD_BUS_TYPE_VARIANT, s);
2027 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2032 n_struct = strlen(s);
2033 n_array = (unsigned) -1;
2038 case SD_BUS_TYPE_STRUCT_BEGIN:
2039 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
2042 r = signature_element_length(t, &k);
2049 memcpy(s, t + 1, k - 2);
2052 r = sd_bus_message_open_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
2057 if (n_array == (unsigned) -1) {
2062 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2068 n_array = (unsigned) -1;
2084 _public_ int sd_bus_message_append(sd_bus_message *m, const char *types, ...) {
2088 assert_return(m, -EINVAL);
2089 assert_return(types, -EINVAL);
2090 assert_return(!m->sealed, -EPERM);
2091 assert_return(!m->poisoned, -ESTALE);
2093 va_start(ap, types);
2094 r = bus_message_append_ap(m, types, ap);
2100 _public_ int sd_bus_message_append_array_space(sd_bus_message *m,
2108 assert_return(m, -EINVAL);
2109 assert_return(!m->sealed, -EPERM);
2110 assert_return(bus_type_is_trivial(type), -EINVAL);
2111 assert_return(ptr || size == 0, -EINVAL);
2112 assert_return(!m->poisoned, -ESTALE);
2114 align = bus_type_get_alignment(type);
2115 sz = bus_type_get_size(type);
2117 assert_se(align > 0);
2123 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
2127 a = message_extend_body(m, align, size);
2131 r = sd_bus_message_close_container(m);
2139 _public_ int sd_bus_message_append_array(sd_bus_message *m,
2146 assert_return(m, -EINVAL);
2147 assert_return(!m->sealed, -EPERM);
2148 assert_return(bus_type_is_trivial(type), -EINVAL);
2149 assert_return(ptr || size == 0, -EINVAL);
2150 assert_return(!m->poisoned, -ESTALE);
2152 r = sd_bus_message_append_array_space(m, type, size, &p);
2157 memcpy(p, ptr, size);
2162 _public_ int sd_bus_message_append_array_memfd(sd_bus_message *m,
2165 _cleanup_close_ int copy_fd = -1;
2166 struct bus_body_part *part;
2178 if (!bus_type_is_trivial(type))
2183 r = sd_memfd_set_sealed(memfd, true);
2187 copy_fd = sd_memfd_dup_fd(memfd);
2191 r = sd_memfd_get_size(memfd, &size);
2195 align = bus_type_get_alignment(type);
2196 sz = bus_type_get_size(type);
2198 assert_se(align > 0);
2204 if (size > (uint64_t) (uint32_t) -1)
2207 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
2211 a = message_extend_body(m, align, 0);
2215 part = message_append_part(m);
2219 part->memfd = copy_fd;
2220 part->sealed = true;
2224 message_extend_containers(m, size);
2225 m->header->body_size += size;
2227 return sd_bus_message_close_container(m);
2230 _public_ int sd_bus_message_append_string_memfd(sd_bus_message *m, sd_memfd *memfd) {
2231 _cleanup_close_ int copy_fd = -1;
2232 struct bus_body_part *part;
2233 struct bus_container *c;
2238 assert_return(m, -EINVAL);
2239 assert_return(memfd, -EINVAL);
2240 assert_return(!m->sealed, -EPERM);
2241 assert_return(!m->poisoned, -ESTALE);
2243 r = sd_memfd_set_sealed(memfd, true);
2247 copy_fd = sd_memfd_dup_fd(memfd);
2251 r = sd_memfd_get_size(memfd, &size);
2255 /* We require this to be NUL terminated */
2259 if (size > (uint64_t) (uint32_t) -1)
2262 c = message_get_container(m);
2263 if (c->signature && c->signature[c->index]) {
2264 /* Container signature is already set */
2266 if (c->signature[c->index] != SD_BUS_TYPE_STRING)
2271 /* Maybe we can append to the signature? But only if this is the top-level container*/
2272 if (c->enclosing != 0)
2275 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRING), NULL);
2282 a = message_extend_body(m, 4, 4);
2286 *(uint32_t*) a = size - 1;
2288 part = message_append_part(m);
2292 part->memfd = copy_fd;
2293 part->sealed = true;
2297 message_extend_containers(m, size);
2298 m->header->body_size += size;
2300 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2306 _public_ int sd_bus_message_append_strv(sd_bus_message *m, char **l) {
2310 assert_return(m, -EINVAL);
2311 assert_return(!m->sealed, -EPERM);
2312 assert_return(!m->poisoned, -ESTALE);
2314 r = sd_bus_message_open_container(m, 'a', "s");
2318 STRV_FOREACH(i, l) {
2319 r = sd_bus_message_append_basic(m, 's', *i);
2324 return sd_bus_message_close_container(m);
2327 int bus_body_part_map(struct bus_body_part *part) {
2336 if (part->size <= 0)
2339 /* For smaller zero parts (as used for padding) we don't need to map anything... */
2340 if (part->memfd < 0 && part->is_zero && part->size < 8) {
2341 static const uint8_t zeroes[7] = { };
2342 part->data = (void*) zeroes;
2346 psz = PAGE_ALIGN(part->size);
2348 if (part->memfd >= 0)
2349 p = mmap(NULL, psz, PROT_READ, MAP_SHARED, part->memfd, 0);
2350 else if (part->is_zero)
2351 p = mmap(NULL, psz, PROT_READ, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
2355 if (p == MAP_FAILED)
2360 part->munmap_this = true;
2365 void bus_body_part_unmap(struct bus_body_part *part) {
2369 if (part->memfd < 0)
2375 if (!part->munmap_this)
2378 assert_se(munmap(part->data, part->mapped) == 0);
2382 part->munmap_this = false;
2387 static int buffer_peek(const void *p, uint32_t sz, size_t *rindex, size_t align, size_t nbytes, void **r) {
2388 size_t k, start, end;
2393 start = ALIGN_TO((size_t) *rindex, align);
2394 end = start + nbytes;
2399 /* Verify that padding is 0 */
2400 for (k = *rindex; k < start; k++)
2401 if (((const uint8_t*) p)[k] != 0)
2405 *r = (uint8_t*) p + start;
2412 static bool message_end_of_signature(sd_bus_message *m) {
2413 struct bus_container *c;
2417 c = message_get_container(m);
2418 return !c->signature || c->signature[c->index] == 0;
2421 static bool message_end_of_array(sd_bus_message *m, size_t index) {
2422 struct bus_container *c;
2426 c = message_get_container(m);
2430 return index >= c->begin + BUS_MESSAGE_BSWAP32(m, *c->array_size);
2433 _public_ int sd_bus_message_at_end(sd_bus_message *m, int complete) {
2434 assert_return(m, -EINVAL);
2435 assert_return(m->sealed, -EPERM);
2437 if (complete && m->n_containers > 0)
2440 if (message_end_of_signature(m))
2443 if (message_end_of_array(m, m->rindex))
2449 static struct bus_body_part* find_part(sd_bus_message *m, size_t index, size_t sz, void **p) {
2450 struct bus_body_part *part;
2456 if (m->cached_rindex_part && index >= m->cached_rindex_part_begin) {
2457 part = m->cached_rindex_part;
2458 begin = m->cached_rindex_part_begin;
2468 if (index + sz <= begin + part->size) {
2470 r = bus_body_part_map(part);
2475 *p = (uint8_t*) part->data + index - begin;
2477 m->cached_rindex_part = part;
2478 m->cached_rindex_part_begin = begin;
2483 begin += part->size;
2490 static int message_peek_body(
2497 size_t k, start, end, padding;
2498 struct bus_body_part *part;
2505 if (message_end_of_array(m, *rindex))
2508 start = ALIGN_TO((size_t) *rindex, align);
2509 padding = start - *rindex;
2510 end = start + nbytes;
2512 if (end > BUS_MESSAGE_BODY_SIZE(m))
2515 part = find_part(m, *rindex, padding, (void**) &q);
2520 /* Verify padding */
2521 for (k = 0; k < padding; k++)
2526 part = find_part(m, start, nbytes, (void**) &q);
2538 static bool validate_nul(const char *s, size_t l) {
2540 /* Check for NUL chars in the string */
2541 if (memchr(s, 0, l))
2544 /* Check for NUL termination */
2551 static bool validate_string(const char *s, size_t l) {
2553 if (!validate_nul(s, l))
2556 /* Check if valid UTF8 */
2557 if (!utf8_is_valid(s))
2563 static bool validate_signature(const char *s, size_t l) {
2565 if (!validate_nul(s, l))
2568 /* Check if valid signature */
2569 if (!signature_is_valid(s, true))
2575 static bool validate_object_path(const char *s, size_t l) {
2577 if (!validate_nul(s, l))
2580 if (!object_path_is_valid(s))
2586 _public_ int sd_bus_message_read_basic(sd_bus_message *m, char type, void *p) {
2587 struct bus_container *c;
2591 assert_return(m, -EINVAL);
2592 assert_return(m->sealed, -EPERM);
2593 assert_return(bus_type_is_basic(type), -EINVAL);
2595 if (message_end_of_signature(m))
2598 if (message_end_of_array(m, m->rindex))
2601 c = message_get_container(m);
2602 if (c->signature[c->index] != type)
2607 case SD_BUS_TYPE_STRING:
2608 case SD_BUS_TYPE_OBJECT_PATH: {
2613 r = message_peek_body(m, &rindex, 4, 4, &q);
2617 l = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2618 r = message_peek_body(m, &rindex, 1, l+1, &q);
2624 if (type == SD_BUS_TYPE_OBJECT_PATH) {
2625 if (!validate_object_path(q, l))
2628 if (!validate_string(q, l))
2634 *(const char**) p = q;
2639 case SD_BUS_TYPE_SIGNATURE: {
2644 r = message_peek_body(m, &rindex, 1, 1, &q);
2649 r = message_peek_body(m, &rindex, 1, l+1, &q);
2655 if (!validate_signature(q, l))
2661 *(const char**) p = q;
2669 align = bus_type_get_alignment(type);
2670 sz = bus_type_get_size(type);
2671 assert(align > 0 && sz > 0);
2674 r = message_peek_body(m, &rindex, align, sz, &q);
2680 case SD_BUS_TYPE_BYTE:
2682 *(uint8_t*) p = *(uint8_t*) q;
2685 case SD_BUS_TYPE_BOOLEAN:
2687 *(int*) p = !!*(uint32_t*) q;
2690 case SD_BUS_TYPE_INT16:
2691 case SD_BUS_TYPE_UINT16:
2693 *(uint16_t*) p = BUS_MESSAGE_BSWAP16(m, *(uint16_t*) q);
2696 case SD_BUS_TYPE_INT32:
2697 case SD_BUS_TYPE_UINT32:
2699 *(uint32_t*) p = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2702 case SD_BUS_TYPE_INT64:
2703 case SD_BUS_TYPE_UINT64:
2704 case SD_BUS_TYPE_DOUBLE:
2706 *(uint64_t*) p = BUS_MESSAGE_BSWAP64(m, *(uint64_t*) q);
2709 case SD_BUS_TYPE_UNIX_FD: {
2712 j = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2717 *(int*) p = m->fds[j];
2722 assert_not_reached("Unknown basic type...");
2731 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2737 static int bus_message_enter_array(
2739 struct bus_container *c,
2740 const char *contents,
2741 uint32_t **array_size) {
2752 if (!signature_is_single(contents, true))
2755 alignment = bus_type_get_alignment(contents[0]);
2759 if (!c->signature || c->signature[c->index] == 0)
2762 if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
2765 if (!startswith(c->signature + c->index + 1, contents))
2769 r = message_peek_body(m, &rindex, 4, 4, &q);
2773 if (BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q) > BUS_ARRAY_MAX_SIZE)
2776 r = message_peek_body(m, &rindex, alignment, 0, NULL);
2782 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2783 c->index += 1 + strlen(contents);
2787 *array_size = (uint32_t*) q;
2792 static int bus_message_enter_variant(
2794 struct bus_container *c,
2795 const char *contents) {
2806 if (!signature_is_single(contents, false))
2809 if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
2812 if (!c->signature || c->signature[c->index] == 0)
2815 if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
2819 r = message_peek_body(m, &rindex, 1, 1, &q);
2824 r = message_peek_body(m, &rindex, 1, l+1, &q);
2830 if (!validate_signature(q, l))
2833 if (!streq(q, contents))
2836 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2844 static int bus_message_enter_struct(
2846 struct bus_container *c,
2847 const char *contents) {
2856 if (!signature_is_valid(contents, false))
2859 if (!c->signature || c->signature[c->index] == 0)
2862 l = strlen(contents);
2864 if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
2865 !startswith(c->signature + c->index + 1, contents) ||
2866 c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
2869 r = message_peek_body(m, &m->rindex, 8, 0, NULL);
2873 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2874 c->index += 1 + l + 1;
2879 static int bus_message_enter_dict_entry(
2881 struct bus_container *c,
2882 const char *contents) {
2891 if (!signature_is_pair(contents))
2894 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2897 if (!c->signature || c->signature[c->index] == 0)
2900 l = strlen(contents);
2902 if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
2903 !startswith(c->signature + c->index + 1, contents) ||
2904 c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
2907 r = message_peek_body(m, &m->rindex, 8, 0, NULL);
2911 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2912 c->index += 1 + l + 1;
2917 _public_ int sd_bus_message_enter_container(sd_bus_message *m,
2919 const char *contents) {
2920 struct bus_container *c, *w;
2921 uint32_t *array_size = NULL;
2926 assert_return(m, -EINVAL);
2927 assert_return(m->sealed, -EPERM);
2928 assert_return(type != 0 || !contents, -EINVAL);
2930 if (type == 0 || !contents) {
2934 /* Allow entering into anonymous containers */
2935 r = sd_bus_message_peek_type(m, &tt, &cc);
2939 if (type != 0 && type != tt)
2942 if (contents && !streq(contents, cc))
2950 * We enforce a global limit on container depth, that is much
2951 * higher than the 32 structs and 32 arrays the specification
2952 * mandates. This is simpler to implement for us, and we need
2953 * this only to ensure our container array doesn't grow
2954 * without bounds. We are happy to return any data from a
2955 * message as long as the data itself is valid, even if the
2956 * overall message might be not.
2958 * Note that the message signature is validated when
2959 * parsing the headers, and that validation does check the
2962 * Note that the specification defines no limits on the depth
2963 * of stacked variants, but we do.
2965 if (m->n_containers >= BUS_CONTAINER_DEPTH)
2968 w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
2973 if (message_end_of_signature(m))
2976 if (message_end_of_array(m, m->rindex))
2979 c = message_get_container(m);
2981 signature = strdup(contents);
2985 c->saved_index = c->index;
2988 if (type == SD_BUS_TYPE_ARRAY)
2989 r = bus_message_enter_array(m, c, contents, &array_size);
2990 else if (type == SD_BUS_TYPE_VARIANT)
2991 r = bus_message_enter_variant(m, c, contents);
2992 else if (type == SD_BUS_TYPE_STRUCT)
2993 r = bus_message_enter_struct(m, c, contents);
2994 else if (type == SD_BUS_TYPE_DICT_ENTRY)
2995 r = bus_message_enter_dict_entry(m, c, contents);
3004 /* OK, let's fill it in */
3005 w += m->n_containers++;
3006 w->enclosing = type;
3007 w->signature = signature;
3009 w->array_size = array_size;
3011 w->begin = m->rindex;
3016 _public_ int sd_bus_message_exit_container(sd_bus_message *m) {
3017 struct bus_container *c;
3019 assert_return(m, -EINVAL);
3020 assert_return(m->sealed, -EPERM);
3021 assert_return(m->n_containers > 0, -EINVAL);
3023 c = message_get_container(m);
3024 if (c->enclosing == SD_BUS_TYPE_ARRAY) {
3027 l = BUS_MESSAGE_BSWAP32(m, *c->array_size);
3028 if (c->begin + l != m->rindex)
3032 if (c->signature && c->signature[c->index] != 0)
3042 static void message_quit_container(sd_bus_message *m) {
3043 struct bus_container *c;
3047 assert(m->n_containers > 0);
3049 c = message_get_container(m);
3052 assert(m->rindex >= c->before);
3053 m->rindex = c->before;
3055 /* Free container */
3059 /* Correct index of new top-level container */
3060 c = message_get_container(m);
3061 c->index = c->saved_index;
3064 _public_ int sd_bus_message_peek_type(sd_bus_message *m, char *type, const char **contents) {
3065 struct bus_container *c;
3068 assert_return(m, -EINVAL);
3069 assert_return(m->sealed, -EPERM);
3071 if (message_end_of_signature(m))
3074 if (message_end_of_array(m, m->rindex))
3077 c = message_get_container(m);
3079 if (bus_type_is_basic(c->signature[c->index])) {
3083 *type = c->signature[c->index];
3087 if (c->signature[c->index] == SD_BUS_TYPE_ARRAY) {
3093 r = signature_element_length(c->signature+c->index+1, &l);
3099 sig = strndup(c->signature + c->index + 1, l);
3103 free(m->peeked_signature);
3104 m->peeked_signature = sig;
3110 *type = SD_BUS_TYPE_ARRAY;
3115 if (c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ||
3116 c->signature[c->index] == SD_BUS_TYPE_DICT_ENTRY_BEGIN) {
3122 r = signature_element_length(c->signature+c->index, &l);
3127 sig = strndup(c->signature + c->index + 1, l - 2);
3131 free(m->peeked_signature);
3132 m->peeked_signature = sig;
3138 *type = c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY;
3143 if (c->signature[c->index] == SD_BUS_TYPE_VARIANT) {
3149 r = message_peek_body(m, &rindex, 1, 1, &q);
3156 r = message_peek_body(m, &rindex, 1, l+1, &q);
3162 if (!validate_signature(q, l))
3169 *type = SD_BUS_TYPE_VARIANT;
3184 _public_ int sd_bus_message_rewind(sd_bus_message *m, int complete) {
3185 struct bus_container *c;
3187 assert_return(m, -EINVAL);
3188 assert_return(m->sealed, -EPERM);
3191 message_reset_containers(m);
3193 m->root_container.index = 0;
3195 c = message_get_container(m);
3197 c = message_get_container(m);
3200 m->rindex = c->begin;
3203 return !isempty(c->signature);
3205 static int message_read_ap(
3210 unsigned n_array, n_struct;
3211 TypeStack stack[BUS_CONTAINER_DEPTH];
3212 unsigned stack_ptr = 0;
3213 unsigned n_loop = 0;
3221 /* Ideally, we'd just call ourselves recursively on every
3222 * complex type. However, the state of a va_list that is
3223 * passed to a function is undefined after that function
3224 * returns. This means we need to docode the va_list linearly
3225 * in a single stackframe. We hence implement our own
3226 * home-grown stack in an array. */
3228 n_array = (unsigned) -1; /* lenght of current array entries */
3229 n_struct = strlen(types); /* length of current struct contents signature */
3236 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
3237 r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
3243 r = sd_bus_message_exit_container(m);
3251 if (n_array != (unsigned) -1)
3260 case SD_BUS_TYPE_BYTE:
3261 case SD_BUS_TYPE_BOOLEAN:
3262 case SD_BUS_TYPE_INT16:
3263 case SD_BUS_TYPE_UINT16:
3264 case SD_BUS_TYPE_INT32:
3265 case SD_BUS_TYPE_UINT32:
3266 case SD_BUS_TYPE_INT64:
3267 case SD_BUS_TYPE_UINT64:
3268 case SD_BUS_TYPE_DOUBLE:
3269 case SD_BUS_TYPE_STRING:
3270 case SD_BUS_TYPE_OBJECT_PATH:
3271 case SD_BUS_TYPE_SIGNATURE:
3272 case SD_BUS_TYPE_UNIX_FD: {
3275 p = va_arg(ap, void*);
3276 r = sd_bus_message_read_basic(m, *t, p);
3289 case SD_BUS_TYPE_ARRAY: {
3292 r = signature_element_length(t + 1, &k);
3298 memcpy(s, t + 1, k);
3301 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, s);
3312 if (n_array == (unsigned) -1) {
3317 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
3323 n_array = va_arg(ap, unsigned);
3328 case SD_BUS_TYPE_VARIANT: {
3331 s = va_arg(ap, const char *);
3335 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, s);
3345 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
3350 n_struct = strlen(s);
3351 n_array = (unsigned) -1;
3356 case SD_BUS_TYPE_STRUCT_BEGIN:
3357 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
3360 r = signature_element_length(t, &k);
3366 memcpy(s, t + 1, k - 2);
3369 r = sd_bus_message_enter_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
3379 if (n_array == (unsigned) -1) {
3384 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
3390 n_array = (unsigned) -1;
3403 _public_ int sd_bus_message_read(sd_bus_message *m, const char *types, ...) {
3407 assert_return(m, -EINVAL);
3408 assert_return(m->sealed, -EPERM);
3409 assert_return(types, -EINVAL);
3411 va_start(ap, types);
3412 r = message_read_ap(m, types, ap);
3418 _public_ int sd_bus_message_skip(sd_bus_message *m, const char *types) {
3421 assert_return(m, -EINVAL);
3422 assert_return(m->sealed, -EPERM);
3423 assert_return(types, -EINVAL);
3430 case SD_BUS_TYPE_BYTE:
3431 case SD_BUS_TYPE_BOOLEAN:
3432 case SD_BUS_TYPE_INT16:
3433 case SD_BUS_TYPE_UINT16:
3434 case SD_BUS_TYPE_INT32:
3435 case SD_BUS_TYPE_UINT32:
3436 case SD_BUS_TYPE_INT64:
3437 case SD_BUS_TYPE_UINT64:
3438 case SD_BUS_TYPE_DOUBLE:
3439 case SD_BUS_TYPE_STRING:
3440 case SD_BUS_TYPE_OBJECT_PATH:
3441 case SD_BUS_TYPE_SIGNATURE:
3442 case SD_BUS_TYPE_UNIX_FD:
3444 r = sd_bus_message_read_basic(m, *types, NULL);
3448 r = sd_bus_message_skip(m, types + 1);
3454 case SD_BUS_TYPE_ARRAY: {
3457 r = signature_element_length(types + 1, &k);
3463 memcpy(s, types+1, k);
3466 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, s);
3471 r = sd_bus_message_skip(m, s);
3478 r = sd_bus_message_exit_container(m);
3483 r = sd_bus_message_skip(m, types + 1 + k);
3490 case SD_BUS_TYPE_VARIANT: {
3491 const char *contents;
3494 r = sd_bus_message_peek_type(m, &x, &contents);
3498 if (x != SD_BUS_TYPE_VARIANT)
3501 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, contents);
3505 r = sd_bus_message_skip(m, contents);
3510 r = sd_bus_message_exit_container(m);
3514 r = sd_bus_message_skip(m, types + 1);
3521 case SD_BUS_TYPE_STRUCT_BEGIN:
3522 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
3525 r = signature_element_length(types, &k);
3531 memcpy(s, types+1, k-2);
3534 r = sd_bus_message_enter_container(m, *types == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
3538 r = sd_bus_message_skip(m, s);
3543 r = sd_bus_message_exit_container(m);
3548 r = sd_bus_message_skip(m, types + k);
3560 _public_ int sd_bus_message_read_array(sd_bus_message *m,
3564 struct bus_container *c;
3570 assert_return(m, -EINVAL);
3571 assert_return(m->sealed, -EPERM);
3572 assert_return(bus_type_is_trivial(type), -EINVAL);
3573 assert_return(ptr, -EINVAL);
3574 assert_return(size, -EINVAL);
3575 assert_return(!BUS_MESSAGE_NEED_BSWAP(m), -ENOTSUP);
3577 align = bus_type_get_alignment(type);
3581 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
3585 c = message_get_container(m);
3586 sz = BUS_MESSAGE_BSWAP32(m, *c->array_size);
3589 /* Zero length array, let's return some aligned
3590 * pointer that is not NULL */
3591 p = (uint8_t*) NULL + align;
3593 r = message_peek_body(m, &m->rindex, align, sz, &p);
3602 r = sd_bus_message_exit_container(m);
3606 *ptr = (const void*) p;
3612 message_quit_container(m);
3616 static int message_peek_fields(
3627 return buffer_peek(BUS_MESSAGE_FIELDS(m), BUS_MESSAGE_FIELDS_SIZE(m), rindex, align, nbytes, ret);
3630 static int message_peek_field_uint32(
3641 r = message_peek_fields(m, ri, 4, 4, &q);
3646 *ret = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
3651 static int message_peek_field_string(
3653 bool (*validate)(const char *p),
3664 r = message_peek_field_uint32(m, ri, &l);
3668 r = message_peek_fields(m, ri, 1, l+1, &q);
3673 if (!validate_nul(q, l))
3679 if (!validate_string(q, l))
3689 static int message_peek_field_signature(
3701 r = message_peek_fields(m, ri, 1, 1, &q);
3706 r = message_peek_fields(m, ri, 1, l+1, &q);
3710 if (!validate_signature(q, l))
3719 static int message_skip_fields(
3722 uint32_t array_size,
3723 const char **signature) {
3725 size_t original_index;
3732 original_index = *ri;
3738 if (array_size != (uint32_t) -1 &&
3739 array_size <= *ri - original_index)
3746 if (t == SD_BUS_TYPE_STRING) {
3748 r = message_peek_field_string(m, NULL, ri, NULL);
3754 } else if (t == SD_BUS_TYPE_OBJECT_PATH) {
3756 r = message_peek_field_string(m, object_path_is_valid, ri, NULL);
3762 } else if (t == SD_BUS_TYPE_SIGNATURE) {
3764 r = message_peek_field_signature(m, ri, NULL);
3770 } else if (bus_type_is_basic(t)) {
3773 align = bus_type_get_alignment(t);
3774 k = bus_type_get_size(t);
3775 assert(align > 0 && k > 0);
3777 r = message_peek_fields(m, ri, align, k, NULL);
3783 } else if (t == SD_BUS_TYPE_ARRAY) {
3785 r = signature_element_length(*signature+1, &l);
3795 strncpy(sig, *signature + 1, l-1);
3798 alignment = bus_type_get_alignment(sig[0]);
3802 r = message_peek_field_uint32(m, ri, &nas);
3805 if (nas > BUS_ARRAY_MAX_SIZE)
3808 r = message_peek_fields(m, ri, alignment, 0, NULL);
3812 r = message_skip_fields(m, ri, nas, (const char**) &s);
3817 (*signature) += 1 + l;
3819 } else if (t == SD_BUS_TYPE_VARIANT) {
3822 r = message_peek_field_signature(m, ri, &s);
3826 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
3832 } else if (t == SD_BUS_TYPE_STRUCT ||
3833 t == SD_BUS_TYPE_DICT_ENTRY) {
3835 r = signature_element_length(*signature, &l);
3842 strncpy(sig, *signature + 1, l-1);
3845 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
3856 int bus_message_parse_fields(sd_bus_message *m) {
3859 uint32_t unix_fds = 0;
3863 for (ri = 0; ri < BUS_MESSAGE_FIELDS_SIZE(m); ) {
3864 const char *signature;
3867 r = message_peek_fields(m, &ri, 8, 1, (void**) &header);
3871 r = message_peek_field_signature(m, &ri, &signature);
3876 case _SD_BUS_MESSAGE_HEADER_INVALID:
3879 case SD_BUS_MESSAGE_HEADER_PATH:
3884 if (!streq(signature, "o"))
3887 r = message_peek_field_string(m, object_path_is_valid, &ri, &m->path);
3890 case SD_BUS_MESSAGE_HEADER_INTERFACE:
3895 if (!streq(signature, "s"))
3898 r = message_peek_field_string(m, interface_name_is_valid, &ri, &m->interface);
3901 case SD_BUS_MESSAGE_HEADER_MEMBER:
3906 if (!streq(signature, "s"))
3909 r = message_peek_field_string(m, member_name_is_valid, &ri, &m->member);
3912 case SD_BUS_MESSAGE_HEADER_ERROR_NAME:
3917 if (!streq(signature, "s"))
3920 r = message_peek_field_string(m, error_name_is_valid, &ri, &m->error.name);
3923 case SD_BUS_MESSAGE_HEADER_DESTINATION:
3928 if (!streq(signature, "s"))
3931 r = message_peek_field_string(m, service_name_is_valid, &ri, &m->destination);
3934 case SD_BUS_MESSAGE_HEADER_SENDER:
3939 if (!streq(signature, "s"))
3942 r = message_peek_field_string(m, service_name_is_valid, &ri, &m->sender);
3946 case SD_BUS_MESSAGE_HEADER_SIGNATURE: {
3950 if (m->root_container.signature)
3953 if (!streq(signature, "g"))
3956 r = message_peek_field_signature(m, &ri, &s);
3964 free(m->root_container.signature);
3965 m->root_container.signature = c;
3969 case SD_BUS_MESSAGE_HEADER_REPLY_SERIAL:
3970 if (m->reply_serial != 0)
3973 if (!streq(signature, "u"))
3976 r = message_peek_field_uint32(m, &ri, &m->reply_serial);
3980 if (m->reply_serial == 0)
3985 case SD_BUS_MESSAGE_HEADER_UNIX_FDS:
3989 if (!streq(signature, "u"))
3992 r = message_peek_field_uint32(m, &ri, &unix_fds);
4002 r = message_skip_fields(m, &ri, (uint32_t) -1, (const char **) &signature);
4009 if (m->n_fds != unix_fds)
4012 if (isempty(m->root_container.signature) != (BUS_MESSAGE_BODY_SIZE(m) == 0))
4015 switch (m->header->type) {
4017 case SD_BUS_MESSAGE_SIGNAL:
4018 if (!m->path || !m->interface || !m->member)
4022 case SD_BUS_MESSAGE_METHOD_CALL:
4024 if (!m->path || !m->member)
4029 case SD_BUS_MESSAGE_METHOD_RETURN:
4031 if (m->reply_serial == 0)
4035 case SD_BUS_MESSAGE_METHOD_ERROR:
4037 if (m->reply_serial == 0 || !m->error.name)
4042 /* Try to read the error message, but if we can't it's a non-issue */
4043 if (m->header->type == SD_BUS_MESSAGE_METHOD_ERROR)
4044 sd_bus_message_read(m, "s", &m->error.message);
4049 int bus_message_seal(sd_bus_message *m, uint64_t serial) {
4050 struct bus_body_part *part;
4060 if (m->n_containers > 0)
4066 /* If there's a non-trivial signature set, then add it in here */
4067 if (!isempty(m->root_container.signature)) {
4068 r = message_append_field_signature(m, SD_BUS_MESSAGE_HEADER_SIGNATURE, m->root_container.signature, NULL);
4074 r = message_append_field_uint32(m, SD_BUS_MESSAGE_HEADER_UNIX_FDS, m->n_fds);
4079 /* Add padding at the end of the fields part, since we know
4080 * the body needs to start at an 8 byte alignment. We made
4081 * sure we allocated enough space for this, so all we need to
4082 * do here is to zero it out. */
4083 l = BUS_MESSAGE_FIELDS_SIZE(m);
4086 memset((uint8_t*) BUS_MESSAGE_FIELDS(m) + l, 0, a);
4088 /* If this is something we can send as memfd, then let's seal
4089 the memfd now. Note that we can send memfds as payload only
4090 for directed messages, and not for broadcasts. */
4091 if (m->destination && m->bus && m->bus->use_memfd) {
4092 MESSAGE_FOREACH_PART(part, i, m)
4093 if (part->memfd >= 0 && !part->sealed && (part->size > MEMFD_MIN_SIZE || m->bus->use_memfd < 0)) {
4094 bus_body_part_unmap(part);
4096 if (ioctl(part->memfd, KDBUS_CMD_MEMFD_SEAL_SET, 1) >= 0)
4097 part->sealed = true;
4101 m->header->serial = serial;
4107 _public_ int sd_bus_message_set_destination(sd_bus_message *m, const char *destination) {
4108 assert_return(m, -EINVAL);
4109 assert_return(destination, -EINVAL);
4110 assert_return(!m->sealed, -EPERM);
4111 assert_return(!m->destination, -EEXIST);
4113 return message_append_field_string(m, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &m->destination);
4116 int bus_message_dump(sd_bus_message *m, FILE *f, bool with_header) {
4117 const char *u = NULL, *uu = NULL, *s = NULL;
4118 char **cmdline = NULL;
4121 uid_t owner, audit_loginuid;
4122 uint32_t audit_sessionid;
4138 "\tfields_size=%u\n"
4143 "\tdestination=%s\n"
4146 "\treply_serial=%u\n"
4148 "\tn_body_parts=%u\n",
4155 BUS_MESSAGE_SERIAL(m),
4156 BUS_MESSAGE_FIELDS_SIZE(m),
4157 BUS_MESSAGE_BODY_SIZE(m),
4159 strna(m->interface),
4161 strna(m->destination),
4163 strna(m->root_container.signature),
4168 if (sd_bus_error_is_set(&m->error))
4171 "\terror.message=%s\n",
4172 strna(m->error.name),
4173 strna(m->error.message));
4176 fprintf(f, "\tpid=%lu\n", (unsigned long) m->pid);
4178 fprintf(f, "\ttid=%lu\n", (unsigned long) m->tid);
4180 fprintf(f, "\tuid=%lu\n", (unsigned long) m->uid);
4182 fprintf(f, "\tgid=%lu\n", (unsigned long) m->gid);
4183 if (m->pid_starttime != 0)
4184 fprintf(f, "\tpid_starttime=%llu\n", (unsigned long long) m->pid_starttime);
4185 if (m->monotonic != 0)
4186 fprintf(f, "\tmonotonic=%llu\n", (unsigned long long) m->monotonic);
4187 if (m->realtime != 0)
4188 fprintf(f, "\trealtime=%llu\n", (unsigned long long) m->realtime);
4190 fprintf(f, "\texe=[%s]\n", m->exe);
4192 fprintf(f, "\tcomm=[%s]\n", m->comm);
4194 fprintf(f, "\ttid_comm=[%s]\n", m->tid_comm);
4196 fprintf(f, "\tlabel=[%s]\n", m->label);
4198 fprintf(f, "\tcgroup=[%s]\n", m->cgroup);
4200 sd_bus_message_get_unit(m, &u);
4202 fprintf(f, "\tunit=[%s]\n", u);
4203 sd_bus_message_get_user_unit(m, &uu);
4205 fprintf(f, "\tuser_unit=[%s]\n", uu);
4206 sd_bus_message_get_session(m, &s);
4208 fprintf(f, "\tsession=[%s]\n", s);
4209 if (sd_bus_message_get_owner_uid(m, &owner) >= 0)
4210 fprintf(f, "\towner_uid=%lu\n", (unsigned long) owner);
4211 if (sd_bus_message_get_audit_loginuid(m, &audit_loginuid) >= 0)
4212 fprintf(f, "\taudit_loginuid=%lu\n", (unsigned long) audit_loginuid);
4213 if (sd_bus_message_get_audit_sessionid(m, &audit_sessionid) >= 0)
4214 fprintf(f, "\taudit_sessionid=%lu\n", (unsigned long) audit_sessionid);
4216 r = sd_bus_message_has_effective_cap(m, 5);
4218 fprintf(f, "\tCAP_KILL=%s\n", yes_no(r));
4220 if (sd_bus_message_get_cmdline(m, &cmdline) >= 0) {
4223 fputs("\tcmdline=[", f);
4224 STRV_FOREACH(c, cmdline) {
4235 r = sd_bus_message_rewind(m, true);
4237 log_error("Failed to rewind: %s", strerror(-r));
4241 fprintf(f, "MESSAGE \"%s\" {\n", strempty(m->root_container.signature));
4244 _cleanup_free_ char *prefix = NULL;
4245 const char *contents = NULL;
4260 r = sd_bus_message_peek_type(m, &type, &contents);
4262 log_error("Failed to peek type: %s", strerror(-r));
4270 r = sd_bus_message_exit_container(m);
4272 log_error("Failed to exit container: %s", strerror(-r));
4278 prefix = strrep("\t", level);
4282 fprintf(f, "%s};\n", prefix);
4286 prefix = strrep("\t", level);
4290 if (bus_type_is_container(type) > 0) {
4291 r = sd_bus_message_enter_container(m, type, contents);
4293 log_error("Failed to enter container: %s", strerror(-r));
4297 if (type == SD_BUS_TYPE_ARRAY)
4298 fprintf(f, "%sARRAY \"%s\" {\n", prefix, contents);
4299 else if (type == SD_BUS_TYPE_VARIANT)
4300 fprintf(f, "%sVARIANT \"%s\" {\n", prefix, contents);
4301 else if (type == SD_BUS_TYPE_STRUCT)
4302 fprintf(f, "%sSTRUCT \"%s\" {\n", prefix, contents);
4303 else if (type == SD_BUS_TYPE_DICT_ENTRY)
4304 fprintf(f, "%sDICT_ENTRY \"%s\" {\n", prefix, contents);
4311 r = sd_bus_message_read_basic(m, type, &basic);
4313 log_error("Failed to get basic: %s", strerror(-r));
4321 case SD_BUS_TYPE_BYTE:
4322 fprintf(f, "%sBYTE %u;\n", prefix, basic.u8);
4325 case SD_BUS_TYPE_BOOLEAN:
4326 fprintf(f, "%sBOOLEAN %s;\n", prefix, yes_no(basic.i));
4329 case SD_BUS_TYPE_INT16:
4330 fprintf(f, "%sINT16 %i;\n", prefix, basic.s16);
4333 case SD_BUS_TYPE_UINT16:
4334 fprintf(f, "%sUINT16 %u;\n", prefix, basic.u16);
4337 case SD_BUS_TYPE_INT32:
4338 fprintf(f, "%sINT32 %i;\n", prefix, basic.s32);
4341 case SD_BUS_TYPE_UINT32:
4342 fprintf(f, "%sUINT32 %u;\n", prefix, basic.u32);
4345 case SD_BUS_TYPE_INT64:
4346 fprintf(f, "%sINT64 %lli;\n", prefix, (long long) basic.s64);
4349 case SD_BUS_TYPE_UINT64:
4350 fprintf(f, "%sUINT64 %llu;\n", prefix, (unsigned long long) basic.u64);
4353 case SD_BUS_TYPE_DOUBLE:
4354 fprintf(f, "%sDOUBLE %g;\n", prefix, basic.d64);
4357 case SD_BUS_TYPE_STRING:
4358 fprintf(f, "%sSTRING \"%s\";\n", prefix, basic.string);
4361 case SD_BUS_TYPE_OBJECT_PATH:
4362 fprintf(f, "%sOBJECT_PATH \"%s\";\n", prefix, basic.string);
4365 case SD_BUS_TYPE_SIGNATURE:
4366 fprintf(f, "%sSIGNATURE \"%s\";\n", prefix, basic.string);
4369 case SD_BUS_TYPE_UNIX_FD:
4370 fprintf(f, "%sUNIX_FD %i;\n", prefix, basic.i);
4374 assert_not_reached("Unknown basic type.");
4382 int bus_message_get_blob(sd_bus_message *m, void **buffer, size_t *sz) {
4386 struct bus_body_part *part;
4392 total = BUS_MESSAGE_SIZE(m);
4398 e = mempcpy(p, m->header, BUS_MESSAGE_BODY_BEGIN(m));
4399 MESSAGE_FOREACH_PART(part, i, m)
4400 e = mempcpy(e, part->data, part->size);
4402 assert(total == (size_t) ((uint8_t*) e - (uint8_t*) p));
4410 int bus_message_read_strv_extend(sd_bus_message *m, char ***l) {
4416 r = sd_bus_message_enter_container(m, 'a', "s");
4423 r = sd_bus_message_read_basic(m, 's', &s);
4429 r = strv_extend(l, s);
4434 r = sd_bus_message_exit_container(m);
4441 _public_ int sd_bus_message_read_strv(sd_bus_message *m, char ***l) {
4445 assert_return(m, -EINVAL);
4446 assert_return(m->sealed, -EPERM);
4447 assert_return(l, -EINVAL);
4449 r = bus_message_read_strv_extend(m, &strv);
4459 const char* bus_message_get_arg(sd_bus_message *m, unsigned i) {
4461 const char *t = NULL;
4466 r = sd_bus_message_rewind(m, true);
4470 for (j = 0; j <= i; j++) {
4473 r = sd_bus_message_peek_type(m, &type, NULL);
4477 if (type != SD_BUS_TYPE_STRING &&
4478 type != SD_BUS_TYPE_OBJECT_PATH &&
4479 type != SD_BUS_TYPE_SIGNATURE)
4482 r = sd_bus_message_read_basic(m, type, &t);
4490 bool bus_header_is_complete(struct bus_header *h, size_t size) {
4496 if (size < sizeof(struct bus_header))
4499 full = sizeof(struct bus_header) +
4500 (h->endian == SD_BUS_NATIVE_ENDIAN ? h->fields_size : bswap_32(h->fields_size));
4502 return size >= full;
4505 int bus_header_message_size(struct bus_header *h, size_t *sum) {
4511 if (h->endian == SD_BUS_NATIVE_ENDIAN) {
4512 fs = h->fields_size;
4514 } else if (h->endian == SD_BUS_REVERSE_ENDIAN) {
4515 fs = bswap_32(h->fields_size);
4516 bs = bswap_32(h->body_size);
4520 *sum = sizeof(struct bus_header) + ALIGN8(fs) + bs;
4524 _public_ int sd_bus_message_get_errno(sd_bus_message *m) {
4525 assert_return(m, -EINVAL);
4527 if (m->header->type != SD_BUS_MESSAGE_METHOD_ERROR)
4530 return sd_bus_error_get_errno(&m->error);
4533 _public_ const char* sd_bus_message_get_signature(sd_bus_message *m, int complete) {
4534 struct bus_container *c;
4536 assert_return(m, NULL);
4538 c = complete ? &m->root_container : message_get_container(m);
4539 return c->signature ?: "";
4542 _public_ int sd_bus_message_copy(sd_bus_message *m, sd_bus_message *source, int all) {
4543 bool done_something = false;
4546 assert_return(m, -EINVAL);
4547 assert_return(source, -EINVAL);
4548 assert_return(!m->sealed, -EPERM);
4549 assert_return(source->sealed, -EPERM);
4552 const char *contents;
4567 r = sd_bus_message_peek_type(source, &type, &contents);
4573 done_something = true;
4575 if (bus_type_is_container(type) > 0) {
4577 r = sd_bus_message_enter_container(source, type, contents);
4581 r = sd_bus_message_open_container(m, type, contents);
4585 r = sd_bus_message_copy(m, source, true);
4589 r = sd_bus_message_close_container(m);
4593 r = sd_bus_message_exit_container(source);
4600 r = sd_bus_message_read_basic(source, type, &basic);
4606 if (type == SD_BUS_TYPE_OBJECT_PATH ||
4607 type == SD_BUS_TYPE_SIGNATURE ||
4608 type == SD_BUS_TYPE_STRING)
4609 r = sd_bus_message_append_basic(m, type, basic.string);
4611 r = sd_bus_message_append_basic(m, type, &basic);
4618 return done_something;
4621 _public_ int sd_bus_message_verify_type(sd_bus_message *m, char type, const char *contents) {
4626 assert_return(m, -EINVAL);
4627 assert_return(m->sealed, -EPERM);
4628 assert_return(!type || bus_type_is_valid(type), -EINVAL);
4629 assert_return(!contents || signature_is_valid(contents, true), -EINVAL);
4630 assert_return(type || contents, -EINVAL);
4631 assert_return(!contents || !type || bus_type_is_container(type), -EINVAL);
4633 r = sd_bus_message_peek_type(m, &t, &c);
4637 if (type != 0 && type != t)
4640 if (contents && !streq_ptr(contents, c))