1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2013 Lennart Poettering
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
29 #include "time-util.h"
30 #include "cgroup-util.h"
33 #include "bus-message.h"
34 #include "bus-internal.h"
36 #include "bus-signature.h"
38 static int message_append_basic(sd_bus_message *m, char type, const void *p, const void **stored);
40 static void *adjust_pointer(const void *p, void *old_base, size_t sz, void *new_base) {
45 if (old_base == new_base)
48 if ((uint8_t*) p < (uint8_t*) old_base)
51 if ((uint8_t*) p >= (uint8_t*) old_base + sz)
54 return (uint8_t*) new_base + ((uint8_t*) p - (uint8_t*) old_base);
57 static void message_free_part(sd_bus_message *m, struct bus_body_part *part) {
61 if (part->memfd >= 0) {
62 /* If we can reuse the memfd, try that. For that it
63 * can't be sealed yet. */
66 bus_kernel_push_memfd(m->bus, part->memfd, part->data, part->mapped);
69 assert_se(munmap(part->data, part->mapped) == 0);
71 close_nointr_nofail(part->memfd);
74 } else if (part->munmap_this)
75 munmap(part->data, part->mapped);
76 else if (part->free_this)
83 static void message_reset_parts(sd_bus_message *m) {
84 struct bus_body_part *part;
89 while (m->n_body_parts > 0) {
90 struct bus_body_part *next = part->next;
91 message_free_part(m, part);
98 m->cached_rindex_part = NULL;
99 m->cached_rindex_part_begin = 0;
102 static void message_reset_containers(sd_bus_message *m) {
107 for (i = 0; i < m->n_containers; i++)
108 free(m->containers[i].signature);
111 m->containers = NULL;
114 m->root_container.index = 0;
117 static void message_free(sd_bus_message *m) {
123 message_reset_parts(m);
128 if (m->release_kdbus) {
131 off = (uint8_t *)m->kdbus - (uint8_t *)m->bus->kdbus_buffer;
132 ioctl(m->bus->input_fd, KDBUS_CMD_MSG_RELEASE, &off);
136 sd_bus_unref(m->bus);
139 close_many(m->fds, m->n_fds);
143 if (m->iovec != m->iovec_fixed)
146 free(m->cmdline_array);
148 message_reset_containers(m);
149 free(m->root_container.signature);
151 free(m->peeked_signature);
159 static void *message_extend_fields(sd_bus_message *m, size_t align, size_t sz) {
161 size_t old_size, new_size, start;
168 old_size = sizeof(struct bus_header) + m->header->fields_size;
169 start = ALIGN_TO(old_size, align);
170 new_size = start + sz;
172 if (old_size == new_size)
173 return (uint8_t*) m->header + old_size;
175 if (new_size > (size_t) ((uint32_t) -1))
178 if (m->free_header) {
179 np = realloc(m->header, ALIGN8(new_size));
183 /* Initially, the header is allocated as part of of
184 * the sd_bus_message itself, let's replace it by
187 np = malloc(ALIGN8(new_size));
191 memcpy(np, m->header, sizeof(struct bus_header));
194 /* Zero out padding */
195 if (start > old_size)
196 memset((uint8_t*) np + old_size, 0, start - old_size);
200 m->header->fields_size = new_size - sizeof(struct bus_header);
202 /* Adjust quick access pointers */
203 m->path = adjust_pointer(m->path, op, old_size, m->header);
204 m->interface = adjust_pointer(m->interface, op, old_size, m->header);
205 m->member = adjust_pointer(m->member, op, old_size, m->header);
206 m->destination = adjust_pointer(m->destination, op, old_size, m->header);
207 m->sender = adjust_pointer(m->sender, op, old_size, m->header);
208 m->error.name = adjust_pointer(m->error.name, op, old_size, m->header);
210 m->free_header = true;
212 return (uint8_t*) np + start;
219 static int message_append_field_string(
232 if (l > (size_t) (uint32_t) -1)
235 /* field id byte + signature length + signature 's' + NUL + string length + string + NUL */
236 p = message_extend_fields(m, 8, 4 + 4 + l + 1);
245 ((uint32_t*) p)[1] = l;
246 memcpy(p + 8, s, l + 1);
249 *ret = (char*) p + 8;
254 static int message_append_field_signature(
269 /* field id byte + signature length + signature 'g' + NUL + string length + string + NUL */
270 p = message_extend_fields(m, 8, 4 + 1 + l + 1);
276 p[2] = SD_BUS_TYPE_SIGNATURE;
279 memcpy(p + 5, s, l + 1);
282 *ret = (const char*) p + 5;
287 static int message_append_field_uint32(sd_bus_message *m, uint8_t h, uint32_t x) {
292 /* field id byte + signature length + signature 'u' + NUL + value */
293 p = message_extend_fields(m, 8, 4 + 4);
299 p[2] = SD_BUS_TYPE_UINT32;
302 ((uint32_t*) p)[1] = x;
307 int bus_message_from_header(
312 const struct ucred *ucred,
315 sd_bus_message **ret) {
318 struct bus_header *h;
321 assert(buffer || length <= 0);
322 assert(fds || n_fds <= 0);
325 if (length < sizeof(struct bus_header))
335 if (h->type == _SD_BUS_MESSAGE_TYPE_INVALID)
338 if (h->endian != SD_BUS_LITTLE_ENDIAN &&
339 h->endian != SD_BUS_BIG_ENDIAN)
342 a = ALIGN(sizeof(sd_bus_message)) + ALIGN(extra);
345 label_sz = strlen(label);
363 m->uid_valid = m->gid_valid = true;
367 m->label = (char*) m + ALIGN(sizeof(sd_bus_message)) + ALIGN(extra);
368 memcpy(m->label, label, label_sz + 1);
375 int bus_message_from_malloc(
380 const struct ucred *ucred,
382 sd_bus_message **ret) {
387 r = bus_message_from_header(buffer, length, fds, n_fds, ucred, label, 0, &m);
391 if (length != BUS_MESSAGE_SIZE(m)) {
397 m->body.data = (uint8_t*) buffer + sizeof(struct bus_header) + ALIGN8(BUS_MESSAGE_FIELDS_SIZE(m));
398 m->body.size = length - sizeof(struct bus_header) - ALIGN8(BUS_MESSAGE_FIELDS_SIZE(m));
399 m->body.sealed = true;
403 m->iovec = m->iovec_fixed;
404 m->iovec[0].iov_base = buffer;
405 m->iovec[0].iov_len = length;
407 r = bus_message_parse_fields(m);
411 /* We take possession of the memory and fds now */
412 m->free_header = true;
423 static sd_bus_message *message_new(sd_bus *bus, uint8_t type) {
426 m = malloc0(ALIGN(sizeof(sd_bus_message)) + sizeof(struct bus_header));
431 m->header = (struct bus_header*) ((uint8_t*) m + ALIGN(sizeof(struct sd_bus_message)));
432 m->header->endian = SD_BUS_NATIVE_ENDIAN;
433 m->header->type = type;
434 m->header->version = bus ? bus->message_version : 1;
435 m->allow_fds = !bus || bus->can_fds || (bus->state != BUS_HELLO && bus->state != BUS_RUNNING);
438 m->bus = sd_bus_ref(bus);
443 int sd_bus_message_new_signal(
446 const char *interface,
448 sd_bus_message **m) {
461 if (bus && bus->state == BUS_UNSET)
464 t = message_new(bus, SD_BUS_MESSAGE_SIGNAL);
468 t->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
470 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_PATH, SD_BUS_TYPE_OBJECT_PATH, path, &t->path);
473 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_INTERFACE, SD_BUS_TYPE_STRING, interface, &t->interface);
476 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_MEMBER, SD_BUS_TYPE_STRING, member, &t->member);
484 sd_bus_message_unref(t);
488 int sd_bus_message_new_method_call(
490 const char *destination,
492 const char *interface,
494 sd_bus_message **m) {
499 if (destination && !service_name_is_valid(destination))
501 if (!object_path_is_valid(path))
503 if (interface && !interface_name_is_valid(interface))
505 if (!member_name_is_valid(member))
509 if (bus && bus->state == BUS_UNSET)
512 t = message_new(bus, SD_BUS_MESSAGE_METHOD_CALL);
516 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_PATH, SD_BUS_TYPE_OBJECT_PATH, path, &t->path);
519 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_MEMBER, SD_BUS_TYPE_STRING, member, &t->member);
524 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_INTERFACE, SD_BUS_TYPE_STRING, interface, &t->interface);
530 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &t->destination);
543 static int message_new_reply(
545 sd_bus_message *call,
547 sd_bus_message **m) {
556 if (call->header->type != SD_BUS_MESSAGE_METHOD_CALL)
560 if (bus && bus->state == BUS_UNSET)
563 t = message_new(bus, type);
567 t->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
568 t->reply_serial = BUS_MESSAGE_SERIAL(call);
570 r = message_append_field_uint32(t, SD_BUS_MESSAGE_HEADER_REPLY_SERIAL, t->reply_serial);
575 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, call->sender, &t->destination);
580 t->dont_send = !!(call->header->flags & SD_BUS_MESSAGE_NO_REPLY_EXPECTED);
590 int sd_bus_message_new_method_return(
592 sd_bus_message *call,
593 sd_bus_message **m) {
595 return message_new_reply(bus, call, SD_BUS_MESSAGE_METHOD_RETURN, m);
598 int sd_bus_message_new_method_error(
600 sd_bus_message *call,
601 const sd_bus_error *e,
602 sd_bus_message **m) {
607 if (!sd_bus_error_is_set(e))
612 r = message_new_reply(bus, call, SD_BUS_MESSAGE_METHOD_ERROR, &t);
616 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_ERROR_NAME, SD_BUS_TYPE_STRING, e->name, &t->error.name);
621 r = message_append_basic(t, SD_BUS_TYPE_STRING, e->message, (const void**) &t->error.message);
634 int sd_bus_message_new_method_errorf(
636 sd_bus_message *call,
642 _cleanup_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
646 assert_return(name, -EINVAL);
647 assert_return(m, -EINVAL);
649 va_start(ap, format);
650 r = bus_error_setfv(&error, name, format, ap);
656 return sd_bus_message_new_method_error(bus, call, &error, m);
659 int sd_bus_message_new_method_errno(
661 sd_bus_message *call,
663 const sd_bus_error *p,
664 sd_bus_message **m) {
666 _cleanup_free_ sd_bus_error berror = SD_BUS_ERROR_NULL;
668 if (sd_bus_error_is_set(p))
669 return sd_bus_message_new_method_error(bus, call, p, m);
671 sd_bus_error_set_errno(&berror, error);
673 return sd_bus_message_new_method_error(bus, call, &berror, m);
676 int sd_bus_message_new_method_errnof(
678 sd_bus_message *call,
684 _cleanup_free_ sd_bus_error berror = SD_BUS_ERROR_NULL;
688 va_start(ap, format);
689 r = bus_error_set_errnofv(&berror, error, format, ap);
695 return sd_bus_message_new_method_error(bus, call, &berror, m);
698 int bus_message_new_synthetic_error(
701 const sd_bus_error *e,
702 sd_bus_message **m) {
707 assert(sd_bus_error_is_set(e));
710 t = message_new(bus, SD_BUS_MESSAGE_METHOD_ERROR);
714 t->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
715 t->reply_serial = serial;
717 r = message_append_field_uint32(t, SD_BUS_MESSAGE_HEADER_REPLY_SERIAL, t->reply_serial);
721 if (bus && bus->unique_name) {
722 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, bus->unique_name, &t->destination);
727 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_ERROR_NAME, SD_BUS_TYPE_STRING, e->name, &t->error.name);
732 r = message_append_basic(t, SD_BUS_TYPE_STRING, e->message, (const void**) &t->error.message);
745 sd_bus_message* sd_bus_message_ref(sd_bus_message *m) {
749 assert(m->n_ref > 0);
755 sd_bus_message* sd_bus_message_unref(sd_bus_message *m) {
759 assert(m->n_ref > 0);
768 int sd_bus_message_get_type(sd_bus_message *m, uint8_t *type) {
774 *type = m->header->type;
778 int sd_bus_message_get_serial(sd_bus_message *m, uint64_t *serial) {
783 if (m->header->serial == 0)
786 *serial = BUS_MESSAGE_SERIAL(m);
790 int sd_bus_message_get_reply_serial(sd_bus_message *m, uint64_t *serial) {
795 if (m->reply_serial == 0)
798 *serial = m->reply_serial;
802 int sd_bus_message_get_no_reply(sd_bus_message *m) {
806 return m->header->type == SD_BUS_MESSAGE_METHOD_CALL ? !!(m->header->flags & SD_BUS_MESSAGE_NO_REPLY_EXPECTED) : 0;
809 const char *sd_bus_message_get_path(sd_bus_message *m) {
816 const char *sd_bus_message_get_interface(sd_bus_message *m) {
823 const char *sd_bus_message_get_member(sd_bus_message *m) {
829 const char *sd_bus_message_get_destination(sd_bus_message *m) {
833 return m->destination;
836 const char *sd_bus_message_get_sender(sd_bus_message *m) {
843 const sd_bus_error *sd_bus_message_get_error(sd_bus_message *m) {
847 if (!sd_bus_error_is_set(&m->error))
853 int sd_bus_message_get_uid(sd_bus_message *m, uid_t *uid) {
865 int sd_bus_message_get_gid(sd_bus_message *m, gid_t *gid) {
877 int sd_bus_message_get_pid(sd_bus_message *m, pid_t *pid) {
889 int sd_bus_message_get_tid(sd_bus_message *m, pid_t *tid) {
901 int sd_bus_message_get_pid_starttime(sd_bus_message *m, uint64_t *usec) {
906 if (m->pid_starttime <= 0)
909 *usec = m->pid_starttime;
913 int sd_bus_message_get_selinux_context(sd_bus_message *m, const char **ret) {
923 int sd_bus_message_get_monotonic_timestamp(sd_bus_message *m, uint64_t *usec) {
928 if (m->monotonic <= 0)
931 *usec = m->monotonic;
935 int sd_bus_message_get_realtime_timestamp(sd_bus_message *m, uint64_t *usec) {
940 if (m->realtime <= 0)
947 int sd_bus_message_get_comm(sd_bus_message *m, const char **ret) {
959 int sd_bus_message_get_tid_comm(sd_bus_message *m, const char **ret) {
971 int sd_bus_message_get_exe(sd_bus_message *m, const char **ret) {
983 int sd_bus_message_get_cgroup(sd_bus_message *m, const char **ret) {
995 int sd_bus_message_get_unit(sd_bus_message *m, const char **ret) {
1006 r = cg_path_get_unit(m->cgroup, &m->unit);
1015 int sd_bus_message_get_user_unit(sd_bus_message *m, const char **ret) {
1025 if (!m->user_unit) {
1026 r = cg_path_get_user_unit(m->cgroup, &m->user_unit);
1031 *ret = m->user_unit;
1035 int sd_bus_message_get_session(sd_bus_message *m, const char **ret) {
1046 r = cg_path_get_session(m->cgroup, &m->session);
1055 int sd_bus_message_get_owner_uid(sd_bus_message *m, uid_t *uid) {
1063 return cg_path_get_owner_uid(m->cgroup, uid);
1066 int sd_bus_message_get_cmdline(sd_bus_message *m, char ***cmdline) {
1077 for (p = m->cmdline, n = 0; p < m->cmdline + m->cmdline_length; p++)
1081 m->cmdline_array = new(char*, n + 1);
1082 if (!m->cmdline_array)
1085 for (p = m->cmdline, i = 0, first = true; p < m->cmdline + m->cmdline_length; p++) {
1087 m->cmdline_array[i++] = (char*) p;
1092 m->cmdline_array[i] = NULL;
1093 *cmdline = m->cmdline_array;
1098 int sd_bus_message_get_audit_sessionid(sd_bus_message *m, uint32_t *sessionid) {
1106 *sessionid = m->audit->sessionid;
1110 int sd_bus_message_get_audit_loginuid(sd_bus_message *m, uid_t *uid) {
1118 *uid = m->audit->loginuid;
1122 int sd_bus_message_has_effective_cap(sd_bus_message *m, int capability) {
1132 sz = m->capability_size / 4;
1133 if ((unsigned) capability >= sz*8)
1136 return !!(m->capability[2 * sz + (capability / 8)] & (1 << (capability % 8)));
1139 int sd_bus_message_is_signal(sd_bus_message *m, const char *interface, const char *member) {
1143 if (m->header->type != SD_BUS_MESSAGE_SIGNAL)
1146 if (interface && (!m->interface || !streq(m->interface, interface)))
1149 if (member && (!m->member || !streq(m->member, member)))
1155 int sd_bus_message_is_method_call(sd_bus_message *m, const char *interface, const char *member) {
1159 if (m->header->type != SD_BUS_MESSAGE_METHOD_CALL)
1162 if (interface && (!m->interface || !streq(m->interface, interface)))
1165 if (member && (!m->member || !streq(m->member, member)))
1171 int sd_bus_message_is_method_error(sd_bus_message *m, const char *name) {
1175 if (m->header->type != SD_BUS_MESSAGE_METHOD_ERROR)
1178 if (name && (!m->error.name || !streq(m->error.name, name)))
1184 int sd_bus_message_set_no_reply(sd_bus_message *m, int b) {
1189 if (m->header->type != SD_BUS_MESSAGE_METHOD_CALL)
1193 m->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
1195 m->header->flags &= ~SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
1200 static struct bus_container *message_get_container(sd_bus_message *m) {
1203 if (m->n_containers == 0)
1204 return &m->root_container;
1206 assert(m->containers);
1207 return m->containers + m->n_containers - 1;
1210 struct bus_body_part *message_append_part(sd_bus_message *m) {
1211 struct bus_body_part *part;
1218 if (m->n_body_parts <= 0) {
1222 assert(m->body_end);
1224 part = new0(struct bus_body_part, 1);
1230 m->body_end->next = part;
1240 static void part_zero(struct bus_body_part *part, size_t sz) {
1245 /* All other fields can be left in their defaults */
1246 assert(!part->data);
1247 assert(part->memfd < 0);
1250 part->is_zero = true;
1251 part->sealed = true;
1254 static int part_make_space(
1255 struct sd_bus_message *m,
1256 struct bus_body_part *part,
1265 assert(!part->sealed);
1270 if (!part->data && part->memfd < 0)
1271 part->memfd = bus_kernel_pop_memfd(m->bus, &part->data, &part->mapped);
1273 if (part->memfd >= 0) {
1276 r = ioctl(part->memfd, KDBUS_CMD_MEMFD_SIZE_SET, &u);
1282 if (!part->data || sz > part->mapped) {
1283 size_t psz = PAGE_ALIGN(sz > 0 ? sz : 1);
1285 if (part->mapped <= 0)
1286 n = mmap(NULL, psz, PROT_READ|PROT_WRITE, MAP_SHARED, part->memfd, 0);
1288 n = mremap(part->data, part->mapped, psz, MREMAP_MAYMOVE);
1290 if (n == MAP_FAILED) {
1299 part->munmap_this = true;
1301 n = realloc(part->data, MAX(sz, 1u));
1308 part->free_this = true;
1312 *q = part->data ? (uint8_t*) part->data + part->size : NULL;
1318 static void message_extend_containers(sd_bus_message *m, size_t expand) {
1319 struct bus_container *c;
1326 /* Update counters */
1327 for (c = m->containers; c < m->containers + m->n_containers; c++)
1329 *c->array_size += expand;
1332 static void *message_extend_body(sd_bus_message *m, size_t align, size_t sz) {
1333 struct bus_body_part *part = NULL;
1334 size_t start_body, end_body, padding, start_part, end_part, added;
1346 start_body = ALIGN_TO((size_t) m->header->body_size, align);
1347 end_body = start_body + sz;
1349 padding = start_body - m->header->body_size;
1350 added = padding + sz;
1352 /* Check for 32bit overflows */
1353 if (end_body > (size_t) ((uint32_t) -1)) {
1359 m->n_body_parts <= 0 ||
1360 m->body_end->sealed ||
1361 padding != ALIGN_TO(m->body_end->size, align) - m->body_end->size;
1365 part = message_append_part(m);
1369 part_zero(part, padding);
1372 part = message_append_part(m);
1376 r = part_make_space(m, part, sz, &p);
1380 struct bus_container *c;
1388 start_part = ALIGN_TO(part->size, align);
1389 end_part = start_part + sz;
1391 r = part_make_space(m, part, end_part, &p);
1396 memset(p, 0, padding);
1397 p = (uint8_t*) p + padding;
1400 /* Readjust pointers */
1401 for (c = m->containers; c < m->containers + m->n_containers; c++)
1402 c->array_size = adjust_pointer(c->array_size, op, os, part->data);
1404 m->error.message = (const char*) adjust_pointer(m->error.message, op, os, part->data);
1407 m->header->body_size = end_body;
1408 message_extend_containers(m, added);
1413 int message_append_basic(sd_bus_message *m, char type, const void *p, const void **stored) {
1414 struct bus_container *c;
1428 if (!bus_type_is_basic(type))
1433 c = message_get_container(m);
1435 if (c->signature && c->signature[c->index]) {
1436 /* Container signature is already set */
1438 if (c->signature[c->index] != type)
1443 /* Maybe we can append to the signature? But only if this is the top-level container*/
1444 if (c->enclosing != 0)
1447 e = strextend(&c->signature, CHAR_TO_STR(type), NULL);
1456 case SD_BUS_TYPE_STRING:
1457 case SD_BUS_TYPE_OBJECT_PATH:
1460 sz = 4 + strlen(p) + 1;
1463 case SD_BUS_TYPE_SIGNATURE:
1466 sz = 1 + strlen(p) + 1;
1469 case SD_BUS_TYPE_BOOLEAN:
1472 assert_cc(sizeof(int) == sizeof(uint32_t));
1478 case SD_BUS_TYPE_UNIX_FD: {
1481 if (!m->allow_fds) {
1494 fd = fcntl(z, F_DUPFD_CLOEXEC, 3);
1500 f = realloc(m->fds, sizeof(int) * (m->n_fds + 1));
1515 align = bus_type_get_alignment(type);
1516 sz = bus_type_get_size(type);
1523 a = message_extend_body(m, align, sz);
1529 if (type == SD_BUS_TYPE_STRING || type == SD_BUS_TYPE_OBJECT_PATH) {
1530 *(uint32_t*) a = sz - 5;
1531 memcpy((uint8_t*) a + 4, p, sz - 4);
1534 *stored = (const uint8_t*) a + 4;
1536 } else if (type == SD_BUS_TYPE_SIGNATURE) {
1537 *(uint8_t*) a = sz - 1;
1538 memcpy((uint8_t*) a + 1, p, sz - 1);
1541 *stored = (const uint8_t*) a + 1;
1542 } else if (type == SD_BUS_TYPE_UNIX_FD) {
1543 *(uint32_t*) a = fdi;
1557 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1564 close_nointr_nofail(fd);
1569 int sd_bus_message_append_basic(sd_bus_message *m, char type, const void *p) {
1570 return message_append_basic(m, type, p, NULL);
1573 int sd_bus_message_append_string_space(sd_bus_message *m, size_t size, char **s) {
1574 struct bus_container *c;
1586 c = message_get_container(m);
1588 if (c->signature && c->signature[c->index]) {
1589 /* Container signature is already set */
1591 if (c->signature[c->index] != SD_BUS_TYPE_STRING)
1596 /* Maybe we can append to the signature? But only if this is the top-level container*/
1597 if (c->enclosing != 0)
1600 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRING), NULL);
1607 a = message_extend_body(m, 4, 4 + size + 1);
1611 *(uint32_t*) a = size;
1616 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1622 static int bus_message_open_array(
1624 struct bus_container *c,
1625 const char *contents,
1626 uint32_t **array_size) {
1632 struct bus_body_part *o;
1639 if (!signature_is_single(contents, true))
1642 alignment = bus_type_get_alignment(contents[0]);
1646 if (c->signature && c->signature[c->index]) {
1648 /* Verify the existing signature */
1650 if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
1653 if (!startswith(c->signature + c->index + 1, contents))
1656 nindex = c->index + 1 + strlen(contents);
1660 if (c->enclosing != 0)
1663 /* Extend the existing signature */
1665 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_ARRAY), contents, NULL);
1671 nindex = e - c->signature;
1674 a = message_extend_body(m, 4, 4);
1679 op = m->body_end->data;
1680 os = m->body_end->size;
1682 /* Add alignment between size and first element */
1683 if (!message_extend_body(m, alignment, 0))
1686 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1689 /* location of array size might have changed so let's readjust a */
1690 if (o == m->body_end)
1691 a = adjust_pointer(a, op, os, m->body_end->data);
1698 static int bus_message_open_variant(
1700 struct bus_container *c,
1701 const char *contents) {
1710 if (!signature_is_single(contents, false))
1713 if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
1716 if (c->signature && c->signature[c->index]) {
1718 if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
1724 if (c->enclosing != 0)
1727 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_VARIANT), NULL);
1734 l = strlen(contents);
1735 a = message_extend_body(m, 1, 1 + l + 1);
1740 memcpy((uint8_t*) a + 1, contents, l + 1);
1742 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1748 static int bus_message_open_struct(
1750 struct bus_container *c,
1751 const char *contents) {
1759 if (!signature_is_valid(contents, false))
1762 if (c->signature && c->signature[c->index]) {
1765 l = strlen(contents);
1767 if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
1768 !startswith(c->signature + c->index + 1, contents) ||
1769 c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
1772 nindex = c->index + 1 + l + 1;
1776 if (c->enclosing != 0)
1779 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_BEGIN), contents, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_END), NULL);
1785 nindex = e - c->signature;
1788 /* Align contents to 8 byte boundary */
1789 if (!message_extend_body(m, 8, 0))
1792 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1798 static int bus_message_open_dict_entry(
1800 struct bus_container *c,
1801 const char *contents) {
1809 if (!signature_is_pair(contents))
1812 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1815 if (c->signature && c->signature[c->index]) {
1818 l = strlen(contents);
1820 if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
1821 !startswith(c->signature + c->index + 1, contents) ||
1822 c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
1825 nindex = c->index + 1 + l + 1;
1829 /* Align contents to 8 byte boundary */
1830 if (!message_extend_body(m, 8, 0))
1833 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1839 int sd_bus_message_open_container(
1842 const char *contents) {
1844 struct bus_container *c, *w;
1845 uint32_t *array_size = NULL;
1859 /* Make sure we have space for one more container */
1860 w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
1868 c = message_get_container(m);
1870 signature = strdup(contents);
1876 /* Save old index in the parent container, in case we have to
1877 * abort this container */
1878 c->saved_index = c->index;
1879 before = m->header->body_size;
1881 if (type == SD_BUS_TYPE_ARRAY)
1882 r = bus_message_open_array(m, c, contents, &array_size);
1883 else if (type == SD_BUS_TYPE_VARIANT)
1884 r = bus_message_open_variant(m, c, contents);
1885 else if (type == SD_BUS_TYPE_STRUCT)
1886 r = bus_message_open_struct(m, c, contents);
1887 else if (type == SD_BUS_TYPE_DICT_ENTRY)
1888 r = bus_message_open_dict_entry(m, c, contents);
1897 /* OK, let's fill it in */
1898 w += m->n_containers++;
1899 w->enclosing = type;
1900 w->signature = signature;
1902 w->array_size = array_size;
1904 w->begin = m->rindex;
1909 int sd_bus_message_close_container(sd_bus_message *m) {
1910 struct bus_container *c;
1916 if (m->n_containers <= 0)
1921 c = message_get_container(m);
1922 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1923 if (c->signature && c->signature[c->index] != 0)
1938 static int type_stack_push(TypeStack *stack, unsigned max, unsigned *i, const char *types, unsigned n_struct, unsigned n_array) {
1945 stack[*i].types = types;
1946 stack[*i].n_struct = n_struct;
1947 stack[*i].n_array = n_array;
1953 static int type_stack_pop(TypeStack *stack, unsigned max, unsigned *i, const char **types, unsigned *n_struct, unsigned *n_array) {
1964 *types = stack[*i].types;
1965 *n_struct = stack[*i].n_struct;
1966 *n_array = stack[*i].n_array;
1971 int bus_message_append_ap(
1976 unsigned n_array, n_struct;
1977 TypeStack stack[BUS_CONTAINER_DEPTH];
1978 unsigned stack_ptr = 0;
1986 n_array = (unsigned) -1;
1987 n_struct = strlen(types);
1992 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
1993 r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
1999 r = sd_bus_message_close_container(m);
2007 if (n_array != (unsigned) -1)
2016 case SD_BUS_TYPE_BYTE: {
2019 x = (uint8_t) va_arg(ap, int);
2020 r = sd_bus_message_append_basic(m, *t, &x);
2024 case SD_BUS_TYPE_BOOLEAN:
2025 case SD_BUS_TYPE_INT32:
2026 case SD_BUS_TYPE_UINT32:
2027 case SD_BUS_TYPE_UNIX_FD: {
2030 /* We assume a boolean is the same as int32_t */
2031 assert_cc(sizeof(int32_t) == sizeof(int));
2033 x = va_arg(ap, uint32_t);
2034 r = sd_bus_message_append_basic(m, *t, &x);
2038 case SD_BUS_TYPE_INT16:
2039 case SD_BUS_TYPE_UINT16: {
2042 x = (uint16_t) va_arg(ap, int);
2043 r = sd_bus_message_append_basic(m, *t, &x);
2047 case SD_BUS_TYPE_INT64:
2048 case SD_BUS_TYPE_UINT64:
2049 case SD_BUS_TYPE_DOUBLE: {
2052 x = va_arg(ap, uint64_t);
2053 r = sd_bus_message_append_basic(m, *t, &x);
2057 case SD_BUS_TYPE_STRING:
2058 case SD_BUS_TYPE_OBJECT_PATH:
2059 case SD_BUS_TYPE_SIGNATURE: {
2062 x = va_arg(ap, const char*);
2063 r = sd_bus_message_append_basic(m, *t, x);
2067 case SD_BUS_TYPE_ARRAY: {
2070 r = signature_element_length(t + 1, &k);
2076 memcpy(s, t + 1, k);
2079 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, s);
2084 if (n_array == (unsigned) -1) {
2089 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2095 n_array = va_arg(ap, unsigned);
2100 case SD_BUS_TYPE_VARIANT: {
2103 s = va_arg(ap, const char*);
2107 r = sd_bus_message_open_container(m, SD_BUS_TYPE_VARIANT, s);
2111 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2116 n_struct = strlen(s);
2117 n_array = (unsigned) -1;
2122 case SD_BUS_TYPE_STRUCT_BEGIN:
2123 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
2126 r = signature_element_length(t, &k);
2133 memcpy(s, t + 1, k - 2);
2136 r = sd_bus_message_open_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
2141 if (n_array == (unsigned) -1) {
2146 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2152 n_array = (unsigned) -1;
2168 int sd_bus_message_append(sd_bus_message *m, const char *types, ...) {
2181 va_start(ap, types);
2182 r = bus_message_append_ap(m, types, ap);
2188 int sd_bus_message_append_array_space(sd_bus_message *m, char type, size_t size, void **ptr) {
2197 if (!bus_type_is_trivial(type))
2199 if (!ptr && size > 0)
2204 align = bus_type_get_alignment(type);
2205 sz = bus_type_get_size(type);
2207 assert_se(align > 0);
2213 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
2217 a = message_extend_body(m, align, size);
2221 r = sd_bus_message_close_container(m);
2229 int sd_bus_message_append_array(sd_bus_message *m, char type, const void *ptr, size_t size) {
2233 if (!ptr && size > 0)
2236 r = sd_bus_message_append_array_space(m, type, size, &p);
2241 memcpy(p, ptr, size);
2246 int sd_bus_message_append_array_memfd(sd_bus_message *m, char type, sd_memfd *memfd) {
2247 _cleanup_close_ int copy_fd = -1;
2248 struct bus_body_part *part;
2260 if (!bus_type_is_trivial(type))
2265 r = sd_memfd_set_sealed(memfd, true);
2269 copy_fd = sd_memfd_dup_fd(memfd);
2273 r = sd_memfd_get_size(memfd, &size);
2277 align = bus_type_get_alignment(type);
2278 sz = bus_type_get_size(type);
2280 assert_se(align > 0);
2286 if (size > (uint64_t) (uint32_t) -1)
2289 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
2293 a = message_extend_body(m, align, 0);
2297 part = message_append_part(m);
2301 part->memfd = copy_fd;
2302 part->sealed = true;
2306 message_extend_containers(m, size);
2307 m->header->body_size += size;
2309 return sd_bus_message_close_container(m);
2312 int sd_bus_message_append_string_memfd(sd_bus_message *m, sd_memfd *memfd) {
2313 _cleanup_close_ int copy_fd = -1;
2314 struct bus_body_part *part;
2315 struct bus_container *c;
2320 assert_return(m, -EINVAL);
2321 assert_return(memfd, -EINVAL);
2322 assert_return(!m->sealed, -EPERM);
2323 assert_return(!m->poisoned, -ESTALE);
2325 r = sd_memfd_set_sealed(memfd, true);
2329 copy_fd = sd_memfd_dup_fd(memfd);
2333 r = sd_memfd_get_size(memfd, &size);
2337 /* We require this to be NUL terminated */
2341 if (size > (uint64_t) (uint32_t) -1)
2344 c = message_get_container(m);
2345 if (c->signature && c->signature[c->index]) {
2346 /* Container signature is already set */
2348 if (c->signature[c->index] != SD_BUS_TYPE_STRING)
2353 /* Maybe we can append to the signature? But only if this is the top-level container*/
2354 if (c->enclosing != 0)
2357 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRING), NULL);
2364 a = message_extend_body(m, 4, 4);
2368 *(uint32_t*) a = size - 1;
2370 part = message_append_part(m);
2374 part->memfd = copy_fd;
2375 part->sealed = true;
2379 message_extend_containers(m, size);
2380 m->header->body_size += size;
2382 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2388 int sd_bus_message_append_strv(sd_bus_message *m, char **l) {
2392 assert_return(m, -EINVAL);
2393 assert_return(!m->sealed, -EPERM);
2394 assert_return(!m->poisoned, -ESTALE);
2396 r = sd_bus_message_open_container(m, 'a', "s");
2400 STRV_FOREACH(i, l) {
2401 r = sd_bus_message_append_basic(m, 's', *i);
2406 return sd_bus_message_close_container(m);
2409 int bus_body_part_map(struct bus_body_part *part) {
2418 if (part->size <= 0)
2421 /* For smaller zero parts (as used for padding) we don't need to map anything... */
2422 if (part->memfd < 0 && part->is_zero && part->size < 8) {
2423 static const uint8_t zeroes[7] = { };
2424 part->data = (void*) zeroes;
2428 psz = PAGE_ALIGN(part->size);
2430 if (part->memfd >= 0)
2431 p = mmap(NULL, psz, PROT_READ, MAP_SHARED, part->memfd, 0);
2432 else if (part->is_zero)
2433 p = mmap(NULL, psz, PROT_READ, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
2437 if (p == MAP_FAILED)
2442 part->munmap_this = true;
2447 void bus_body_part_unmap(struct bus_body_part *part) {
2451 if (part->memfd < 0)
2457 if (!part->munmap_this)
2460 assert_se(munmap(part->data, part->mapped) == 0);
2464 part->munmap_this = false;
2469 static int buffer_peek(const void *p, uint32_t sz, size_t *rindex, size_t align, size_t nbytes, void **r) {
2470 size_t k, start, end;
2475 start = ALIGN_TO((size_t) *rindex, align);
2476 end = start + nbytes;
2481 /* Verify that padding is 0 */
2482 for (k = *rindex; k < start; k++)
2483 if (((const uint8_t*) p)[k] != 0)
2487 *r = (uint8_t*) p + start;
2494 static bool message_end_of_array(sd_bus_message *m, size_t index) {
2495 struct bus_container *c;
2499 c = message_get_container(m);
2503 return index >= c->begin + BUS_MESSAGE_BSWAP32(m, *c->array_size);
2506 static struct bus_body_part* find_part(sd_bus_message *m, size_t index, size_t sz, void **p) {
2507 struct bus_body_part *part;
2513 if (m->cached_rindex_part && index >= m->cached_rindex_part_begin) {
2514 part = m->cached_rindex_part;
2515 begin = m->cached_rindex_part_begin;
2525 if (index + sz <= begin + part->size) {
2527 r = bus_body_part_map(part);
2532 *p = (uint8_t*) part->data + index - begin;
2534 m->cached_rindex_part = part;
2535 m->cached_rindex_part_begin = begin;
2540 begin += part->size;
2547 static int message_peek_body(
2554 size_t k, start, end, padding;
2555 struct bus_body_part *part;
2562 if (message_end_of_array(m, *rindex))
2565 start = ALIGN_TO((size_t) *rindex, align);
2566 padding = start - *rindex;
2567 end = start + nbytes;
2569 if (end > BUS_MESSAGE_BODY_SIZE(m))
2572 part = find_part(m, *rindex, padding, (void**) &q);
2577 /* Verify padding */
2578 for (k = 0; k < padding; k++)
2583 part = find_part(m, start, nbytes, (void**) &q);
2595 static bool validate_nul(const char *s, size_t l) {
2597 /* Check for NUL chars in the string */
2598 if (memchr(s, 0, l))
2601 /* Check for NUL termination */
2608 static bool validate_string(const char *s, size_t l) {
2610 if (!validate_nul(s, l))
2613 /* Check if valid UTF8 */
2614 if (!utf8_is_valid(s))
2620 static bool validate_signature(const char *s, size_t l) {
2622 if (!validate_nul(s, l))
2625 /* Check if valid signature */
2626 if (!signature_is_valid(s, true))
2632 static bool validate_object_path(const char *s, size_t l) {
2634 if (!validate_nul(s, l))
2637 if (!object_path_is_valid(s))
2643 int sd_bus_message_read_basic(sd_bus_message *m, char type, void *p) {
2644 struct bus_container *c;
2652 if (!bus_type_is_basic(type))
2655 c = message_get_container(m);
2657 if (!c->signature || c->signature[c->index] == 0)
2660 if (message_end_of_array(m, m->rindex))
2663 if (c->signature[c->index] != type)
2668 case SD_BUS_TYPE_STRING:
2669 case SD_BUS_TYPE_OBJECT_PATH: {
2674 r = message_peek_body(m, &rindex, 4, 4, &q);
2678 l = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2679 r = message_peek_body(m, &rindex, 1, l+1, &q);
2685 if (type == SD_BUS_TYPE_OBJECT_PATH) {
2686 if (!validate_object_path(q, l))
2689 if (!validate_string(q, l))
2695 *(const char**) p = q;
2700 case SD_BUS_TYPE_SIGNATURE: {
2705 r = message_peek_body(m, &rindex, 1, 1, &q);
2710 r = message_peek_body(m, &rindex, 1, l+1, &q);
2716 if (!validate_signature(q, l))
2722 *(const char**) p = q;
2730 align = bus_type_get_alignment(type);
2731 sz = bus_type_get_size(type);
2732 assert(align > 0 && sz > 0);
2735 r = message_peek_body(m, &rindex, align, sz, &q);
2741 case SD_BUS_TYPE_BYTE:
2743 *(uint8_t*) p = *(uint8_t*) q;
2746 case SD_BUS_TYPE_BOOLEAN:
2748 *(unsigned*) p = !!*(uint32_t*) q;
2751 case SD_BUS_TYPE_INT16:
2752 case SD_BUS_TYPE_UINT16:
2754 *(uint16_t*) p = BUS_MESSAGE_BSWAP16(m, *(uint16_t*) q);
2757 case SD_BUS_TYPE_INT32:
2758 case SD_BUS_TYPE_UINT32:
2760 *(uint32_t*) p = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2763 case SD_BUS_TYPE_INT64:
2764 case SD_BUS_TYPE_UINT64:
2765 case SD_BUS_TYPE_DOUBLE:
2767 *(uint64_t*) p = BUS_MESSAGE_BSWAP64(m, *(uint64_t*) q);
2770 case SD_BUS_TYPE_UNIX_FD: {
2773 j = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2778 *(int*) p = m->fds[j];
2783 assert_not_reached("Unknown basic type...");
2792 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2798 static int bus_message_enter_array(
2800 struct bus_container *c,
2801 const char *contents,
2802 uint32_t **array_size) {
2813 if (!signature_is_single(contents, true))
2816 alignment = bus_type_get_alignment(contents[0]);
2820 if (!c->signature || c->signature[c->index] == 0)
2823 if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
2826 if (!startswith(c->signature + c->index + 1, contents))
2830 r = message_peek_body(m, &rindex, 4, 4, &q);
2834 if (BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q) > BUS_ARRAY_MAX_SIZE)
2837 r = message_peek_body(m, &rindex, alignment, 0, NULL);
2843 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2844 c->index += 1 + strlen(contents);
2848 *array_size = (uint32_t*) q;
2853 static int bus_message_enter_variant(
2855 struct bus_container *c,
2856 const char *contents) {
2867 if (!signature_is_single(contents, false))
2870 if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
2873 if (!c->signature || c->signature[c->index] == 0)
2876 if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
2880 r = message_peek_body(m, &rindex, 1, 1, &q);
2885 r = message_peek_body(m, &rindex, 1, l+1, &q);
2891 if (!validate_signature(q, l))
2894 if (!streq(q, contents))
2897 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2905 static int bus_message_enter_struct(
2907 struct bus_container *c,
2908 const char *contents) {
2917 if (!signature_is_valid(contents, false))
2920 if (!c->signature || c->signature[c->index] == 0)
2923 l = strlen(contents);
2925 if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
2926 !startswith(c->signature + c->index + 1, contents) ||
2927 c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
2930 r = message_peek_body(m, &m->rindex, 8, 0, NULL);
2934 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2935 c->index += 1 + l + 1;
2940 static int bus_message_enter_dict_entry(
2942 struct bus_container *c,
2943 const char *contents) {
2952 if (!signature_is_pair(contents))
2955 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2958 if (!c->signature || c->signature[c->index] == 0)
2961 l = strlen(contents);
2963 if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
2964 !startswith(c->signature + c->index + 1, contents) ||
2965 c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
2968 r = message_peek_body(m, &m->rindex, 8, 0, NULL);
2972 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2973 c->index += 1 + l + 1;
2978 int sd_bus_message_enter_container(sd_bus_message *m, char type, const char *contents) {
2979 struct bus_container *c, *w;
2980 uint32_t *array_size = NULL;
2985 assert_return(m, -EINVAL);
2986 assert_return(m->sealed, -EPERM);
2987 assert_return(type != 0 || !contents, -EINVAL);
2989 if (type == 0 || !contents) {
2993 /* Allow entering into anonymous containers */
2994 r = sd_bus_message_peek_type(m, &tt, &cc);
2998 if (type != 0 && type != tt)
3001 if (contents && !streq(contents, cc))
3009 * We enforce a global limit on container depth, that is much
3010 * higher than the 32 structs and 32 arrays the specification
3011 * mandates. This is simpler to implement for us, and we need
3012 * this only to ensure our container array doesn't grow
3013 * without bounds. We are happy to return any data from a
3014 * message as long as the data itself is valid, even if the
3015 * overall message might be not.
3017 * Note that the message signature is validated when
3018 * parsing the headers, and that validation does check the
3021 * Note that the specification defines no limits on the depth
3022 * of stacked variants, but we do.
3024 if (m->n_containers >= BUS_CONTAINER_DEPTH)
3027 w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
3032 c = message_get_container(m);
3034 if (!c->signature || c->signature[c->index] == 0)
3037 if (message_end_of_array(m, m->rindex))
3040 signature = strdup(contents);
3044 c->saved_index = c->index;
3047 if (type == SD_BUS_TYPE_ARRAY)
3048 r = bus_message_enter_array(m, c, contents, &array_size);
3049 else if (type == SD_BUS_TYPE_VARIANT)
3050 r = bus_message_enter_variant(m, c, contents);
3051 else if (type == SD_BUS_TYPE_STRUCT)
3052 r = bus_message_enter_struct(m, c, contents);
3053 else if (type == SD_BUS_TYPE_DICT_ENTRY)
3054 r = bus_message_enter_dict_entry(m, c, contents);
3063 /* OK, let's fill it in */
3064 w += m->n_containers++;
3065 w->enclosing = type;
3066 w->signature = signature;
3068 w->array_size = array_size;
3070 w->begin = m->rindex;
3075 int sd_bus_message_exit_container(sd_bus_message *m) {
3076 struct bus_container *c;
3082 if (m->n_containers <= 0)
3085 c = message_get_container(m);
3086 if (c->enclosing == SD_BUS_TYPE_ARRAY) {
3089 l = BUS_MESSAGE_BSWAP32(m, *c->array_size);
3090 if (c->begin + l != m->rindex)
3094 if (c->signature && c->signature[c->index] != 0)
3104 static void message_quit_container(sd_bus_message *m) {
3105 struct bus_container *c;
3109 assert(m->n_containers > 0);
3111 c = message_get_container(m);
3114 assert(m->rindex >= c->before);
3115 m->rindex = c->before;
3117 /* Free container */
3121 /* Correct index of new top-level container */
3122 c = message_get_container(m);
3123 c->index = c->saved_index;
3126 int sd_bus_message_peek_type(sd_bus_message *m, char *type, const char **contents) {
3127 struct bus_container *c;
3130 assert_return(m, -EINVAL);
3131 assert_return(m->sealed, -EPERM);
3133 c = message_get_container(m);
3135 if (!c->signature || c->signature[c->index] == 0)
3138 if (message_end_of_array(m, m->rindex))
3141 if (bus_type_is_basic(c->signature[c->index])) {
3145 *type = c->signature[c->index];
3149 if (c->signature[c->index] == SD_BUS_TYPE_ARRAY) {
3155 r = signature_element_length(c->signature+c->index+1, &l);
3161 sig = strndup(c->signature + c->index + 1, l);
3165 free(m->peeked_signature);
3166 m->peeked_signature = sig;
3172 *type = SD_BUS_TYPE_ARRAY;
3177 if (c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ||
3178 c->signature[c->index] == SD_BUS_TYPE_DICT_ENTRY_BEGIN) {
3184 r = signature_element_length(c->signature+c->index, &l);
3189 sig = strndup(c->signature + c->index + 1, l - 2);
3193 free(m->peeked_signature);
3194 m->peeked_signature = sig;
3200 *type = c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY;
3205 if (c->signature[c->index] == SD_BUS_TYPE_VARIANT) {
3211 r = message_peek_body(m, &rindex, 1, 1, &q);
3218 r = message_peek_body(m, &rindex, 1, l+1, &q);
3224 if (!validate_signature(q, l))
3231 *type = SD_BUS_TYPE_VARIANT;
3240 *type = c->enclosing;
3246 int sd_bus_message_rewind(sd_bus_message *m, int complete) {
3247 struct bus_container *c;
3255 message_reset_containers(m);
3257 m->root_container.index = 0;
3259 c = message_get_container(m);
3261 c = message_get_container(m);
3264 m->rindex = c->begin;
3267 return !isempty(c->signature);
3269 static int message_read_ap(
3274 unsigned n_array, n_struct;
3275 TypeStack stack[BUS_CONTAINER_DEPTH];
3276 unsigned stack_ptr = 0;
3277 unsigned n_loop = 0;
3285 /* Ideally, we'd just call ourselves recursively on every
3286 * complex type. However, the state of a va_list that is
3287 * passed to a function is undefined after that function
3288 * returns. This means we need to docode the va_list linearly
3289 * in a single stackframe. We hence implement our own
3290 * home-grown stack in an array. */
3292 n_array = (unsigned) -1; /* lenght of current array entries */
3293 n_struct = strlen(types); /* length of current struct contents signature */
3300 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
3301 r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
3307 r = sd_bus_message_exit_container(m);
3315 if (n_array != (unsigned) -1)
3324 case SD_BUS_TYPE_BYTE:
3325 case SD_BUS_TYPE_BOOLEAN:
3326 case SD_BUS_TYPE_INT16:
3327 case SD_BUS_TYPE_UINT16:
3328 case SD_BUS_TYPE_INT32:
3329 case SD_BUS_TYPE_UINT32:
3330 case SD_BUS_TYPE_INT64:
3331 case SD_BUS_TYPE_UINT64:
3332 case SD_BUS_TYPE_DOUBLE:
3333 case SD_BUS_TYPE_STRING:
3334 case SD_BUS_TYPE_OBJECT_PATH:
3335 case SD_BUS_TYPE_SIGNATURE:
3336 case SD_BUS_TYPE_UNIX_FD: {
3339 p = va_arg(ap, void*);
3340 r = sd_bus_message_read_basic(m, *t, p);
3353 case SD_BUS_TYPE_ARRAY: {
3356 r = signature_element_length(t + 1, &k);
3362 memcpy(s, t + 1, k);
3365 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, s);
3376 if (n_array == (unsigned) -1) {
3381 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
3387 n_array = va_arg(ap, unsigned);
3392 case SD_BUS_TYPE_VARIANT: {
3395 s = va_arg(ap, const char *);
3399 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, s);
3409 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
3414 n_struct = strlen(s);
3415 n_array = (unsigned) -1;
3420 case SD_BUS_TYPE_STRUCT_BEGIN:
3421 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
3424 r = signature_element_length(t, &k);
3430 memcpy(s, t + 1, k - 2);
3433 r = sd_bus_message_enter_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
3443 if (n_array == (unsigned) -1) {
3448 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
3454 n_array = (unsigned) -1;
3467 int sd_bus_message_read(sd_bus_message *m, const char *types, ...) {
3471 assert_return(m, -EINVAL);
3472 assert_return(m->sealed, -EPERM);
3473 assert_return(types, -EINVAL);
3475 va_start(ap, types);
3476 r = message_read_ap(m, types, ap);
3482 int sd_bus_message_skip(sd_bus_message *m, const char *types) {
3485 assert_return(m, -EINVAL);
3486 assert_return(m->sealed, -EPERM);
3487 assert_return(types, -EINVAL);
3494 case SD_BUS_TYPE_BYTE:
3495 case SD_BUS_TYPE_BOOLEAN:
3496 case SD_BUS_TYPE_INT16:
3497 case SD_BUS_TYPE_UINT16:
3498 case SD_BUS_TYPE_INT32:
3499 case SD_BUS_TYPE_UINT32:
3500 case SD_BUS_TYPE_INT64:
3501 case SD_BUS_TYPE_UINT64:
3502 case SD_BUS_TYPE_DOUBLE:
3503 case SD_BUS_TYPE_STRING:
3504 case SD_BUS_TYPE_OBJECT_PATH:
3505 case SD_BUS_TYPE_SIGNATURE:
3506 case SD_BUS_TYPE_UNIX_FD:
3508 r = sd_bus_message_read_basic(m, *types, NULL);
3512 r = sd_bus_message_skip(m, types + 1);
3518 case SD_BUS_TYPE_ARRAY: {
3521 r = signature_element_length(types + 1, &k);
3527 memcpy(s, types+1, k);
3530 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, s);
3535 r = sd_bus_message_skip(m, s);
3542 r = sd_bus_message_exit_container(m);
3547 r = sd_bus_message_skip(m, types + 1 + k);
3554 case SD_BUS_TYPE_VARIANT: {
3555 const char *contents;
3558 r = sd_bus_message_peek_type(m, &x, &contents);
3562 if (x != SD_BUS_TYPE_VARIANT)
3565 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, contents);
3569 r = sd_bus_message_skip(m, contents);
3574 r = sd_bus_message_exit_container(m);
3578 r = sd_bus_message_skip(m, types + 1);
3585 case SD_BUS_TYPE_STRUCT_BEGIN:
3586 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
3589 r = signature_element_length(types, &k);
3595 memcpy(s, types+1, k-2);
3598 r = sd_bus_message_enter_container(m, *types == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
3602 r = sd_bus_message_skip(m, s);
3607 r = sd_bus_message_exit_container(m);
3612 r = sd_bus_message_skip(m, types + k);
3624 int sd_bus_message_read_array(sd_bus_message *m, char type, const void **ptr, size_t *size) {
3625 struct bus_container *c;
3635 if (!bus_type_is_trivial(type))
3641 if (BUS_MESSAGE_NEED_BSWAP(m))
3644 align = bus_type_get_alignment(type);
3648 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
3652 c = message_get_container(m);
3653 sz = BUS_MESSAGE_BSWAP32(m, *c->array_size);
3655 r = message_peek_body(m, &m->rindex, align, sz, &p);
3663 r = sd_bus_message_exit_container(m);
3667 *ptr = (const void*) p;
3673 message_quit_container(m);
3677 static int message_peek_fields(
3688 return buffer_peek(BUS_MESSAGE_FIELDS(m), BUS_MESSAGE_FIELDS_SIZE(m), rindex, align, nbytes, ret);
3691 static int message_peek_field_uint32(
3702 r = message_peek_fields(m, ri, 4, 4, &q);
3707 *ret = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
3712 static int message_peek_field_string(
3714 bool (*validate)(const char *p),
3725 r = message_peek_field_uint32(m, ri, &l);
3729 r = message_peek_fields(m, ri, 1, l+1, &q);
3734 if (!validate_nul(q, l))
3740 if (!validate_string(q, l))
3750 static int message_peek_field_signature(
3762 r = message_peek_fields(m, ri, 1, 1, &q);
3767 r = message_peek_fields(m, ri, 1, l+1, &q);
3771 if (!validate_signature(q, l))
3780 static int message_skip_fields(
3783 uint32_t array_size,
3784 const char **signature) {
3786 size_t original_index;
3793 original_index = *ri;
3799 if (array_size != (uint32_t) -1 &&
3800 array_size <= *ri - original_index)
3807 if (t == SD_BUS_TYPE_STRING) {
3809 r = message_peek_field_string(m, NULL, ri, NULL);
3815 } else if (t == SD_BUS_TYPE_OBJECT_PATH) {
3817 r = message_peek_field_string(m, object_path_is_valid, ri, NULL);
3823 } else if (t == SD_BUS_TYPE_SIGNATURE) {
3825 r = message_peek_field_signature(m, ri, NULL);
3831 } else if (bus_type_is_basic(t)) {
3834 align = bus_type_get_alignment(t);
3835 k = bus_type_get_size(t);
3836 assert(align > 0 && k > 0);
3838 r = message_peek_fields(m, ri, align, k, NULL);
3844 } else if (t == SD_BUS_TYPE_ARRAY) {
3846 r = signature_element_length(*signature+1, &l);
3856 strncpy(sig, *signature + 1, l-1);
3859 alignment = bus_type_get_alignment(sig[0]);
3863 r = message_peek_field_uint32(m, ri, &nas);
3866 if (nas > BUS_ARRAY_MAX_SIZE)
3869 r = message_peek_fields(m, ri, alignment, 0, NULL);
3873 r = message_skip_fields(m, ri, nas, (const char**) &s);
3878 (*signature) += 1 + l;
3880 } else if (t == SD_BUS_TYPE_VARIANT) {
3883 r = message_peek_field_signature(m, ri, &s);
3887 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
3893 } else if (t == SD_BUS_TYPE_STRUCT ||
3894 t == SD_BUS_TYPE_DICT_ENTRY) {
3896 r = signature_element_length(*signature, &l);
3903 strncpy(sig, *signature + 1, l-1);
3906 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
3917 int bus_message_parse_fields(sd_bus_message *m) {
3920 uint32_t unix_fds = 0;
3924 for (ri = 0; ri < BUS_MESSAGE_FIELDS_SIZE(m); ) {
3925 const char *signature;
3928 r = message_peek_fields(m, &ri, 8, 1, (void**) &header);
3932 r = message_peek_field_signature(m, &ri, &signature);
3937 case _SD_BUS_MESSAGE_HEADER_INVALID:
3940 case SD_BUS_MESSAGE_HEADER_PATH:
3945 if (!streq(signature, "o"))
3948 r = message_peek_field_string(m, object_path_is_valid, &ri, &m->path);
3951 case SD_BUS_MESSAGE_HEADER_INTERFACE:
3956 if (!streq(signature, "s"))
3959 r = message_peek_field_string(m, interface_name_is_valid, &ri, &m->interface);
3962 case SD_BUS_MESSAGE_HEADER_MEMBER:
3967 if (!streq(signature, "s"))
3970 r = message_peek_field_string(m, member_name_is_valid, &ri, &m->member);
3973 case SD_BUS_MESSAGE_HEADER_ERROR_NAME:
3978 if (!streq(signature, "s"))
3981 r = message_peek_field_string(m, error_name_is_valid, &ri, &m->error.name);
3984 case SD_BUS_MESSAGE_HEADER_DESTINATION:
3989 if (!streq(signature, "s"))
3992 r = message_peek_field_string(m, service_name_is_valid, &ri, &m->destination);
3995 case SD_BUS_MESSAGE_HEADER_SENDER:
4000 if (!streq(signature, "s"))
4003 r = message_peek_field_string(m, service_name_is_valid, &ri, &m->sender);
4007 case SD_BUS_MESSAGE_HEADER_SIGNATURE: {
4011 if (m->root_container.signature)
4014 if (!streq(signature, "g"))
4017 r = message_peek_field_signature(m, &ri, &s);
4025 free(m->root_container.signature);
4026 m->root_container.signature = c;
4030 case SD_BUS_MESSAGE_HEADER_REPLY_SERIAL:
4031 if (m->reply_serial != 0)
4034 if (!streq(signature, "u"))
4037 r = message_peek_field_uint32(m, &ri, &m->reply_serial);
4041 if (m->reply_serial == 0)
4046 case SD_BUS_MESSAGE_HEADER_UNIX_FDS:
4050 if (!streq(signature, "u"))
4053 r = message_peek_field_uint32(m, &ri, &unix_fds);
4063 r = message_skip_fields(m, &ri, (uint32_t) -1, (const char **) &signature);
4070 if (m->n_fds != unix_fds)
4073 if (isempty(m->root_container.signature) != (BUS_MESSAGE_BODY_SIZE(m) == 0))
4076 switch (m->header->type) {
4078 case SD_BUS_MESSAGE_SIGNAL:
4079 if (!m->path || !m->interface || !m->member)
4083 case SD_BUS_MESSAGE_METHOD_CALL:
4085 if (!m->path || !m->member)
4090 case SD_BUS_MESSAGE_METHOD_RETURN:
4092 if (m->reply_serial == 0)
4096 case SD_BUS_MESSAGE_METHOD_ERROR:
4098 if (m->reply_serial == 0 || !m->error.name)
4103 /* Try to read the error message, but if we can't it's a non-issue */
4104 if (m->header->type == SD_BUS_MESSAGE_METHOD_ERROR)
4105 sd_bus_message_read(m, "s", &m->error.message);
4110 int bus_message_seal(sd_bus_message *m, uint64_t serial) {
4111 struct bus_body_part *part;
4121 if (m->n_containers > 0)
4127 /* If there's a non-trivial signature set, then add it in here */
4128 if (!isempty(m->root_container.signature)) {
4129 r = message_append_field_signature(m, SD_BUS_MESSAGE_HEADER_SIGNATURE, m->root_container.signature, NULL);
4135 r = message_append_field_uint32(m, SD_BUS_MESSAGE_HEADER_UNIX_FDS, m->n_fds);
4140 /* Add padding at the end of the fields part, since we know
4141 * the body needs to start at an 8 byte alignment. We made
4142 * sure we allocated enough space for this, so all we need to
4143 * do here is to zero it out. */
4144 l = BUS_MESSAGE_FIELDS_SIZE(m);
4147 memset((uint8_t*) BUS_MESSAGE_FIELDS(m) + l, 0, a);
4149 /* If this is something we can send as memfd, then let's seal
4150 the memfd now. Note that we can send memfds as payload only
4151 for directed messages, and not for broadcasts. */
4152 if (m->destination && m->bus && m->bus->use_memfd) {
4153 MESSAGE_FOREACH_PART(part, i, m)
4154 if (part->memfd >= 0 && !part->sealed && (part->size > MEMFD_MIN_SIZE || m->bus->use_memfd < 0)) {
4155 bus_body_part_unmap(part);
4157 if (ioctl(part->memfd, KDBUS_CMD_MEMFD_SEAL_SET, 1) >= 0)
4158 part->sealed = true;
4162 m->header->serial = serial;
4168 int sd_bus_message_set_destination(sd_bus_message *m, const char *destination) {
4178 return message_append_field_string(m, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &m->destination);
4181 int bus_message_dump(sd_bus_message *m, FILE *f, bool with_header) {
4182 const char *u = NULL, *uu = NULL, *s = NULL;
4183 char **cmdline = NULL;
4186 uid_t owner, audit_loginuid;
4187 uint32_t audit_sessionid;
4203 "\tfields_size=%u\n"
4208 "\tdestination=%s\n"
4211 "\treply_serial=%u\n"
4213 "\tn_body_parts=%u\n",
4220 BUS_MESSAGE_SERIAL(m),
4221 BUS_MESSAGE_FIELDS_SIZE(m),
4222 BUS_MESSAGE_BODY_SIZE(m),
4224 strna(m->interface),
4226 strna(m->destination),
4228 strna(m->root_container.signature),
4233 if (sd_bus_error_is_set(&m->error))
4236 "\terror.message=%s\n",
4237 strna(m->error.name),
4238 strna(m->error.message));
4241 fprintf(f, "\tpid=%lu\n", (unsigned long) m->pid);
4243 fprintf(f, "\ttid=%lu\n", (unsigned long) m->tid);
4245 fprintf(f, "\tuid=%lu\n", (unsigned long) m->uid);
4247 fprintf(f, "\tgid=%lu\n", (unsigned long) m->gid);
4248 if (m->pid_starttime != 0)
4249 fprintf(f, "\tpid_starttime=%llu\n", (unsigned long long) m->pid_starttime);
4250 if (m->monotonic != 0)
4251 fprintf(f, "\tmonotonic=%llu\n", (unsigned long long) m->monotonic);
4252 if (m->realtime != 0)
4253 fprintf(f, "\trealtime=%llu\n", (unsigned long long) m->realtime);
4255 fprintf(f, "\texe=[%s]\n", m->exe);
4257 fprintf(f, "\tcomm=[%s]\n", m->comm);
4259 fprintf(f, "\ttid_comm=[%s]\n", m->tid_comm);
4261 fprintf(f, "\tlabel=[%s]\n", m->label);
4263 fprintf(f, "\tcgroup=[%s]\n", m->cgroup);
4265 sd_bus_message_get_unit(m, &u);
4267 fprintf(f, "\tunit=[%s]\n", u);
4268 sd_bus_message_get_user_unit(m, &uu);
4270 fprintf(f, "\tuser_unit=[%s]\n", uu);
4271 sd_bus_message_get_session(m, &s);
4273 fprintf(f, "\tsession=[%s]\n", s);
4274 if (sd_bus_message_get_owner_uid(m, &owner) >= 0)
4275 fprintf(f, "\towner_uid=%lu\n", (unsigned long) owner);
4276 if (sd_bus_message_get_audit_loginuid(m, &audit_loginuid) >= 0)
4277 fprintf(f, "\taudit_loginuid=%lu\n", (unsigned long) audit_loginuid);
4278 if (sd_bus_message_get_audit_sessionid(m, &audit_sessionid) >= 0)
4279 fprintf(f, "\taudit_sessionid=%lu\n", (unsigned long) audit_sessionid);
4281 r = sd_bus_message_has_effective_cap(m, 5);
4283 fprintf(f, "\tCAP_KILL=%s\n", yes_no(r));
4285 if (sd_bus_message_get_cmdline(m, &cmdline) >= 0) {
4288 fputs("\tcmdline=[", f);
4289 STRV_FOREACH(c, cmdline) {
4300 r = sd_bus_message_rewind(m, true);
4302 log_error("Failed to rewind: %s", strerror(-r));
4306 fprintf(f, "BEGIN_MESSAGE \"%s\" {\n", strempty(m->root_container.signature));
4309 _cleanup_free_ char *prefix = NULL;
4310 const char *contents = NULL;
4325 r = sd_bus_message_peek_type(m, &type, &contents);
4327 log_error("Failed to peek type: %s", strerror(-r));
4334 r = sd_bus_message_exit_container(m);
4336 log_error("Failed to exit container: %s", strerror(-r));
4342 prefix = strrep("\t", level);
4346 if (type == SD_BUS_TYPE_ARRAY)
4347 fprintf(f, "%s} END_ARRAY \n", prefix);
4348 else if (type == SD_BUS_TYPE_VARIANT)
4349 fprintf(f, "%s} END_VARIANT\n", prefix);
4350 else if (type == SD_BUS_TYPE_STRUCT)
4351 fprintf(f, "%s} END_STRUCT\n", prefix);
4352 else if (type == SD_BUS_TYPE_DICT_ENTRY)
4353 fprintf(f, "%s} END_DICT_ENTRY\n", prefix);
4358 prefix = strrep("\t", level);
4362 if (bus_type_is_container(type) > 0) {
4363 r = sd_bus_message_enter_container(m, type, contents);
4365 log_error("Failed to enter container: %s", strerror(-r));
4369 if (type == SD_BUS_TYPE_ARRAY)
4370 fprintf(f, "%sBEGIN_ARRAY \"%s\" {\n", prefix, contents);
4371 else if (type == SD_BUS_TYPE_VARIANT)
4372 fprintf(f, "%sBEGIN_VARIANT \"%s\" {\n", prefix, contents);
4373 else if (type == SD_BUS_TYPE_STRUCT)
4374 fprintf(f, "%sBEGIN_STRUCT \"%s\" {\n", prefix, contents);
4375 else if (type == SD_BUS_TYPE_DICT_ENTRY)
4376 fprintf(f, "%sBEGIN_DICT_ENTRY \"%s\" {\n", prefix, contents);
4383 r = sd_bus_message_read_basic(m, type, &basic);
4385 log_error("Failed to get basic: %s", strerror(-r));
4393 case SD_BUS_TYPE_BYTE:
4394 fprintf(f, "%sBYTE: %u\n", prefix, basic.u8);
4397 case SD_BUS_TYPE_BOOLEAN:
4398 fprintf(f, "%sBOOLEAN: %s\n", prefix, yes_no(basic.i));
4401 case SD_BUS_TYPE_INT16:
4402 fprintf(f, "%sINT16: %i\n", prefix, basic.s16);
4405 case SD_BUS_TYPE_UINT16:
4406 fprintf(f, "%sUINT16: %u\n", prefix, basic.u16);
4409 case SD_BUS_TYPE_INT32:
4410 fprintf(f, "%sINT32: %i\n", prefix, basic.s32);
4413 case SD_BUS_TYPE_UINT32:
4414 fprintf(f, "%sUINT32: %u\n", prefix, basic.u32);
4417 case SD_BUS_TYPE_INT64:
4418 fprintf(f, "%sINT64: %lli\n", prefix, (long long) basic.s64);
4421 case SD_BUS_TYPE_UINT64:
4422 fprintf(f, "%sUINT64: %llu\n", prefix, (unsigned long long) basic.u64);
4425 case SD_BUS_TYPE_DOUBLE:
4426 fprintf(f, "%sDOUBLE: %g\n", prefix, basic.d64);
4429 case SD_BUS_TYPE_STRING:
4430 fprintf(f, "%sSTRING: \"%s\"\n", prefix, basic.string);
4433 case SD_BUS_TYPE_OBJECT_PATH:
4434 fprintf(f, "%sOBJECT_PATH: \"%s\"\n", prefix, basic.string);
4437 case SD_BUS_TYPE_SIGNATURE:
4438 fprintf(f, "%sSIGNATURE: \"%s\"\n", prefix, basic.string);
4441 case SD_BUS_TYPE_UNIX_FD:
4442 fprintf(f, "%sUNIX_FD: %i\n", prefix, basic.i);
4446 assert_not_reached("Unknown basic type.");
4450 fprintf(f, "} END_MESSAGE\n");
4454 int bus_message_get_blob(sd_bus_message *m, void **buffer, size_t *sz) {
4458 struct bus_body_part *part;
4464 total = BUS_MESSAGE_SIZE(m);
4470 e = mempcpy(p, m->header, BUS_MESSAGE_BODY_BEGIN(m));
4471 MESSAGE_FOREACH_PART(part, i, m)
4472 e = mempcpy(e, part->data, part->size);
4474 assert(total == (size_t) ((uint8_t*) e - (uint8_t*) p));
4482 int bus_message_read_strv_extend(sd_bus_message *m, char ***l) {
4488 r = sd_bus_message_enter_container(m, 'a', "s");
4495 r = sd_bus_message_read_basic(m, 's', &s);
4501 r = strv_extend(l, s);
4506 r = sd_bus_message_exit_container(m);
4513 int sd_bus_message_read_strv(sd_bus_message *m, char ***l) {
4517 assert_return(m, -EINVAL);
4518 assert_return(m->sealed, -EPERM);
4519 assert_return(l, -EINVAL);
4521 r = bus_message_read_strv_extend(m, &strv);
4531 const char* bus_message_get_arg(sd_bus_message *m, unsigned i) {
4533 const char *t = NULL;
4538 r = sd_bus_message_rewind(m, true);
4542 for (j = 0; j <= i; j++) {
4545 r = sd_bus_message_peek_type(m, &type, NULL);
4549 if (type != SD_BUS_TYPE_STRING &&
4550 type != SD_BUS_TYPE_OBJECT_PATH &&
4551 type != SD_BUS_TYPE_SIGNATURE)
4554 r = sd_bus_message_read_basic(m, type, &t);
4562 bool bus_header_is_complete(struct bus_header *h, size_t size) {
4568 if (size < sizeof(struct bus_header))
4571 full = sizeof(struct bus_header) +
4572 (h->endian == SD_BUS_NATIVE_ENDIAN ? h->fields_size : bswap_32(h->fields_size));
4574 return size >= full;
4577 int bus_header_message_size(struct bus_header *h, size_t *sum) {
4583 if (h->endian == SD_BUS_NATIVE_ENDIAN) {
4584 fs = h->fields_size;
4586 } else if (h->endian == SD_BUS_REVERSE_ENDIAN) {
4587 fs = bswap_32(h->fields_size);
4588 bs = bswap_32(h->body_size);
4592 *sum = sizeof(struct bus_header) + ALIGN8(fs) + bs;
4596 int sd_bus_message_get_errno(sd_bus_message *m) {
4597 assert_return(m, -EINVAL);
4599 if (m->header->type != SD_BUS_MESSAGE_METHOD_ERROR)
4602 return sd_bus_error_get_errno(&m->error);
4605 const char* sd_bus_message_get_signature(sd_bus_message *m, int complete) {
4606 struct bus_container *c;
4611 c = complete ? &m->root_container : message_get_container(m);
4612 return c->signature ?: "";
4615 int sd_bus_message_copy(sd_bus_message *m, sd_bus_message *source, int all) {
4616 bool done_something = false;
4619 assert_return(m, -EINVAL);
4620 assert_return(source, -EINVAL);
4621 assert_return(!m->sealed, -EPERM);
4622 assert_return(source->sealed, -EPERM);
4625 const char *contents;
4640 r = sd_bus_message_peek_type(source, &type, &contents);
4646 done_something = true;
4648 if (bus_type_is_container(type) > 0) {
4650 r = sd_bus_message_enter_container(source, type, contents);
4654 r = sd_bus_message_open_container(m, type, contents);
4658 r = sd_bus_message_copy(m, source, true);
4662 r = sd_bus_message_close_container(m);
4666 r = sd_bus_message_exit_container(source);
4673 r = sd_bus_message_read_basic(source, type, &basic);
4679 if (type == SD_BUS_TYPE_OBJECT_PATH ||
4680 type == SD_BUS_TYPE_SIGNATURE ||
4681 type == SD_BUS_TYPE_STRING)
4682 r = sd_bus_message_append_basic(m, type, basic.string);
4684 r = sd_bus_message_append_basic(m, type, &basic);
4691 return done_something;
4694 int sd_bus_message_verify_type(sd_bus_message *m, char type, const char *contents) {
4699 assert_return(m, -EINVAL);
4700 assert_return(m->sealed, -EPERM);
4701 assert_return(!type || bus_type_is_valid(type), -EINVAL);
4702 assert_return(!contents || signature_is_valid(contents, true), -EINVAL);
4703 assert_return(type || contents, -EINVAL);
4704 assert_return(!contents || !type || bus_type_is_container(type), -EINVAL);
4706 r = sd_bus_message_peek_type(m, &t, &c);
4710 if (type != 0 && type != t)
4713 if (contents && !streq_ptr(contents, c))