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))
2657 c = message_get_container(m);
2659 if (!c->signature || c->signature[c->index] == 0)
2662 if (message_end_of_array(m, m->rindex))
2665 if (c->signature[c->index] != type)
2670 case SD_BUS_TYPE_STRING:
2671 case SD_BUS_TYPE_OBJECT_PATH: {
2676 r = message_peek_body(m, &rindex, 4, 4, &q);
2680 l = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2681 r = message_peek_body(m, &rindex, 1, l+1, &q);
2687 if (type == SD_BUS_TYPE_OBJECT_PATH) {
2688 if (!validate_object_path(q, l))
2691 if (!validate_string(q, l))
2696 *(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))
2720 *(const char**) p = q;
2728 align = bus_type_get_alignment(type);
2729 sz = bus_type_get_size(type);
2730 assert(align > 0 && sz > 0);
2733 r = message_peek_body(m, &rindex, align, sz, &q);
2739 case SD_BUS_TYPE_BYTE:
2740 *(uint8_t*) p = *(uint8_t*) q;
2743 case SD_BUS_TYPE_BOOLEAN:
2744 *(unsigned*) p = !!*(uint32_t*) q;
2747 case SD_BUS_TYPE_INT16:
2748 case SD_BUS_TYPE_UINT16:
2749 *(uint16_t*) p = BUS_MESSAGE_BSWAP16(m, *(uint16_t*) q);
2752 case SD_BUS_TYPE_INT32:
2753 case SD_BUS_TYPE_UINT32:
2754 *(uint32_t*) p = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2757 case SD_BUS_TYPE_INT64:
2758 case SD_BUS_TYPE_UINT64:
2759 case SD_BUS_TYPE_DOUBLE:
2760 *(uint64_t*) p = BUS_MESSAGE_BSWAP64(m, *(uint64_t*) q);
2763 case SD_BUS_TYPE_UNIX_FD: {
2766 j = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2770 *(int*) p = m->fds[j];
2775 assert_not_reached("Unknown basic type...");
2784 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2790 static int bus_message_enter_array(
2792 struct bus_container *c,
2793 const char *contents,
2794 uint32_t **array_size) {
2805 if (!signature_is_single(contents, true))
2808 alignment = bus_type_get_alignment(contents[0]);
2812 if (!c->signature || c->signature[c->index] == 0)
2815 if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
2818 if (!startswith(c->signature + c->index + 1, contents))
2822 r = message_peek_body(m, &rindex, 4, 4, &q);
2826 if (BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q) > BUS_ARRAY_MAX_SIZE)
2829 r = message_peek_body(m, &rindex, alignment, 0, NULL);
2835 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2836 c->index += 1 + strlen(contents);
2840 *array_size = (uint32_t*) q;
2845 static int bus_message_enter_variant(
2847 struct bus_container *c,
2848 const char *contents) {
2859 if (!signature_is_single(contents, false))
2862 if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
2865 if (!c->signature || c->signature[c->index] == 0)
2868 if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
2872 r = message_peek_body(m, &rindex, 1, 1, &q);
2877 r = message_peek_body(m, &rindex, 1, l+1, &q);
2883 if (!validate_signature(q, l))
2886 if (!streq(q, contents))
2889 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2897 static int bus_message_enter_struct(
2899 struct bus_container *c,
2900 const char *contents) {
2909 if (!signature_is_valid(contents, false))
2912 if (!c->signature || c->signature[c->index] == 0)
2915 l = strlen(contents);
2917 if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
2918 !startswith(c->signature + c->index + 1, contents) ||
2919 c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
2922 r = message_peek_body(m, &m->rindex, 8, 0, NULL);
2926 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2927 c->index += 1 + l + 1;
2932 static int bus_message_enter_dict_entry(
2934 struct bus_container *c,
2935 const char *contents) {
2944 if (!signature_is_pair(contents))
2947 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2950 if (!c->signature || c->signature[c->index] == 0)
2953 l = strlen(contents);
2955 if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
2956 !startswith(c->signature + c->index + 1, contents) ||
2957 c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
2960 r = message_peek_body(m, &m->rindex, 8, 0, NULL);
2964 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2965 c->index += 1 + l + 1;
2970 int sd_bus_message_enter_container(sd_bus_message *m, char type, const char *contents) {
2971 struct bus_container *c, *w;
2972 uint32_t *array_size = NULL;
2985 * We enforce a global limit on container depth, that is much
2986 * higher than the 32 structs and 32 arrays the specification
2987 * mandates. This is simpler to implement for us, and we need
2988 * this only to ensure our container array doesn't grow
2989 * without bounds. We are happy to return any data from a
2990 * message as long as the data itself is valid, even if the
2991 * overall message might be not.
2993 * Note that the message signature is validated when
2994 * parsing the headers, and that validation does check the
2997 * Note that the specification defines no limits on the depth
2998 * of stacked variants, but we do.
3000 if (m->n_containers >= BUS_CONTAINER_DEPTH)
3003 w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
3008 c = message_get_container(m);
3010 if (!c->signature || c->signature[c->index] == 0)
3013 if (message_end_of_array(m, m->rindex))
3016 signature = strdup(contents);
3020 c->saved_index = c->index;
3023 if (type == SD_BUS_TYPE_ARRAY)
3024 r = bus_message_enter_array(m, c, contents, &array_size);
3025 else if (type == SD_BUS_TYPE_VARIANT)
3026 r = bus_message_enter_variant(m, c, contents);
3027 else if (type == SD_BUS_TYPE_STRUCT)
3028 r = bus_message_enter_struct(m, c, contents);
3029 else if (type == SD_BUS_TYPE_DICT_ENTRY)
3030 r = bus_message_enter_dict_entry(m, c, contents);
3039 /* OK, let's fill it in */
3040 w += m->n_containers++;
3041 w->enclosing = type;
3042 w->signature = signature;
3044 w->array_size = array_size;
3046 w->begin = m->rindex;
3051 int sd_bus_message_exit_container(sd_bus_message *m) {
3052 struct bus_container *c;
3058 if (m->n_containers <= 0)
3061 c = message_get_container(m);
3062 if (c->enclosing == SD_BUS_TYPE_ARRAY) {
3065 l = BUS_MESSAGE_BSWAP32(m, *c->array_size);
3066 if (c->begin + l != m->rindex)
3070 if (c->signature && c->signature[c->index] != 0)
3080 static void message_quit_container(sd_bus_message *m) {
3081 struct bus_container *c;
3085 assert(m->n_containers > 0);
3087 c = message_get_container(m);
3090 assert(m->rindex >= c->before);
3091 m->rindex = c->before;
3093 /* Free container */
3097 /* Correct index of new top-level container */
3098 c = message_get_container(m);
3099 c->index = c->saved_index;
3102 int sd_bus_message_peek_type(sd_bus_message *m, char *type, const char **contents) {
3103 struct bus_container *c;
3111 c = message_get_container(m);
3113 if (!c->signature || c->signature[c->index] == 0)
3116 if (message_end_of_array(m, m->rindex))
3119 if (bus_type_is_basic(c->signature[c->index])) {
3123 *type = c->signature[c->index];
3127 if (c->signature[c->index] == SD_BUS_TYPE_ARRAY) {
3133 r = signature_element_length(c->signature+c->index+1, &l);
3139 sig = strndup(c->signature + c->index + 1, l);
3143 free(m->peeked_signature);
3144 m->peeked_signature = sig;
3150 *type = SD_BUS_TYPE_ARRAY;
3155 if (c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ||
3156 c->signature[c->index] == SD_BUS_TYPE_DICT_ENTRY_BEGIN) {
3162 r = signature_element_length(c->signature+c->index, &l);
3167 sig = strndup(c->signature + c->index + 1, l - 2);
3171 free(m->peeked_signature);
3172 m->peeked_signature = sig;
3178 *type = c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY;
3183 if (c->signature[c->index] == SD_BUS_TYPE_VARIANT) {
3189 r = message_peek_body(m, &rindex, 1, 1, &q);
3196 r = message_peek_body(m, &rindex, 1, l+1, &q);
3202 if (!validate_signature(q, l))
3209 *type = SD_BUS_TYPE_VARIANT;
3218 *type = c->enclosing;
3224 int sd_bus_message_rewind(sd_bus_message *m, int complete) {
3225 struct bus_container *c;
3233 message_reset_containers(m);
3235 m->root_container.index = 0;
3237 c = message_get_container(m);
3239 c = message_get_container(m);
3242 m->rindex = c->begin;
3245 return !isempty(c->signature);
3247 static int message_read_ap(
3252 unsigned n_array, n_struct;
3253 TypeStack stack[BUS_CONTAINER_DEPTH];
3254 unsigned stack_ptr = 0;
3255 unsigned n_loop = 0;
3263 /* Ideally, we'd just call ourselves recursively on every
3264 * complex type. However, the state of a va_list that is
3265 * passed to a function is undefined after that function
3266 * returns. This means we need to docode the va_list linearly
3267 * in a single stackframe. We hence implement our own
3268 * home-grown stack in an array. */
3270 n_array = (unsigned) -1; /* lenght of current array entries */
3271 n_struct = strlen(types); /* length of current struct contents signature */
3278 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
3279 r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
3285 r = sd_bus_message_exit_container(m);
3293 if (n_array != (unsigned) -1)
3302 case SD_BUS_TYPE_BYTE:
3303 case SD_BUS_TYPE_BOOLEAN:
3304 case SD_BUS_TYPE_INT16:
3305 case SD_BUS_TYPE_UINT16:
3306 case SD_BUS_TYPE_INT32:
3307 case SD_BUS_TYPE_UINT32:
3308 case SD_BUS_TYPE_INT64:
3309 case SD_BUS_TYPE_UINT64:
3310 case SD_BUS_TYPE_DOUBLE:
3311 case SD_BUS_TYPE_STRING:
3312 case SD_BUS_TYPE_OBJECT_PATH:
3313 case SD_BUS_TYPE_SIGNATURE:
3314 case SD_BUS_TYPE_UNIX_FD: {
3317 p = va_arg(ap, void*);
3318 r = sd_bus_message_read_basic(m, *t, p);
3332 case SD_BUS_TYPE_ARRAY: {
3335 r = signature_element_length(t + 1, &k);
3341 memcpy(s, t + 1, k);
3344 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, s);
3355 if (n_array == (unsigned) -1) {
3360 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
3366 n_array = va_arg(ap, unsigned);
3371 case SD_BUS_TYPE_VARIANT: {
3374 s = va_arg(ap, const char *);
3378 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, s);
3388 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
3393 n_struct = strlen(s);
3394 n_array = (unsigned) -1;
3399 case SD_BUS_TYPE_STRUCT_BEGIN:
3400 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
3403 r = signature_element_length(t, &k);
3409 memcpy(s, t + 1, k - 2);
3412 r = sd_bus_message_enter_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
3422 if (n_array == (unsigned) -1) {
3427 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
3433 n_array = (unsigned) -1;
3446 int sd_bus_message_read(sd_bus_message *m, const char *types, ...) {
3457 va_start(ap, types);
3458 r = message_read_ap(m, types, ap);
3464 int sd_bus_message_read_array(sd_bus_message *m, char type, const void **ptr, size_t *size) {
3465 struct bus_container *c;
3475 if (!bus_type_is_trivial(type))
3481 if (BUS_MESSAGE_NEED_BSWAP(m))
3484 align = bus_type_get_alignment(type);
3488 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
3492 c = message_get_container(m);
3493 sz = BUS_MESSAGE_BSWAP32(m, *c->array_size);
3495 r = message_peek_body(m, &m->rindex, align, sz, &p);
3503 r = sd_bus_message_exit_container(m);
3507 *ptr = (const void*) p;
3513 message_quit_container(m);
3517 static int message_peek_fields(
3528 return buffer_peek(BUS_MESSAGE_FIELDS(m), BUS_MESSAGE_FIELDS_SIZE(m), rindex, align, nbytes, ret);
3531 static int message_peek_field_uint32(
3542 r = message_peek_fields(m, ri, 4, 4, &q);
3547 *ret = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
3552 static int message_peek_field_string(
3554 bool (*validate)(const char *p),
3565 r = message_peek_field_uint32(m, ri, &l);
3569 r = message_peek_fields(m, ri, 1, l+1, &q);
3574 if (!validate_nul(q, l))
3580 if (!validate_string(q, l))
3590 static int message_peek_field_signature(
3602 r = message_peek_fields(m, ri, 1, 1, &q);
3607 r = message_peek_fields(m, ri, 1, l+1, &q);
3611 if (!validate_signature(q, l))
3620 static int message_skip_fields(
3623 uint32_t array_size,
3624 const char **signature) {
3626 size_t original_index;
3633 original_index = *ri;
3639 if (array_size != (uint32_t) -1 &&
3640 array_size <= *ri - original_index)
3647 if (t == SD_BUS_TYPE_STRING) {
3649 r = message_peek_field_string(m, NULL, ri, NULL);
3655 } else if (t == SD_BUS_TYPE_OBJECT_PATH) {
3657 r = message_peek_field_string(m, object_path_is_valid, ri, NULL);
3663 } else if (t == SD_BUS_TYPE_SIGNATURE) {
3665 r = message_peek_field_signature(m, ri, NULL);
3671 } else if (bus_type_is_basic(t)) {
3674 align = bus_type_get_alignment(t);
3675 k = bus_type_get_size(t);
3676 assert(align > 0 && k > 0);
3678 r = message_peek_fields(m, ri, align, k, NULL);
3684 } else if (t == SD_BUS_TYPE_ARRAY) {
3686 r = signature_element_length(*signature+1, &l);
3696 strncpy(sig, *signature + 1, l-1);
3699 alignment = bus_type_get_alignment(sig[0]);
3703 r = message_peek_field_uint32(m, ri, &nas);
3706 if (nas > BUS_ARRAY_MAX_SIZE)
3709 r = message_peek_fields(m, ri, alignment, 0, NULL);
3713 r = message_skip_fields(m, ri, nas, (const char**) &s);
3718 (*signature) += 1 + l;
3720 } else if (t == SD_BUS_TYPE_VARIANT) {
3723 r = message_peek_field_signature(m, ri, &s);
3727 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
3733 } else if (t == SD_BUS_TYPE_STRUCT ||
3734 t == SD_BUS_TYPE_DICT_ENTRY) {
3736 r = signature_element_length(*signature, &l);
3743 strncpy(sig, *signature + 1, l-1);
3746 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
3757 int bus_message_parse_fields(sd_bus_message *m) {
3760 uint32_t unix_fds = 0;
3764 for (ri = 0; ri < BUS_MESSAGE_FIELDS_SIZE(m); ) {
3765 const char *signature;
3768 r = message_peek_fields(m, &ri, 8, 1, (void**) &header);
3772 r = message_peek_field_signature(m, &ri, &signature);
3777 case _SD_BUS_MESSAGE_HEADER_INVALID:
3780 case SD_BUS_MESSAGE_HEADER_PATH:
3785 if (!streq(signature, "o"))
3788 r = message_peek_field_string(m, object_path_is_valid, &ri, &m->path);
3791 case SD_BUS_MESSAGE_HEADER_INTERFACE:
3796 if (!streq(signature, "s"))
3799 r = message_peek_field_string(m, interface_name_is_valid, &ri, &m->interface);
3802 case SD_BUS_MESSAGE_HEADER_MEMBER:
3807 if (!streq(signature, "s"))
3810 r = message_peek_field_string(m, member_name_is_valid, &ri, &m->member);
3813 case SD_BUS_MESSAGE_HEADER_ERROR_NAME:
3818 if (!streq(signature, "s"))
3821 r = message_peek_field_string(m, error_name_is_valid, &ri, &m->error.name);
3824 case SD_BUS_MESSAGE_HEADER_DESTINATION:
3829 if (!streq(signature, "s"))
3832 r = message_peek_field_string(m, service_name_is_valid, &ri, &m->destination);
3835 case SD_BUS_MESSAGE_HEADER_SENDER:
3840 if (!streq(signature, "s"))
3843 r = message_peek_field_string(m, service_name_is_valid, &ri, &m->sender);
3847 case SD_BUS_MESSAGE_HEADER_SIGNATURE: {
3851 if (m->root_container.signature)
3854 if (!streq(signature, "g"))
3857 r = message_peek_field_signature(m, &ri, &s);
3865 free(m->root_container.signature);
3866 m->root_container.signature = c;
3870 case SD_BUS_MESSAGE_HEADER_REPLY_SERIAL:
3871 if (m->reply_serial != 0)
3874 if (!streq(signature, "u"))
3877 r = message_peek_field_uint32(m, &ri, &m->reply_serial);
3881 if (m->reply_serial == 0)
3886 case SD_BUS_MESSAGE_HEADER_UNIX_FDS:
3890 if (!streq(signature, "u"))
3893 r = message_peek_field_uint32(m, &ri, &unix_fds);
3903 r = message_skip_fields(m, &ri, (uint32_t) -1, (const char **) &signature);
3910 if (m->n_fds != unix_fds)
3913 if (isempty(m->root_container.signature) != (BUS_MESSAGE_BODY_SIZE(m) == 0))
3916 switch (m->header->type) {
3918 case SD_BUS_MESSAGE_SIGNAL:
3919 if (!m->path || !m->interface || !m->member)
3923 case SD_BUS_MESSAGE_METHOD_CALL:
3925 if (!m->path || !m->member)
3930 case SD_BUS_MESSAGE_METHOD_RETURN:
3932 if (m->reply_serial == 0)
3936 case SD_BUS_MESSAGE_METHOD_ERROR:
3938 if (m->reply_serial == 0 || !m->error.name)
3943 /* Try to read the error message, but if we can't it's a non-issue */
3944 if (m->header->type == SD_BUS_MESSAGE_METHOD_ERROR)
3945 sd_bus_message_read(m, "s", &m->error.message);
3950 int bus_message_seal(sd_bus_message *m, uint64_t serial) {
3951 struct bus_body_part *part;
3961 if (m->n_containers > 0)
3967 /* If there's a non-trivial signature set, then add it in here */
3968 if (!isempty(m->root_container.signature)) {
3969 r = message_append_field_signature(m, SD_BUS_MESSAGE_HEADER_SIGNATURE, m->root_container.signature, NULL);
3975 r = message_append_field_uint32(m, SD_BUS_MESSAGE_HEADER_UNIX_FDS, m->n_fds);
3980 /* Add padding at the end of the fields part, since we know
3981 * the body needs to start at an 8 byte alignment. We made
3982 * sure we allocated enough space for this, so all we need to
3983 * do here is to zero it out. */
3984 l = BUS_MESSAGE_FIELDS_SIZE(m);
3987 memset((uint8_t*) BUS_MESSAGE_FIELDS(m) + l, 0, a);
3989 /* If this is something we can send as memfd, then let's seal
3990 the memfd now. Note that we can send memfds as payload only
3991 for directed messages, and not for broadcasts. */
3992 if (m->destination && m->bus && m->bus->use_memfd) {
3993 MESSAGE_FOREACH_PART(part, i, m)
3994 if (part->memfd >= 0 && !part->sealed && (part->size > MEMFD_MIN_SIZE || m->bus->use_memfd < 0)) {
3995 bus_body_part_unmap(part);
3997 if (ioctl(part->memfd, KDBUS_CMD_MEMFD_SEAL_SET, 1) >= 0)
3998 part->sealed = true;
4002 m->header->serial = serial;
4008 int sd_bus_message_set_destination(sd_bus_message *m, const char *destination) {
4018 return message_append_field_string(m, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &m->destination);
4021 int bus_message_dump(sd_bus_message *m) {
4022 const char *u = NULL, *uu = NULL, *s = NULL;
4023 char **cmdline = NULL;
4026 uid_t owner, audit_loginuid;
4027 uint32_t audit_sessionid;
4031 printf("Message %p\n"
4038 "\tfields_size=%u\n"
4043 "\tdestination=%s\n"
4046 "\treply_serial=%u\n"
4048 "\terror.message=%s\n"
4050 "\tn_body_parts=%u\n",
4057 BUS_MESSAGE_SERIAL(m),
4058 BUS_MESSAGE_FIELDS_SIZE(m),
4059 BUS_MESSAGE_BODY_SIZE(m),
4061 strna(m->interface),
4063 strna(m->destination),
4065 strna(m->root_container.signature),
4067 strna(m->error.name),
4068 strna(m->error.message),
4073 printf("\tpid=%lu\n", (unsigned long) m->pid);
4075 printf("\ttid=%lu\n", (unsigned long) m->tid);
4077 printf("\tuid=%lu\n", (unsigned long) m->uid);
4079 printf("\tgid=%lu\n", (unsigned long) m->gid);
4080 if (m->pid_starttime != 0)
4081 printf("\tpid_starttime=%llu\n", (unsigned long long) m->pid_starttime);
4082 if (m->monotonic != 0)
4083 printf("\tmonotonic=%llu\n", (unsigned long long) m->monotonic);
4084 if (m->realtime != 0)
4085 printf("\trealtime=%llu\n", (unsigned long long) m->realtime);
4087 printf("\texe=[%s]\n", m->exe);
4089 printf("\tcomm=[%s]\n", m->comm);
4091 printf("\ttid_comm=[%s]\n", m->tid_comm);
4093 printf("\tlabel=[%s]\n", m->label);
4095 printf("\tcgroup=[%s]\n", m->cgroup);
4097 sd_bus_message_get_unit(m, &u);
4099 printf("\tunit=[%s]\n", u);
4100 sd_bus_message_get_user_unit(m, &uu);
4102 printf("\tuser_unit=[%s]\n", uu);
4103 sd_bus_message_get_session(m, &s);
4105 printf("\tsession=[%s]\n", s);
4106 if (sd_bus_message_get_owner_uid(m, &owner) >= 0)
4107 printf("\towner_uid=%lu\n", (unsigned long) owner);
4108 if (sd_bus_message_get_audit_loginuid(m, &audit_loginuid) >= 0)
4109 printf("\taudit_loginuid=%lu\n", (unsigned long) audit_loginuid);
4110 if (sd_bus_message_get_audit_sessionid(m, &audit_sessionid) >= 0)
4111 printf("\taudit_sessionid=%lu\n", (unsigned long) audit_sessionid);
4113 printf("\tCAP_KILL=%i\n", sd_bus_message_has_effective_cap(m, 5));
4115 if (sd_bus_message_get_cmdline(m, &cmdline) >= 0) {
4118 fputs("\tcmdline=[", stdout);
4119 STRV_FOREACH(c, cmdline) {
4126 fputs("]\n", stdout);
4129 r = sd_bus_message_rewind(m, true);
4131 log_error("Failed to rewind: %s", strerror(-r));
4135 printf("BEGIN_MESSAGE \"%s\" {\n", strempty(m->root_container.signature));
4138 _cleanup_free_ char *prefix = NULL;
4139 const char *contents = NULL;
4154 r = sd_bus_message_peek_type(m, &type, &contents);
4156 log_error("Failed to peek type: %s", strerror(-r));
4163 r = sd_bus_message_exit_container(m);
4165 log_error("Failed to exit container: %s", strerror(-r));
4171 prefix = strrep("\t", level);
4175 if (type == SD_BUS_TYPE_ARRAY)
4176 printf("%s} END_ARRAY \n", prefix);
4177 else if (type == SD_BUS_TYPE_VARIANT)
4178 printf("%s} END_VARIANT\n", prefix);
4179 else if (type == SD_BUS_TYPE_STRUCT)
4180 printf("%s} END_STRUCT\n", prefix);
4181 else if (type == SD_BUS_TYPE_DICT_ENTRY)
4182 printf("%s} END_DICT_ENTRY\n", prefix);
4187 prefix = strrep("\t", level);
4191 if (bus_type_is_container(type) > 0) {
4192 r = sd_bus_message_enter_container(m, type, contents);
4194 log_error("Failed to enter container: %s", strerror(-r));
4198 if (type == SD_BUS_TYPE_ARRAY)
4199 printf("%sBEGIN_ARRAY \"%s\" {\n", prefix, contents);
4200 else if (type == SD_BUS_TYPE_VARIANT)
4201 printf("%sBEGIN_VARIANT \"%s\" {\n", prefix, contents);
4202 else if (type == SD_BUS_TYPE_STRUCT)
4203 printf("%sBEGIN_STRUCT \"%s\" {\n", prefix, contents);
4204 else if (type == SD_BUS_TYPE_DICT_ENTRY)
4205 printf("%sBEGIN_DICT_ENTRY \"%s\" {\n", prefix, contents);
4212 r = sd_bus_message_read_basic(m, type, &basic);
4214 log_error("Failed to get basic: %s", strerror(-r));
4220 case SD_BUS_TYPE_BYTE:
4221 printf("%sBYTE: %u\n", prefix, basic.u8);
4224 case SD_BUS_TYPE_BOOLEAN:
4225 printf("%sBOOLEAN: %s\n", prefix, yes_no(basic.i));
4228 case SD_BUS_TYPE_INT16:
4229 printf("%sINT16: %i\n", prefix, basic.s16);
4232 case SD_BUS_TYPE_UINT16:
4233 printf("%sUINT16: %u\n", prefix, basic.u16);
4236 case SD_BUS_TYPE_INT32:
4237 printf("%sINT32: %i\n", prefix, basic.s32);
4240 case SD_BUS_TYPE_UINT32:
4241 printf("%sUINT32: %u\n", prefix, basic.u32);
4244 case SD_BUS_TYPE_INT64:
4245 printf("%sINT64: %lli\n", prefix, (long long) basic.s64);
4248 case SD_BUS_TYPE_UINT64:
4249 printf("%sUINT64: %llu\n", prefix, (unsigned long long) basic.u64);
4252 case SD_BUS_TYPE_DOUBLE:
4253 printf("%sDOUBLE: %g\n", prefix, basic.d64);
4256 case SD_BUS_TYPE_STRING:
4257 printf("%sSTRING: \"%s\"\n", prefix, basic.string);
4260 case SD_BUS_TYPE_OBJECT_PATH:
4261 printf("%sOBJECT_PATH: \"%s\"\n", prefix, basic.string);
4264 case SD_BUS_TYPE_SIGNATURE:
4265 printf("%sSIGNATURE: \"%s\"\n", prefix, basic.string);
4268 case SD_BUS_TYPE_UNIX_FD:
4269 printf("%sUNIX_FD: %i\n", prefix, basic.i);
4273 assert_not_reached("Unknown basic type.");
4277 printf("} END_MESSAGE\n");
4281 int bus_message_get_blob(sd_bus_message *m, void **buffer, size_t *sz) {
4285 struct bus_body_part *part;
4291 total = BUS_MESSAGE_SIZE(m);
4297 e = mempcpy(p, m->header, BUS_MESSAGE_BODY_BEGIN(m));
4298 MESSAGE_FOREACH_PART(part, i, m)
4299 e = mempcpy(e, part->data, part->size);
4301 assert(total == (size_t) ((uint8_t*) e - (uint8_t*) p));
4309 int bus_message_read_strv_extend(sd_bus_message *m, char ***l) {
4315 r = sd_bus_message_enter_container(m, 'a', "s");
4322 r = sd_bus_message_read_basic(m, 's', &s);
4328 r = strv_extend(l, s);
4333 r = sd_bus_message_exit_container(m);
4340 const char* bus_message_get_arg(sd_bus_message *m, unsigned i) {
4342 const char *t = NULL;
4347 r = sd_bus_message_rewind(m, true);
4351 for (j = 0; j <= i; j++) {
4354 r = sd_bus_message_peek_type(m, &type, NULL);
4358 if (type != SD_BUS_TYPE_STRING &&
4359 type != SD_BUS_TYPE_OBJECT_PATH &&
4360 type != SD_BUS_TYPE_SIGNATURE)
4363 r = sd_bus_message_read_basic(m, type, &t);
4371 bool bus_header_is_complete(struct bus_header *h, size_t size) {
4377 if (size < sizeof(struct bus_header))
4380 full = sizeof(struct bus_header) +
4381 (h->endian == SD_BUS_NATIVE_ENDIAN ? h->fields_size : bswap_32(h->fields_size));
4383 return size >= full;
4386 int bus_header_message_size(struct bus_header *h, size_t *sum) {
4392 if (h->endian == SD_BUS_NATIVE_ENDIAN) {
4393 fs = h->fields_size;
4395 } else if (h->endian == SD_BUS_REVERSE_ENDIAN) {
4396 fs = bswap_32(h->fields_size);
4397 bs = bswap_32(h->body_size);
4401 *sum = sizeof(struct bus_header) + ALIGN8(fs) + bs;
4405 int sd_bus_message_get_errno(sd_bus_message *m) {
4406 assert_return(m, -EINVAL);
4408 if (m->header->type != SD_BUS_MESSAGE_METHOD_ERROR)
4411 return sd_bus_error_get_errno(&m->error);
4414 const char* sd_bus_message_get_signature(sd_bus_message *m, int complete) {
4415 struct bus_container *c;
4420 c = complete ? &m->root_container : message_get_container(m);
4421 return c->signature ?: "";