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;
2993 * We enforce a global limit on container depth, that is much
2994 * higher than the 32 structs and 32 arrays the specification
2995 * mandates. This is simpler to implement for us, and we need
2996 * this only to ensure our container array doesn't grow
2997 * without bounds. We are happy to return any data from a
2998 * message as long as the data itself is valid, even if the
2999 * overall message might be not.
3001 * Note that the message signature is validated when
3002 * parsing the headers, and that validation does check the
3005 * Note that the specification defines no limits on the depth
3006 * of stacked variants, but we do.
3008 if (m->n_containers >= BUS_CONTAINER_DEPTH)
3011 w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
3016 c = message_get_container(m);
3018 if (!c->signature || c->signature[c->index] == 0)
3021 if (message_end_of_array(m, m->rindex))
3024 signature = strdup(contents);
3028 c->saved_index = c->index;
3031 if (type == SD_BUS_TYPE_ARRAY)
3032 r = bus_message_enter_array(m, c, contents, &array_size);
3033 else if (type == SD_BUS_TYPE_VARIANT)
3034 r = bus_message_enter_variant(m, c, contents);
3035 else if (type == SD_BUS_TYPE_STRUCT)
3036 r = bus_message_enter_struct(m, c, contents);
3037 else if (type == SD_BUS_TYPE_DICT_ENTRY)
3038 r = bus_message_enter_dict_entry(m, c, contents);
3047 /* OK, let's fill it in */
3048 w += m->n_containers++;
3049 w->enclosing = type;
3050 w->signature = signature;
3052 w->array_size = array_size;
3054 w->begin = m->rindex;
3059 int sd_bus_message_exit_container(sd_bus_message *m) {
3060 struct bus_container *c;
3066 if (m->n_containers <= 0)
3069 c = message_get_container(m);
3070 if (c->enclosing == SD_BUS_TYPE_ARRAY) {
3073 l = BUS_MESSAGE_BSWAP32(m, *c->array_size);
3074 if (c->begin + l != m->rindex)
3078 if (c->signature && c->signature[c->index] != 0)
3088 static void message_quit_container(sd_bus_message *m) {
3089 struct bus_container *c;
3093 assert(m->n_containers > 0);
3095 c = message_get_container(m);
3098 assert(m->rindex >= c->before);
3099 m->rindex = c->before;
3101 /* Free container */
3105 /* Correct index of new top-level container */
3106 c = message_get_container(m);
3107 c->index = c->saved_index;
3110 int sd_bus_message_peek_type(sd_bus_message *m, char *type, const char **contents) {
3111 struct bus_container *c;
3114 assert_return(m, -EINVAL);
3115 assert_return(m->sealed, -EPERM);
3117 c = message_get_container(m);
3119 if (!c->signature || c->signature[c->index] == 0)
3122 if (message_end_of_array(m, m->rindex))
3125 if (bus_type_is_basic(c->signature[c->index])) {
3129 *type = c->signature[c->index];
3133 if (c->signature[c->index] == SD_BUS_TYPE_ARRAY) {
3139 r = signature_element_length(c->signature+c->index+1, &l);
3145 sig = strndup(c->signature + c->index + 1, l);
3149 free(m->peeked_signature);
3150 m->peeked_signature = sig;
3156 *type = SD_BUS_TYPE_ARRAY;
3161 if (c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ||
3162 c->signature[c->index] == SD_BUS_TYPE_DICT_ENTRY_BEGIN) {
3168 r = signature_element_length(c->signature+c->index, &l);
3173 sig = strndup(c->signature + c->index + 1, l - 2);
3177 free(m->peeked_signature);
3178 m->peeked_signature = sig;
3184 *type = c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY;
3189 if (c->signature[c->index] == SD_BUS_TYPE_VARIANT) {
3195 r = message_peek_body(m, &rindex, 1, 1, &q);
3202 r = message_peek_body(m, &rindex, 1, l+1, &q);
3208 if (!validate_signature(q, l))
3215 *type = SD_BUS_TYPE_VARIANT;
3224 *type = c->enclosing;
3230 int sd_bus_message_rewind(sd_bus_message *m, int complete) {
3231 struct bus_container *c;
3239 message_reset_containers(m);
3241 m->root_container.index = 0;
3243 c = message_get_container(m);
3245 c = message_get_container(m);
3248 m->rindex = c->begin;
3251 return !isempty(c->signature);
3253 static int message_read_ap(
3258 unsigned n_array, n_struct;
3259 TypeStack stack[BUS_CONTAINER_DEPTH];
3260 unsigned stack_ptr = 0;
3261 unsigned n_loop = 0;
3269 /* Ideally, we'd just call ourselves recursively on every
3270 * complex type. However, the state of a va_list that is
3271 * passed to a function is undefined after that function
3272 * returns. This means we need to docode the va_list linearly
3273 * in a single stackframe. We hence implement our own
3274 * home-grown stack in an array. */
3276 n_array = (unsigned) -1; /* lenght of current array entries */
3277 n_struct = strlen(types); /* length of current struct contents signature */
3284 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
3285 r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
3291 r = sd_bus_message_exit_container(m);
3299 if (n_array != (unsigned) -1)
3308 case SD_BUS_TYPE_BYTE:
3309 case SD_BUS_TYPE_BOOLEAN:
3310 case SD_BUS_TYPE_INT16:
3311 case SD_BUS_TYPE_UINT16:
3312 case SD_BUS_TYPE_INT32:
3313 case SD_BUS_TYPE_UINT32:
3314 case SD_BUS_TYPE_INT64:
3315 case SD_BUS_TYPE_UINT64:
3316 case SD_BUS_TYPE_DOUBLE:
3317 case SD_BUS_TYPE_STRING:
3318 case SD_BUS_TYPE_OBJECT_PATH:
3319 case SD_BUS_TYPE_SIGNATURE:
3320 case SD_BUS_TYPE_UNIX_FD: {
3323 p = va_arg(ap, void*);
3324 r = sd_bus_message_read_basic(m, *t, p);
3337 case SD_BUS_TYPE_ARRAY: {
3340 r = signature_element_length(t + 1, &k);
3346 memcpy(s, t + 1, k);
3349 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, s);
3360 if (n_array == (unsigned) -1) {
3365 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
3371 n_array = va_arg(ap, unsigned);
3376 case SD_BUS_TYPE_VARIANT: {
3379 s = va_arg(ap, const char *);
3383 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, s);
3393 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
3398 n_struct = strlen(s);
3399 n_array = (unsigned) -1;
3404 case SD_BUS_TYPE_STRUCT_BEGIN:
3405 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
3408 r = signature_element_length(t, &k);
3414 memcpy(s, t + 1, k - 2);
3417 r = sd_bus_message_enter_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
3427 if (n_array == (unsigned) -1) {
3432 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
3438 n_array = (unsigned) -1;
3451 int sd_bus_message_read(sd_bus_message *m, const char *types, ...) {
3455 assert_return(m, -EINVAL);
3456 assert_return(m->sealed, -EPERM);
3457 assert_return(types, -EINVAL);
3459 va_start(ap, types);
3460 r = message_read_ap(m, types, ap);
3466 int sd_bus_message_skip(sd_bus_message *m, const char *types) {
3469 assert_return(m, -EINVAL);
3470 assert_return(m->sealed, -EPERM);
3471 assert_return(types, -EINVAL);
3478 case SD_BUS_TYPE_BYTE:
3479 case SD_BUS_TYPE_BOOLEAN:
3480 case SD_BUS_TYPE_INT16:
3481 case SD_BUS_TYPE_UINT16:
3482 case SD_BUS_TYPE_INT32:
3483 case SD_BUS_TYPE_UINT32:
3484 case SD_BUS_TYPE_INT64:
3485 case SD_BUS_TYPE_UINT64:
3486 case SD_BUS_TYPE_DOUBLE:
3487 case SD_BUS_TYPE_STRING:
3488 case SD_BUS_TYPE_OBJECT_PATH:
3489 case SD_BUS_TYPE_SIGNATURE:
3490 case SD_BUS_TYPE_UNIX_FD:
3492 r = sd_bus_message_read_basic(m, *types, NULL);
3496 r = sd_bus_message_skip(m, types + 1);
3502 case SD_BUS_TYPE_ARRAY: {
3505 r = signature_element_length(types + 1, &k);
3511 memcpy(s, types+1, k);
3514 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, s);
3519 r = sd_bus_message_skip(m, s);
3526 r = sd_bus_message_exit_container(m);
3531 r = sd_bus_message_skip(m, types + 1 + k);
3538 case SD_BUS_TYPE_VARIANT: {
3539 const char *contents;
3542 r = sd_bus_message_peek_type(m, &x, &contents);
3546 if (x != SD_BUS_TYPE_VARIANT)
3549 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, contents);
3553 r = sd_bus_message_skip(m, contents);
3558 r = sd_bus_message_exit_container(m);
3562 r = sd_bus_message_skip(m, types + 1);
3569 case SD_BUS_TYPE_STRUCT_BEGIN:
3570 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
3573 r = signature_element_length(types, &k);
3579 memcpy(s, types+1, k-2);
3582 r = sd_bus_message_enter_container(m, *types == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
3586 r = sd_bus_message_skip(m, s);
3591 r = sd_bus_message_exit_container(m);
3596 r = sd_bus_message_skip(m, types + k);
3608 int sd_bus_message_read_array(sd_bus_message *m, char type, const void **ptr, size_t *size) {
3609 struct bus_container *c;
3619 if (!bus_type_is_trivial(type))
3625 if (BUS_MESSAGE_NEED_BSWAP(m))
3628 align = bus_type_get_alignment(type);
3632 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
3636 c = message_get_container(m);
3637 sz = BUS_MESSAGE_BSWAP32(m, *c->array_size);
3639 r = message_peek_body(m, &m->rindex, align, sz, &p);
3647 r = sd_bus_message_exit_container(m);
3651 *ptr = (const void*) p;
3657 message_quit_container(m);
3661 static int message_peek_fields(
3672 return buffer_peek(BUS_MESSAGE_FIELDS(m), BUS_MESSAGE_FIELDS_SIZE(m), rindex, align, nbytes, ret);
3675 static int message_peek_field_uint32(
3686 r = message_peek_fields(m, ri, 4, 4, &q);
3691 *ret = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
3696 static int message_peek_field_string(
3698 bool (*validate)(const char *p),
3709 r = message_peek_field_uint32(m, ri, &l);
3713 r = message_peek_fields(m, ri, 1, l+1, &q);
3718 if (!validate_nul(q, l))
3724 if (!validate_string(q, l))
3734 static int message_peek_field_signature(
3746 r = message_peek_fields(m, ri, 1, 1, &q);
3751 r = message_peek_fields(m, ri, 1, l+1, &q);
3755 if (!validate_signature(q, l))
3764 static int message_skip_fields(
3767 uint32_t array_size,
3768 const char **signature) {
3770 size_t original_index;
3777 original_index = *ri;
3783 if (array_size != (uint32_t) -1 &&
3784 array_size <= *ri - original_index)
3791 if (t == SD_BUS_TYPE_STRING) {
3793 r = message_peek_field_string(m, NULL, ri, NULL);
3799 } else if (t == SD_BUS_TYPE_OBJECT_PATH) {
3801 r = message_peek_field_string(m, object_path_is_valid, ri, NULL);
3807 } else if (t == SD_BUS_TYPE_SIGNATURE) {
3809 r = message_peek_field_signature(m, ri, NULL);
3815 } else if (bus_type_is_basic(t)) {
3818 align = bus_type_get_alignment(t);
3819 k = bus_type_get_size(t);
3820 assert(align > 0 && k > 0);
3822 r = message_peek_fields(m, ri, align, k, NULL);
3828 } else if (t == SD_BUS_TYPE_ARRAY) {
3830 r = signature_element_length(*signature+1, &l);
3840 strncpy(sig, *signature + 1, l-1);
3843 alignment = bus_type_get_alignment(sig[0]);
3847 r = message_peek_field_uint32(m, ri, &nas);
3850 if (nas > BUS_ARRAY_MAX_SIZE)
3853 r = message_peek_fields(m, ri, alignment, 0, NULL);
3857 r = message_skip_fields(m, ri, nas, (const char**) &s);
3862 (*signature) += 1 + l;
3864 } else if (t == SD_BUS_TYPE_VARIANT) {
3867 r = message_peek_field_signature(m, ri, &s);
3871 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
3877 } else if (t == SD_BUS_TYPE_STRUCT ||
3878 t == SD_BUS_TYPE_DICT_ENTRY) {
3880 r = signature_element_length(*signature, &l);
3887 strncpy(sig, *signature + 1, l-1);
3890 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
3901 int bus_message_parse_fields(sd_bus_message *m) {
3904 uint32_t unix_fds = 0;
3908 for (ri = 0; ri < BUS_MESSAGE_FIELDS_SIZE(m); ) {
3909 const char *signature;
3912 r = message_peek_fields(m, &ri, 8, 1, (void**) &header);
3916 r = message_peek_field_signature(m, &ri, &signature);
3921 case _SD_BUS_MESSAGE_HEADER_INVALID:
3924 case SD_BUS_MESSAGE_HEADER_PATH:
3929 if (!streq(signature, "o"))
3932 r = message_peek_field_string(m, object_path_is_valid, &ri, &m->path);
3935 case SD_BUS_MESSAGE_HEADER_INTERFACE:
3940 if (!streq(signature, "s"))
3943 r = message_peek_field_string(m, interface_name_is_valid, &ri, &m->interface);
3946 case SD_BUS_MESSAGE_HEADER_MEMBER:
3951 if (!streq(signature, "s"))
3954 r = message_peek_field_string(m, member_name_is_valid, &ri, &m->member);
3957 case SD_BUS_MESSAGE_HEADER_ERROR_NAME:
3962 if (!streq(signature, "s"))
3965 r = message_peek_field_string(m, error_name_is_valid, &ri, &m->error.name);
3968 case SD_BUS_MESSAGE_HEADER_DESTINATION:
3973 if (!streq(signature, "s"))
3976 r = message_peek_field_string(m, service_name_is_valid, &ri, &m->destination);
3979 case SD_BUS_MESSAGE_HEADER_SENDER:
3984 if (!streq(signature, "s"))
3987 r = message_peek_field_string(m, service_name_is_valid, &ri, &m->sender);
3991 case SD_BUS_MESSAGE_HEADER_SIGNATURE: {
3995 if (m->root_container.signature)
3998 if (!streq(signature, "g"))
4001 r = message_peek_field_signature(m, &ri, &s);
4009 free(m->root_container.signature);
4010 m->root_container.signature = c;
4014 case SD_BUS_MESSAGE_HEADER_REPLY_SERIAL:
4015 if (m->reply_serial != 0)
4018 if (!streq(signature, "u"))
4021 r = message_peek_field_uint32(m, &ri, &m->reply_serial);
4025 if (m->reply_serial == 0)
4030 case SD_BUS_MESSAGE_HEADER_UNIX_FDS:
4034 if (!streq(signature, "u"))
4037 r = message_peek_field_uint32(m, &ri, &unix_fds);
4047 r = message_skip_fields(m, &ri, (uint32_t) -1, (const char **) &signature);
4054 if (m->n_fds != unix_fds)
4057 if (isempty(m->root_container.signature) != (BUS_MESSAGE_BODY_SIZE(m) == 0))
4060 switch (m->header->type) {
4062 case SD_BUS_MESSAGE_SIGNAL:
4063 if (!m->path || !m->interface || !m->member)
4067 case SD_BUS_MESSAGE_METHOD_CALL:
4069 if (!m->path || !m->member)
4074 case SD_BUS_MESSAGE_METHOD_RETURN:
4076 if (m->reply_serial == 0)
4080 case SD_BUS_MESSAGE_METHOD_ERROR:
4082 if (m->reply_serial == 0 || !m->error.name)
4087 /* Try to read the error message, but if we can't it's a non-issue */
4088 if (m->header->type == SD_BUS_MESSAGE_METHOD_ERROR)
4089 sd_bus_message_read(m, "s", &m->error.message);
4094 int bus_message_seal(sd_bus_message *m, uint64_t serial) {
4095 struct bus_body_part *part;
4105 if (m->n_containers > 0)
4111 /* If there's a non-trivial signature set, then add it in here */
4112 if (!isempty(m->root_container.signature)) {
4113 r = message_append_field_signature(m, SD_BUS_MESSAGE_HEADER_SIGNATURE, m->root_container.signature, NULL);
4119 r = message_append_field_uint32(m, SD_BUS_MESSAGE_HEADER_UNIX_FDS, m->n_fds);
4124 /* Add padding at the end of the fields part, since we know
4125 * the body needs to start at an 8 byte alignment. We made
4126 * sure we allocated enough space for this, so all we need to
4127 * do here is to zero it out. */
4128 l = BUS_MESSAGE_FIELDS_SIZE(m);
4131 memset((uint8_t*) BUS_MESSAGE_FIELDS(m) + l, 0, a);
4133 /* If this is something we can send as memfd, then let's seal
4134 the memfd now. Note that we can send memfds as payload only
4135 for directed messages, and not for broadcasts. */
4136 if (m->destination && m->bus && m->bus->use_memfd) {
4137 MESSAGE_FOREACH_PART(part, i, m)
4138 if (part->memfd >= 0 && !part->sealed && (part->size > MEMFD_MIN_SIZE || m->bus->use_memfd < 0)) {
4139 bus_body_part_unmap(part);
4141 if (ioctl(part->memfd, KDBUS_CMD_MEMFD_SEAL_SET, 1) >= 0)
4142 part->sealed = true;
4146 m->header->serial = serial;
4152 int sd_bus_message_set_destination(sd_bus_message *m, const char *destination) {
4162 return message_append_field_string(m, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &m->destination);
4165 int bus_message_dump(sd_bus_message *m, FILE *f, bool with_header) {
4166 const char *u = NULL, *uu = NULL, *s = NULL;
4167 char **cmdline = NULL;
4170 uid_t owner, audit_loginuid;
4171 uint32_t audit_sessionid;
4187 "\tfields_size=%u\n"
4192 "\tdestination=%s\n"
4195 "\treply_serial=%u\n"
4197 "\tn_body_parts=%u\n",
4204 BUS_MESSAGE_SERIAL(m),
4205 BUS_MESSAGE_FIELDS_SIZE(m),
4206 BUS_MESSAGE_BODY_SIZE(m),
4208 strna(m->interface),
4210 strna(m->destination),
4212 strna(m->root_container.signature),
4217 if (sd_bus_error_is_set(&m->error))
4220 "\terror.message=%s\n",
4221 strna(m->error.name),
4222 strna(m->error.message));
4225 fprintf(f, "\tpid=%lu\n", (unsigned long) m->pid);
4227 fprintf(f, "\ttid=%lu\n", (unsigned long) m->tid);
4229 fprintf(f, "\tuid=%lu\n", (unsigned long) m->uid);
4231 fprintf(f, "\tgid=%lu\n", (unsigned long) m->gid);
4232 if (m->pid_starttime != 0)
4233 fprintf(f, "\tpid_starttime=%llu\n", (unsigned long long) m->pid_starttime);
4234 if (m->monotonic != 0)
4235 fprintf(f, "\tmonotonic=%llu\n", (unsigned long long) m->monotonic);
4236 if (m->realtime != 0)
4237 fprintf(f, "\trealtime=%llu\n", (unsigned long long) m->realtime);
4239 fprintf(f, "\texe=[%s]\n", m->exe);
4241 fprintf(f, "\tcomm=[%s]\n", m->comm);
4243 fprintf(f, "\ttid_comm=[%s]\n", m->tid_comm);
4245 fprintf(f, "\tlabel=[%s]\n", m->label);
4247 fprintf(f, "\tcgroup=[%s]\n", m->cgroup);
4249 sd_bus_message_get_unit(m, &u);
4251 fprintf(f, "\tunit=[%s]\n", u);
4252 sd_bus_message_get_user_unit(m, &uu);
4254 fprintf(f, "\tuser_unit=[%s]\n", uu);
4255 sd_bus_message_get_session(m, &s);
4257 fprintf(f, "\tsession=[%s]\n", s);
4258 if (sd_bus_message_get_owner_uid(m, &owner) >= 0)
4259 fprintf(f, "\towner_uid=%lu\n", (unsigned long) owner);
4260 if (sd_bus_message_get_audit_loginuid(m, &audit_loginuid) >= 0)
4261 fprintf(f, "\taudit_loginuid=%lu\n", (unsigned long) audit_loginuid);
4262 if (sd_bus_message_get_audit_sessionid(m, &audit_sessionid) >= 0)
4263 fprintf(f, "\taudit_sessionid=%lu\n", (unsigned long) audit_sessionid);
4265 r = sd_bus_message_has_effective_cap(m, 5);
4267 fprintf(f, "\tCAP_KILL=%s\n", yes_no(r));
4269 if (sd_bus_message_get_cmdline(m, &cmdline) >= 0) {
4272 fputs("\tcmdline=[", f);
4273 STRV_FOREACH(c, cmdline) {
4284 r = sd_bus_message_rewind(m, true);
4286 log_error("Failed to rewind: %s", strerror(-r));
4290 fprintf(f, "BEGIN_MESSAGE \"%s\" {\n", strempty(m->root_container.signature));
4293 _cleanup_free_ char *prefix = NULL;
4294 const char *contents = NULL;
4309 r = sd_bus_message_peek_type(m, &type, &contents);
4311 log_error("Failed to peek type: %s", strerror(-r));
4318 r = sd_bus_message_exit_container(m);
4320 log_error("Failed to exit container: %s", strerror(-r));
4326 prefix = strrep("\t", level);
4330 if (type == SD_BUS_TYPE_ARRAY)
4331 fprintf(f, "%s} END_ARRAY \n", prefix);
4332 else if (type == SD_BUS_TYPE_VARIANT)
4333 fprintf(f, "%s} END_VARIANT\n", prefix);
4334 else if (type == SD_BUS_TYPE_STRUCT)
4335 fprintf(f, "%s} END_STRUCT\n", prefix);
4336 else if (type == SD_BUS_TYPE_DICT_ENTRY)
4337 fprintf(f, "%s} END_DICT_ENTRY\n", prefix);
4342 prefix = strrep("\t", level);
4346 if (bus_type_is_container(type) > 0) {
4347 r = sd_bus_message_enter_container(m, type, contents);
4349 log_error("Failed to enter container: %s", strerror(-r));
4353 if (type == SD_BUS_TYPE_ARRAY)
4354 fprintf(f, "%sBEGIN_ARRAY \"%s\" {\n", prefix, contents);
4355 else if (type == SD_BUS_TYPE_VARIANT)
4356 fprintf(f, "%sBEGIN_VARIANT \"%s\" {\n", prefix, contents);
4357 else if (type == SD_BUS_TYPE_STRUCT)
4358 fprintf(f, "%sBEGIN_STRUCT \"%s\" {\n", prefix, contents);
4359 else if (type == SD_BUS_TYPE_DICT_ENTRY)
4360 fprintf(f, "%sBEGIN_DICT_ENTRY \"%s\" {\n", prefix, contents);
4367 r = sd_bus_message_read_basic(m, type, &basic);
4369 log_error("Failed to get basic: %s", strerror(-r));
4377 case SD_BUS_TYPE_BYTE:
4378 fprintf(f, "%sBYTE: %u\n", prefix, basic.u8);
4381 case SD_BUS_TYPE_BOOLEAN:
4382 fprintf(f, "%sBOOLEAN: %s\n", prefix, yes_no(basic.i));
4385 case SD_BUS_TYPE_INT16:
4386 fprintf(f, "%sINT16: %i\n", prefix, basic.s16);
4389 case SD_BUS_TYPE_UINT16:
4390 fprintf(f, "%sUINT16: %u\n", prefix, basic.u16);
4393 case SD_BUS_TYPE_INT32:
4394 fprintf(f, "%sINT32: %i\n", prefix, basic.s32);
4397 case SD_BUS_TYPE_UINT32:
4398 fprintf(f, "%sUINT32: %u\n", prefix, basic.u32);
4401 case SD_BUS_TYPE_INT64:
4402 fprintf(f, "%sINT64: %lli\n", prefix, (long long) basic.s64);
4405 case SD_BUS_TYPE_UINT64:
4406 fprintf(f, "%sUINT64: %llu\n", prefix, (unsigned long long) basic.u64);
4409 case SD_BUS_TYPE_DOUBLE:
4410 fprintf(f, "%sDOUBLE: %g\n", prefix, basic.d64);
4413 case SD_BUS_TYPE_STRING:
4414 fprintf(f, "%sSTRING: \"%s\"\n", prefix, basic.string);
4417 case SD_BUS_TYPE_OBJECT_PATH:
4418 fprintf(f, "%sOBJECT_PATH: \"%s\"\n", prefix, basic.string);
4421 case SD_BUS_TYPE_SIGNATURE:
4422 fprintf(f, "%sSIGNATURE: \"%s\"\n", prefix, basic.string);
4425 case SD_BUS_TYPE_UNIX_FD:
4426 fprintf(f, "%sUNIX_FD: %i\n", prefix, basic.i);
4430 assert_not_reached("Unknown basic type.");
4434 fprintf(f, "} END_MESSAGE\n");
4438 int bus_message_get_blob(sd_bus_message *m, void **buffer, size_t *sz) {
4442 struct bus_body_part *part;
4448 total = BUS_MESSAGE_SIZE(m);
4454 e = mempcpy(p, m->header, BUS_MESSAGE_BODY_BEGIN(m));
4455 MESSAGE_FOREACH_PART(part, i, m)
4456 e = mempcpy(e, part->data, part->size);
4458 assert(total == (size_t) ((uint8_t*) e - (uint8_t*) p));
4466 int bus_message_read_strv_extend(sd_bus_message *m, char ***l) {
4472 r = sd_bus_message_enter_container(m, 'a', "s");
4479 r = sd_bus_message_read_basic(m, 's', &s);
4485 r = strv_extend(l, s);
4490 r = sd_bus_message_exit_container(m);
4497 const char* bus_message_get_arg(sd_bus_message *m, unsigned i) {
4499 const char *t = NULL;
4504 r = sd_bus_message_rewind(m, true);
4508 for (j = 0; j <= i; j++) {
4511 r = sd_bus_message_peek_type(m, &type, NULL);
4515 if (type != SD_BUS_TYPE_STRING &&
4516 type != SD_BUS_TYPE_OBJECT_PATH &&
4517 type != SD_BUS_TYPE_SIGNATURE)
4520 r = sd_bus_message_read_basic(m, type, &t);
4528 bool bus_header_is_complete(struct bus_header *h, size_t size) {
4534 if (size < sizeof(struct bus_header))
4537 full = sizeof(struct bus_header) +
4538 (h->endian == SD_BUS_NATIVE_ENDIAN ? h->fields_size : bswap_32(h->fields_size));
4540 return size >= full;
4543 int bus_header_message_size(struct bus_header *h, size_t *sum) {
4549 if (h->endian == SD_BUS_NATIVE_ENDIAN) {
4550 fs = h->fields_size;
4552 } else if (h->endian == SD_BUS_REVERSE_ENDIAN) {
4553 fs = bswap_32(h->fields_size);
4554 bs = bswap_32(h->body_size);
4558 *sum = sizeof(struct bus_header) + ALIGN8(fs) + bs;
4562 int sd_bus_message_get_errno(sd_bus_message *m) {
4563 assert_return(m, -EINVAL);
4565 if (m->header->type != SD_BUS_MESSAGE_METHOD_ERROR)
4568 return sd_bus_error_get_errno(&m->error);
4571 const char* sd_bus_message_get_signature(sd_bus_message *m, int complete) {
4572 struct bus_container *c;
4577 c = complete ? &m->root_container : message_get_container(m);
4578 return c->signature ?: "";
4581 int sd_bus_message_copy(sd_bus_message *m, sd_bus_message *source, int all) {
4582 bool done_something = false;
4585 assert_return(m, -EINVAL);
4586 assert_return(source, -EINVAL);
4587 assert_return(!m->sealed, -EPERM);
4588 assert_return(source->sealed, -EPERM);
4591 const char *contents;
4606 r = sd_bus_message_peek_type(source, &type, &contents);
4612 done_something = true;
4614 if (bus_type_is_container(type) > 0) {
4616 r = sd_bus_message_enter_container(source, type, contents);
4620 r = sd_bus_message_open_container(m, type, contents);
4624 r = sd_bus_message_copy(m, source, true);
4628 r = sd_bus_message_close_container(m);
4632 r = sd_bus_message_exit_container(source);
4639 r = sd_bus_message_read_basic(source, type, &basic);
4645 if (type == SD_BUS_TYPE_OBJECT_PATH ||
4646 type == SD_BUS_TYPE_SIGNATURE ||
4647 type == SD_BUS_TYPE_STRING)
4648 r = sd_bus_message_append_basic(m, type, basic.string);
4650 r = sd_bus_message_append_basic(m, type, &basic);
4657 return done_something;
4660 int sd_bus_message_verify_type(sd_bus_message *m, char type, const char *contents) {
4665 assert_return(m, -EINVAL);
4666 assert_return(m->sealed, -EPERM);
4667 assert_return(!type || bus_type_is_valid(type), -EINVAL);
4668 assert_return(!contents || signature_is_valid(contents, true), -EINVAL);
4669 assert_return(type || contents, -EINVAL);
4670 assert_return(!contents || !type || bus_type_is_container(type), -EINVAL);
4672 r = sd_bus_message_peek_type(m, &t, &c);
4676 if (type != 0 && type != t)
4679 if (contents && !streq_ptr(contents, c))