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_TYPE_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_TYPE_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_TYPE_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_TYPE_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_TYPE_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_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
652 r = message_new_reply(bus, call, SD_BUS_MESSAGE_TYPE_METHOD_ERROR, &t);
656 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_ERROR_NAME, SD_BUS_TYPE_STRING, name, &t->error.name);
661 _cleanup_free_ char *message = NULL;
663 va_start(ap, format);
664 r = vasprintf(&message, format, ap);
672 r = message_append_basic(t, SD_BUS_TYPE_STRING, message, (const void**) &t->error.message);
685 int bus_message_new_synthetic_error(
688 const sd_bus_error *e,
689 sd_bus_message **m) {
694 assert(sd_bus_error_is_set(e));
697 t = message_new(bus, SD_BUS_MESSAGE_TYPE_METHOD_ERROR);
701 t->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
702 t->reply_serial = serial;
704 r = message_append_field_uint32(t, SD_BUS_MESSAGE_HEADER_REPLY_SERIAL, t->reply_serial);
708 if (bus && bus->unique_name) {
709 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, bus->unique_name, &t->destination);
714 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_ERROR_NAME, SD_BUS_TYPE_STRING, e->name, &t->error.name);
719 r = message_append_basic(t, SD_BUS_TYPE_STRING, e->message, (const void**) &t->error.message);
732 sd_bus_message* sd_bus_message_ref(sd_bus_message *m) {
736 assert(m->n_ref > 0);
742 sd_bus_message* sd_bus_message_unref(sd_bus_message *m) {
746 assert(m->n_ref > 0);
755 int sd_bus_message_get_type(sd_bus_message *m, uint8_t *type) {
761 *type = m->header->type;
765 int sd_bus_message_get_serial(sd_bus_message *m, uint64_t *serial) {
770 if (m->header->serial == 0)
773 *serial = BUS_MESSAGE_SERIAL(m);
777 int sd_bus_message_get_reply_serial(sd_bus_message *m, uint64_t *serial) {
782 if (m->reply_serial == 0)
785 *serial = m->reply_serial;
789 int sd_bus_message_get_no_reply(sd_bus_message *m) {
793 return m->header->type == SD_BUS_MESSAGE_TYPE_METHOD_CALL ? !!(m->header->flags & SD_BUS_MESSAGE_NO_REPLY_EXPECTED) : 0;
796 const char *sd_bus_message_get_path(sd_bus_message *m) {
803 const char *sd_bus_message_get_interface(sd_bus_message *m) {
810 const char *sd_bus_message_get_member(sd_bus_message *m) {
816 const char *sd_bus_message_get_destination(sd_bus_message *m) {
820 return m->destination;
823 const char *sd_bus_message_get_sender(sd_bus_message *m) {
830 const sd_bus_error *sd_bus_message_get_error(sd_bus_message *m) {
834 if (!sd_bus_error_is_set(&m->error))
840 int sd_bus_message_get_uid(sd_bus_message *m, uid_t *uid) {
852 int sd_bus_message_get_gid(sd_bus_message *m, gid_t *gid) {
864 int sd_bus_message_get_pid(sd_bus_message *m, pid_t *pid) {
876 int sd_bus_message_get_tid(sd_bus_message *m, pid_t *tid) {
888 int sd_bus_message_get_pid_starttime(sd_bus_message *m, uint64_t *usec) {
893 if (m->pid_starttime <= 0)
896 *usec = m->pid_starttime;
900 int sd_bus_message_get_selinux_context(sd_bus_message *m, const char **ret) {
910 int sd_bus_message_get_monotonic_timestamp(sd_bus_message *m, uint64_t *usec) {
915 if (m->monotonic <= 0)
918 *usec = m->monotonic;
922 int sd_bus_message_get_realtime_timestamp(sd_bus_message *m, uint64_t *usec) {
927 if (m->realtime <= 0)
934 int sd_bus_message_get_comm(sd_bus_message *m, const char **ret) {
946 int sd_bus_message_get_tid_comm(sd_bus_message *m, const char **ret) {
958 int sd_bus_message_get_exe(sd_bus_message *m, const char **ret) {
970 int sd_bus_message_get_cgroup(sd_bus_message *m, const char **ret) {
982 int sd_bus_message_get_unit(sd_bus_message *m, const char **ret) {
993 r = cg_path_get_unit(m->cgroup, &m->unit);
1002 int sd_bus_message_get_user_unit(sd_bus_message *m, const char **ret) {
1012 if (!m->user_unit) {
1013 r = cg_path_get_user_unit(m->cgroup, &m->user_unit);
1018 *ret = m->user_unit;
1022 int sd_bus_message_get_session(sd_bus_message *m, const char **ret) {
1033 r = cg_path_get_session(m->cgroup, &m->session);
1042 int sd_bus_message_get_owner_uid(sd_bus_message *m, uid_t *uid) {
1050 return cg_path_get_owner_uid(m->cgroup, uid);
1053 int sd_bus_message_get_cmdline(sd_bus_message *m, char ***cmdline) {
1064 for (p = m->cmdline, n = 0; p < m->cmdline + m->cmdline_length; p++)
1068 m->cmdline_array = new(char*, n + 1);
1069 if (!m->cmdline_array)
1072 for (p = m->cmdline, i = 0, first = true; p < m->cmdline + m->cmdline_length; p++) {
1074 m->cmdline_array[i++] = (char*) p;
1079 m->cmdline_array[i] = NULL;
1080 *cmdline = m->cmdline_array;
1085 int sd_bus_message_get_audit_sessionid(sd_bus_message *m, uint32_t *sessionid) {
1093 *sessionid = m->audit->sessionid;
1097 int sd_bus_message_get_audit_loginuid(sd_bus_message *m, uid_t *uid) {
1105 *uid = m->audit->loginuid;
1109 int sd_bus_message_has_effective_cap(sd_bus_message *m, int capability) {
1119 sz = m->capability_size / 4;
1120 if ((unsigned) capability >= sz*8)
1123 return !!(m->capability[2 * sz + (capability / 8)] & (1 << (capability % 8)));
1126 int sd_bus_message_is_signal(sd_bus_message *m, const char *interface, const char *member) {
1130 if (m->header->type != SD_BUS_MESSAGE_TYPE_SIGNAL)
1133 if (interface && (!m->interface || !streq(m->interface, interface)))
1136 if (member && (!m->member || !streq(m->member, member)))
1142 int sd_bus_message_is_method_call(sd_bus_message *m, const char *interface, const char *member) {
1146 if (m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_CALL)
1149 if (interface && (!m->interface || !streq(m->interface, interface)))
1152 if (member && (!m->member || !streq(m->member, member)))
1158 int sd_bus_message_is_method_error(sd_bus_message *m, const char *name) {
1162 if (m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_ERROR)
1165 if (name && (!m->error.name || !streq(m->error.name, name)))
1171 int sd_bus_message_set_no_reply(sd_bus_message *m, int b) {
1176 if (m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_CALL)
1180 m->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
1182 m->header->flags &= ~SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
1187 static struct bus_container *message_get_container(sd_bus_message *m) {
1190 if (m->n_containers == 0)
1191 return &m->root_container;
1193 assert(m->containers);
1194 return m->containers + m->n_containers - 1;
1197 struct bus_body_part *message_append_part(sd_bus_message *m) {
1198 struct bus_body_part *part;
1205 if (m->n_body_parts <= 0) {
1209 assert(m->body_end);
1211 part = new0(struct bus_body_part, 1);
1217 m->body_end->next = part;
1227 static void part_zero(struct bus_body_part *part, size_t sz) {
1232 /* All other fields can be left in their defaults */
1233 assert(!part->data);
1234 assert(part->memfd < 0);
1237 part->is_zero = true;
1238 part->sealed = true;
1241 static int part_make_space(
1242 struct sd_bus_message *m,
1243 struct bus_body_part *part,
1252 assert(!part->sealed);
1257 if (!part->data && part->memfd < 0)
1258 part->memfd = bus_kernel_pop_memfd(m->bus, &part->data, &part->mapped);
1260 if (part->memfd >= 0) {
1263 r = ioctl(part->memfd, KDBUS_CMD_MEMFD_SIZE_SET, &u);
1269 if (!part->data || sz > part->mapped) {
1270 size_t psz = PAGE_ALIGN(sz > 0 ? sz : 1);
1272 if (part->mapped <= 0)
1273 n = mmap(NULL, psz, PROT_READ|PROT_WRITE, MAP_SHARED, part->memfd, 0);
1275 n = mremap(part->data, part->mapped, psz, MREMAP_MAYMOVE);
1277 if (n == MAP_FAILED) {
1286 part->munmap_this = true;
1288 n = realloc(part->data, sz);
1295 part->free_this = true;
1299 *q = part->data ? (uint8_t*) part->data + part->size : NULL;
1305 static void message_extend_containers(sd_bus_message *m, size_t expand) {
1306 struct bus_container *c;
1313 /* Update counters */
1314 for (c = m->containers; c < m->containers + m->n_containers; c++)
1316 *c->array_size += expand;
1319 static void *message_extend_body(sd_bus_message *m, size_t align, size_t sz) {
1320 struct bus_body_part *part = NULL;
1321 size_t start_body, end_body, padding, start_part, end_part, added;
1333 start_body = ALIGN_TO((size_t) m->header->body_size, align);
1334 end_body = start_body + sz;
1336 padding = start_body - m->header->body_size;
1337 added = padding + sz;
1339 /* Check for 32bit overflows */
1340 if (end_body > (size_t) ((uint32_t) -1)) {
1346 m->n_body_parts <= 0 ||
1347 m->body_end->sealed ||
1348 padding != ALIGN_TO(m->body_end->size, align) - m->body_end->size;
1352 part = message_append_part(m);
1356 part_zero(part, padding);
1359 part = message_append_part(m);
1363 r = part_make_space(m, part, sz, &p);
1367 struct bus_container *c;
1375 start_part = ALIGN_TO(part->size, align);
1376 end_part = start_part + sz;
1378 r = part_make_space(m, part, end_part, &p);
1383 memset(p, 0, padding);
1384 p = (uint8_t*) p + padding;
1387 /* Readjust pointers */
1388 for (c = m->containers; c < m->containers + m->n_containers; c++)
1389 c->array_size = adjust_pointer(c->array_size, op, os, part->data);
1391 m->error.message = (const char*) adjust_pointer(m->error.message, op, os, part->data);
1394 m->header->body_size = end_body;
1395 message_extend_containers(m, added);
1400 int message_append_basic(sd_bus_message *m, char type, const void *p, const void **stored) {
1401 struct bus_container *c;
1415 if (!bus_type_is_basic(type))
1420 c = message_get_container(m);
1422 if (c->signature && c->signature[c->index]) {
1423 /* Container signature is already set */
1425 if (c->signature[c->index] != type)
1430 /* Maybe we can append to the signature? But only if this is the top-level container*/
1431 if (c->enclosing != 0)
1434 e = strextend(&c->signature, CHAR_TO_STR(type), NULL);
1443 case SD_BUS_TYPE_STRING:
1444 case SD_BUS_TYPE_OBJECT_PATH:
1447 sz = 4 + strlen(p) + 1;
1450 case SD_BUS_TYPE_SIGNATURE:
1453 sz = 1 + strlen(p) + 1;
1456 case SD_BUS_TYPE_BOOLEAN:
1459 assert_cc(sizeof(int) == sizeof(uint32_t));
1465 case SD_BUS_TYPE_UNIX_FD: {
1468 if (!m->allow_fds) {
1481 fd = fcntl(z, F_DUPFD_CLOEXEC, 3);
1487 f = realloc(m->fds, sizeof(int) * (m->n_fds + 1));
1502 align = bus_type_get_alignment(type);
1503 sz = bus_type_get_size(type);
1510 a = message_extend_body(m, align, sz);
1516 if (type == SD_BUS_TYPE_STRING || type == SD_BUS_TYPE_OBJECT_PATH) {
1517 *(uint32_t*) a = sz - 5;
1518 memcpy((uint8_t*) a + 4, p, sz - 4);
1521 *stored = (const uint8_t*) a + 4;
1523 } else if (type == SD_BUS_TYPE_SIGNATURE) {
1524 *(uint8_t*) a = sz - 1;
1525 memcpy((uint8_t*) a + 1, p, sz - 1);
1528 *stored = (const uint8_t*) a + 1;
1529 } else if (type == SD_BUS_TYPE_UNIX_FD) {
1530 *(uint32_t*) a = fdi;
1544 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1551 close_nointr_nofail(fd);
1556 int sd_bus_message_append_basic(sd_bus_message *m, char type, const void *p) {
1557 return message_append_basic(m, type, p, NULL);
1560 int sd_bus_message_append_string_space(sd_bus_message *m, size_t size, char **s) {
1561 struct bus_container *c;
1573 c = message_get_container(m);
1575 if (c->signature && c->signature[c->index]) {
1576 /* Container signature is already set */
1578 if (c->signature[c->index] != SD_BUS_TYPE_STRING)
1583 /* Maybe we can append to the signature? But only if this is the top-level container*/
1584 if (c->enclosing != 0)
1587 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRING), NULL);
1594 a = message_extend_body(m, 4, 4 + size + 1);
1598 *(uint32_t*) a = size;
1603 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1609 static int bus_message_open_array(
1611 struct bus_container *c,
1612 const char *contents,
1613 uint32_t **array_size) {
1619 struct bus_body_part *o;
1626 if (!signature_is_single(contents, true))
1629 alignment = bus_type_get_alignment(contents[0]);
1633 if (c->signature && c->signature[c->index]) {
1635 /* Verify the existing signature */
1637 if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
1640 if (!startswith(c->signature + c->index + 1, contents))
1643 nindex = c->index + 1 + strlen(contents);
1647 if (c->enclosing != 0)
1650 /* Extend the existing signature */
1652 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_ARRAY), contents, NULL);
1658 nindex = e - c->signature;
1661 a = message_extend_body(m, 4, 4);
1666 op = m->body_end->data;
1667 os = m->body_end->size;
1669 /* Add alignment between size and first element */
1670 if (!message_extend_body(m, alignment, 0))
1673 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1676 /* location of array size might have changed so let's readjust a */
1677 if (o == m->body_end)
1678 a = adjust_pointer(a, op, os, m->body_end->data);
1685 static int bus_message_open_variant(
1687 struct bus_container *c,
1688 const char *contents) {
1697 if (!signature_is_single(contents, false))
1700 if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
1703 if (c->signature && c->signature[c->index]) {
1705 if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
1711 if (c->enclosing != 0)
1714 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_VARIANT), NULL);
1721 l = strlen(contents);
1722 a = message_extend_body(m, 1, 1 + l + 1);
1727 memcpy((uint8_t*) a + 1, contents, l + 1);
1729 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1735 static int bus_message_open_struct(
1737 struct bus_container *c,
1738 const char *contents) {
1746 if (!signature_is_valid(contents, false))
1749 if (c->signature && c->signature[c->index]) {
1752 l = strlen(contents);
1754 if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
1755 !startswith(c->signature + c->index + 1, contents) ||
1756 c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
1759 nindex = c->index + 1 + l + 1;
1763 if (c->enclosing != 0)
1766 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_BEGIN), contents, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_END), NULL);
1772 nindex = e - c->signature;
1775 /* Align contents to 8 byte boundary */
1776 if (!message_extend_body(m, 8, 0))
1779 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1785 static int bus_message_open_dict_entry(
1787 struct bus_container *c,
1788 const char *contents) {
1796 if (!signature_is_pair(contents))
1799 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1802 if (c->signature && c->signature[c->index]) {
1805 l = strlen(contents);
1807 if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
1808 !startswith(c->signature + c->index + 1, contents) ||
1809 c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
1812 nindex = c->index + 1 + l + 1;
1816 /* Align contents to 8 byte boundary */
1817 if (!message_extend_body(m, 8, 0))
1820 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1826 int sd_bus_message_open_container(
1829 const char *contents) {
1831 struct bus_container *c, *w;
1832 uint32_t *array_size = NULL;
1846 /* Make sure we have space for one more container */
1847 w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
1855 c = message_get_container(m);
1857 signature = strdup(contents);
1863 /* Save old index in the parent container, in case we have to
1864 * abort this container */
1865 c->saved_index = c->index;
1866 before = m->header->body_size;
1868 if (type == SD_BUS_TYPE_ARRAY)
1869 r = bus_message_open_array(m, c, contents, &array_size);
1870 else if (type == SD_BUS_TYPE_VARIANT)
1871 r = bus_message_open_variant(m, c, contents);
1872 else if (type == SD_BUS_TYPE_STRUCT)
1873 r = bus_message_open_struct(m, c, contents);
1874 else if (type == SD_BUS_TYPE_DICT_ENTRY)
1875 r = bus_message_open_dict_entry(m, c, contents);
1884 /* OK, let's fill it in */
1885 w += m->n_containers++;
1886 w->enclosing = type;
1887 w->signature = signature;
1889 w->array_size = array_size;
1891 w->begin = m->rindex;
1896 int sd_bus_message_close_container(sd_bus_message *m) {
1897 struct bus_container *c;
1903 if (m->n_containers <= 0)
1908 c = message_get_container(m);
1909 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1910 if (c->signature && c->signature[c->index] != 0)
1925 static int type_stack_push(TypeStack *stack, unsigned max, unsigned *i, const char *types, unsigned n_struct, unsigned n_array) {
1932 stack[*i].types = types;
1933 stack[*i].n_struct = n_struct;
1934 stack[*i].n_array = n_array;
1940 static int type_stack_pop(TypeStack *stack, unsigned max, unsigned *i, const char **types, unsigned *n_struct, unsigned *n_array) {
1951 *types = stack[*i].types;
1952 *n_struct = stack[*i].n_struct;
1953 *n_array = stack[*i].n_array;
1958 int bus_message_append_ap(
1963 unsigned n_array, n_struct;
1964 TypeStack stack[BUS_CONTAINER_DEPTH];
1965 unsigned stack_ptr = 0;
1973 n_array = (unsigned) -1;
1974 n_struct = strlen(types);
1979 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
1980 r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
1986 r = sd_bus_message_close_container(m);
1994 if (n_array != (unsigned) -1)
2003 case SD_BUS_TYPE_BYTE: {
2006 x = (uint8_t) va_arg(ap, int);
2007 r = sd_bus_message_append_basic(m, *t, &x);
2011 case SD_BUS_TYPE_BOOLEAN:
2012 case SD_BUS_TYPE_INT32:
2013 case SD_BUS_TYPE_UINT32:
2014 case SD_BUS_TYPE_UNIX_FD: {
2017 /* We assume a boolean is the same as int32_t */
2018 assert_cc(sizeof(int32_t) == sizeof(int));
2020 x = va_arg(ap, uint32_t);
2021 r = sd_bus_message_append_basic(m, *t, &x);
2025 case SD_BUS_TYPE_INT16:
2026 case SD_BUS_TYPE_UINT16: {
2029 x = (uint16_t) va_arg(ap, int);
2030 r = sd_bus_message_append_basic(m, *t, &x);
2034 case SD_BUS_TYPE_INT64:
2035 case SD_BUS_TYPE_UINT64:
2036 case SD_BUS_TYPE_DOUBLE: {
2039 x = va_arg(ap, uint64_t);
2040 r = sd_bus_message_append_basic(m, *t, &x);
2044 case SD_BUS_TYPE_STRING:
2045 case SD_BUS_TYPE_OBJECT_PATH:
2046 case SD_BUS_TYPE_SIGNATURE: {
2049 x = va_arg(ap, const char*);
2050 r = sd_bus_message_append_basic(m, *t, x);
2054 case SD_BUS_TYPE_ARRAY: {
2057 r = signature_element_length(t + 1, &k);
2063 memcpy(s, t + 1, k);
2066 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, s);
2071 if (n_array == (unsigned) -1) {
2076 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2082 n_array = va_arg(ap, unsigned);
2087 case SD_BUS_TYPE_VARIANT: {
2090 s = va_arg(ap, const char*);
2094 r = sd_bus_message_open_container(m, SD_BUS_TYPE_VARIANT, s);
2098 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2103 n_struct = strlen(s);
2104 n_array = (unsigned) -1;
2109 case SD_BUS_TYPE_STRUCT_BEGIN:
2110 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
2113 r = signature_element_length(t, &k);
2120 memcpy(s, t + 1, k - 2);
2123 r = sd_bus_message_open_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
2128 if (n_array == (unsigned) -1) {
2133 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2139 n_array = (unsigned) -1;
2155 int sd_bus_message_append(sd_bus_message *m, const char *types, ...) {
2168 va_start(ap, types);
2169 r = bus_message_append_ap(m, types, ap);
2175 int sd_bus_message_append_array_space(sd_bus_message *m, char type, size_t size, void **ptr) {
2184 if (!bus_type_is_trivial(type))
2186 if (!ptr && size > 0)
2191 align = bus_type_get_alignment(type);
2192 sz = bus_type_get_size(type);
2194 assert_se(align > 0);
2200 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
2204 a = message_extend_body(m, align, size);
2208 r = sd_bus_message_close_container(m);
2216 int sd_bus_message_append_array(sd_bus_message *m, char type, const void *ptr, size_t size) {
2220 if (!ptr && size > 0)
2223 r = sd_bus_message_append_array_space(m, type, size, &p);
2228 memcpy(p, ptr, size);
2233 int sd_bus_message_append_array_memfd(sd_bus_message *m, char type, sd_memfd *memfd) {
2234 _cleanup_close_ int copy_fd = -1;
2235 struct bus_body_part *part;
2247 if (!bus_type_is_trivial(type))
2252 r = sd_memfd_set_sealed(memfd, true);
2256 copy_fd = sd_memfd_dup_fd(memfd);
2260 r = sd_memfd_get_size(memfd, &size);
2264 align = bus_type_get_alignment(type);
2265 sz = bus_type_get_size(type);
2267 assert_se(align > 0);
2273 if (size > (uint64_t) (uint32_t) -1)
2276 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
2280 a = message_extend_body(m, align, 0);
2284 part = message_append_part(m);
2288 part->memfd = copy_fd;
2289 part->sealed = true;
2293 message_extend_containers(m, size);
2294 m->header->body_size += size;
2296 return sd_bus_message_close_container(m);
2299 int sd_bus_message_append_string_memfd(sd_bus_message *m, sd_memfd *memfd) {
2300 _cleanup_close_ int copy_fd = -1;
2301 struct bus_body_part *part;
2302 struct bus_container *c;
2316 r = sd_memfd_set_sealed(memfd, true);
2320 copy_fd = sd_memfd_dup_fd(memfd);
2324 r = sd_memfd_get_size(memfd, &size);
2328 /* We require this to be NUL terminated */
2332 if (size > (uint64_t) (uint32_t) -1)
2335 c = message_get_container(m);
2336 if (c->signature && c->signature[c->index]) {
2337 /* Container signature is already set */
2339 if (c->signature[c->index] != SD_BUS_TYPE_STRING)
2344 /* Maybe we can append to the signature? But only if this is the top-level container*/
2345 if (c->enclosing != 0)
2348 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRING), NULL);
2355 a = message_extend_body(m, 4, 4);
2359 *(uint32_t*) a = size - 1;
2361 part = message_append_part(m);
2365 part->memfd = copy_fd;
2366 part->sealed = true;
2370 message_extend_containers(m, size);
2371 m->header->body_size += size;
2373 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2379 int bus_body_part_map(struct bus_body_part *part) {
2388 if (part->size <= 0)
2391 /* For smaller zero parts (as used for padding) we don't need to map anything... */
2392 if (part->memfd < 0 && part->is_zero && part->size < 8) {
2393 static const uint8_t zeroes[7] = { };
2394 part->data = (void*) zeroes;
2398 psz = PAGE_ALIGN(part->size);
2400 if (part->memfd >= 0)
2401 p = mmap(NULL, psz, PROT_READ, MAP_SHARED, part->memfd, 0);
2402 else if (part->is_zero)
2403 p = mmap(NULL, psz, PROT_READ, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
2407 if (p == MAP_FAILED)
2412 part->munmap_this = true;
2417 void bus_body_part_unmap(struct bus_body_part *part) {
2421 if (part->memfd < 0)
2427 if (!part->munmap_this)
2430 assert_se(munmap(part->data, part->mapped) == 0);
2434 part->munmap_this = false;
2439 static int buffer_peek(const void *p, uint32_t sz, size_t *rindex, size_t align, size_t nbytes, void **r) {
2440 size_t k, start, end;
2445 start = ALIGN_TO((size_t) *rindex, align);
2446 end = start + nbytes;
2451 /* Verify that padding is 0 */
2452 for (k = *rindex; k < start; k++)
2453 if (((const uint8_t*) p)[k] != 0)
2457 *r = (uint8_t*) p + start;
2464 static bool message_end_of_array(sd_bus_message *m, size_t index) {
2465 struct bus_container *c;
2469 c = message_get_container(m);
2473 return index >= c->begin + BUS_MESSAGE_BSWAP32(m, *c->array_size);
2476 static struct bus_body_part* find_part(sd_bus_message *m, size_t index, size_t sz, void **p) {
2477 struct bus_body_part *part;
2483 if (m->cached_rindex_part && index >= m->cached_rindex_part_begin) {
2484 part = m->cached_rindex_part;
2485 begin = m->cached_rindex_part_begin;
2495 if (index + sz <= begin + part->size) {
2497 r = bus_body_part_map(part);
2502 *p = (uint8_t*) part->data + index - begin;
2504 m->cached_rindex_part = part;
2505 m->cached_rindex_part_begin = begin;
2510 begin += part->size;
2517 static int message_peek_body(
2524 size_t k, start, end, padding;
2525 struct bus_body_part *part;
2532 if (message_end_of_array(m, *rindex))
2535 start = ALIGN_TO((size_t) *rindex, align);
2536 padding = start - *rindex;
2537 end = start + nbytes;
2539 if (end > BUS_MESSAGE_BODY_SIZE(m))
2542 part = find_part(m, *rindex, padding, (void**) &q);
2547 /* Verify padding */
2548 for (k = 0; k < padding; k++)
2553 part = find_part(m, start, nbytes, (void**) &q);
2565 static bool validate_nul(const char *s, size_t l) {
2567 /* Check for NUL chars in the string */
2568 if (memchr(s, 0, l))
2571 /* Check for NUL termination */
2578 static bool validate_string(const char *s, size_t l) {
2580 if (!validate_nul(s, l))
2583 /* Check if valid UTF8 */
2584 if (!utf8_is_valid(s))
2590 static bool validate_signature(const char *s, size_t l) {
2592 if (!validate_nul(s, l))
2595 /* Check if valid signature */
2596 if (!signature_is_valid(s, true))
2602 static bool validate_object_path(const char *s, size_t l) {
2604 if (!validate_nul(s, l))
2607 if (!object_path_is_valid(s))
2613 int sd_bus_message_read_basic(sd_bus_message *m, char type, void *p) {
2614 struct bus_container *c;
2622 if (!bus_type_is_basic(type))
2627 c = message_get_container(m);
2629 if (!c->signature || c->signature[c->index] == 0)
2632 if (c->signature[c->index] != type)
2637 case SD_BUS_TYPE_STRING:
2638 case SD_BUS_TYPE_OBJECT_PATH: {
2643 r = message_peek_body(m, &rindex, 4, 4, &q);
2647 l = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2648 r = message_peek_body(m, &rindex, 1, l+1, &q);
2654 if (type == SD_BUS_TYPE_OBJECT_PATH) {
2655 if (!validate_object_path(q, l))
2658 if (!validate_string(q, l))
2663 *(const char**) p = q;
2667 case SD_BUS_TYPE_SIGNATURE: {
2672 r = message_peek_body(m, &rindex, 1, 1, &q);
2677 r = message_peek_body(m, &rindex, 1, l+1, &q);
2683 if (!validate_signature(q, l))
2687 *(const char**) p = q;
2695 align = bus_type_get_alignment(type);
2696 sz = bus_type_get_size(type);
2697 assert(align > 0 && sz > 0);
2700 r = message_peek_body(m, &rindex, align, sz, &q);
2706 case SD_BUS_TYPE_BYTE:
2707 *(uint8_t*) p = *(uint8_t*) q;
2710 case SD_BUS_TYPE_BOOLEAN:
2711 *(int*) p = !!*(uint32_t*) q;
2714 case SD_BUS_TYPE_INT16:
2715 case SD_BUS_TYPE_UINT16:
2716 *(uint16_t*) p = BUS_MESSAGE_BSWAP16(m, *(uint16_t*) q);
2719 case SD_BUS_TYPE_INT32:
2720 case SD_BUS_TYPE_UINT32:
2721 *(uint32_t*) p = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2724 case SD_BUS_TYPE_INT64:
2725 case SD_BUS_TYPE_UINT64:
2726 case SD_BUS_TYPE_DOUBLE:
2727 *(uint64_t*) p = BUS_MESSAGE_BSWAP64(m, *(uint64_t*) q);
2730 case SD_BUS_TYPE_UNIX_FD: {
2733 j = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2737 *(int*) p = m->fds[j];
2742 assert_not_reached("Unknown basic type...");
2751 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2757 static int bus_message_enter_array(
2759 struct bus_container *c,
2760 const char *contents,
2761 uint32_t **array_size) {
2772 if (!signature_is_single(contents, true))
2775 alignment = bus_type_get_alignment(contents[0]);
2779 if (!c->signature || c->signature[c->index] == 0)
2782 if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
2785 if (!startswith(c->signature + c->index + 1, contents))
2789 r = message_peek_body(m, &rindex, 4, 4, &q);
2793 if (BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q) > BUS_ARRAY_MAX_SIZE)
2796 r = message_peek_body(m, &rindex, alignment, 0, NULL);
2802 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2803 c->index += 1 + strlen(contents);
2807 *array_size = (uint32_t*) q;
2812 static int bus_message_enter_variant(
2814 struct bus_container *c,
2815 const char *contents) {
2826 if (!signature_is_single(contents, false))
2829 if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
2832 if (!c->signature || c->signature[c->index] == 0)
2835 if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
2839 r = message_peek_body(m, &rindex, 1, 1, &q);
2844 r = message_peek_body(m, &rindex, 1, l+1, &q);
2850 if (!validate_signature(q, l))
2853 if (!streq(q, contents))
2856 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2864 static int bus_message_enter_struct(
2866 struct bus_container *c,
2867 const char *contents) {
2876 if (!signature_is_valid(contents, false))
2879 if (!c->signature || c->signature[c->index] == 0)
2882 l = strlen(contents);
2884 if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
2885 !startswith(c->signature + c->index + 1, contents) ||
2886 c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
2889 r = message_peek_body(m, &m->rindex, 8, 0, NULL);
2893 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2894 c->index += 1 + l + 1;
2899 static int bus_message_enter_dict_entry(
2901 struct bus_container *c,
2902 const char *contents) {
2911 if (!signature_is_pair(contents))
2914 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2917 if (!c->signature || c->signature[c->index] == 0)
2920 l = strlen(contents);
2922 if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
2923 !startswith(c->signature + c->index + 1, contents) ||
2924 c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
2927 r = message_peek_body(m, &m->rindex, 8, 0, NULL);
2931 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2932 c->index += 1 + l + 1;
2937 int sd_bus_message_enter_container(sd_bus_message *m, char type, const char *contents) {
2938 struct bus_container *c, *w;
2939 uint32_t *array_size = NULL;
2952 * We enforce a global limit on container depth, that is much
2953 * higher than the 32 structs and 32 arrays the specification
2954 * mandates. This is simpler to implement for us, and we need
2955 * this only to ensure our container array doesn't grow
2956 * without bounds. We are happy to return any data from a
2957 * message as long as the data itself is valid, even if the
2958 * overall message might be not.
2960 * Note that the message signature is validated when
2961 * parsing the headers, and that validation does check the
2964 * Note that the specification defines no limits on the depth
2965 * of stacked variants, but we do.
2967 if (m->n_containers >= BUS_CONTAINER_DEPTH)
2970 w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
2975 c = message_get_container(m);
2977 if (!c->signature || c->signature[c->index] == 0)
2980 signature = strdup(contents);
2984 c->saved_index = c->index;
2987 if (type == SD_BUS_TYPE_ARRAY)
2988 r = bus_message_enter_array(m, c, contents, &array_size);
2989 else if (type == SD_BUS_TYPE_VARIANT)
2990 r = bus_message_enter_variant(m, c, contents);
2991 else if (type == SD_BUS_TYPE_STRUCT)
2992 r = bus_message_enter_struct(m, c, contents);
2993 else if (type == SD_BUS_TYPE_DICT_ENTRY)
2994 r = bus_message_enter_dict_entry(m, c, contents);
3003 /* OK, let's fill it in */
3004 w += m->n_containers++;
3005 w->enclosing = type;
3006 w->signature = signature;
3008 w->array_size = array_size;
3010 w->begin = m->rindex;
3015 int sd_bus_message_exit_container(sd_bus_message *m) {
3016 struct bus_container *c;
3022 if (m->n_containers <= 0)
3025 c = message_get_container(m);
3026 if (c->enclosing == SD_BUS_TYPE_ARRAY) {
3029 l = BUS_MESSAGE_BSWAP32(m, *c->array_size);
3030 if (c->begin + l != m->rindex)
3034 if (c->signature && c->signature[c->index] != 0)
3044 static void message_quit_container(sd_bus_message *m) {
3045 struct bus_container *c;
3049 assert(m->n_containers > 0);
3051 c = message_get_container(m);
3054 assert(m->rindex >= c->before);
3055 m->rindex = c->before;
3057 /* Free container */
3061 /* Correct index of new top-level container */
3062 c = message_get_container(m);
3063 c->index = c->saved_index;
3066 int sd_bus_message_peek_type(sd_bus_message *m, char *type, const char **contents) {
3067 struct bus_container *c;
3075 c = message_get_container(m);
3077 if (!c->signature || c->signature[c->index] == 0)
3080 if (message_end_of_array(m, m->rindex))
3083 if (bus_type_is_basic(c->signature[c->index])) {
3087 *type = c->signature[c->index];
3091 if (c->signature[c->index] == SD_BUS_TYPE_ARRAY) {
3097 r = signature_element_length(c->signature+c->index+1, &l);
3103 sig = strndup(c->signature + c->index + 1, l);
3107 free(m->peeked_signature);
3108 m->peeked_signature = sig;
3114 *type = SD_BUS_TYPE_ARRAY;
3119 if (c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ||
3120 c->signature[c->index] == SD_BUS_TYPE_DICT_ENTRY_BEGIN) {
3126 r = signature_element_length(c->signature+c->index, &l);
3131 sig = strndup(c->signature + c->index + 1, l - 2);
3135 free(m->peeked_signature);
3136 m->peeked_signature = sig;
3142 *type = c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY;
3147 if (c->signature[c->index] == SD_BUS_TYPE_VARIANT) {
3153 r = message_peek_body(m, &rindex, 1, 1, &q);
3160 r = message_peek_body(m, &rindex, 1, l+1, &q);
3166 if (!validate_signature(q, l))
3173 *type = SD_BUS_TYPE_VARIANT;
3182 *type = c->enclosing;
3188 int sd_bus_message_rewind(sd_bus_message *m, int complete) {
3189 struct bus_container *c;
3197 message_reset_containers(m);
3199 m->root_container.index = 0;
3201 c = message_get_container(m);
3203 c = message_get_container(m);
3206 m->rindex = c->begin;
3209 return !isempty(c->signature);
3211 static int message_read_ap(
3216 unsigned n_array, n_struct;
3217 TypeStack stack[BUS_CONTAINER_DEPTH];
3218 unsigned stack_ptr = 0;
3226 /* Ideally, we'd just call ourselves recursively on every
3227 * complex type. However, the state of a va_list that is
3228 * passed to a function is undefined after that function
3229 * returns. This means we need to docode the va_list linearly
3230 * in a single stackframe. We hence implement our own
3231 * home-grown stack in an array. */
3233 n_array = (unsigned) -1;
3234 n_struct = strlen(types);
3239 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
3240 r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
3246 r = sd_bus_message_exit_container(m);
3254 if (n_array != (unsigned) -1)
3263 case SD_BUS_TYPE_BYTE:
3264 case SD_BUS_TYPE_BOOLEAN:
3265 case SD_BUS_TYPE_INT16:
3266 case SD_BUS_TYPE_UINT16:
3267 case SD_BUS_TYPE_INT32:
3268 case SD_BUS_TYPE_UINT32:
3269 case SD_BUS_TYPE_INT64:
3270 case SD_BUS_TYPE_UINT64:
3271 case SD_BUS_TYPE_DOUBLE:
3272 case SD_BUS_TYPE_STRING:
3273 case SD_BUS_TYPE_OBJECT_PATH:
3274 case SD_BUS_TYPE_SIGNATURE:
3275 case SD_BUS_TYPE_UNIX_FD: {
3278 p = va_arg(ap, void*);
3279 r = sd_bus_message_read_basic(m, *t, p);
3288 case SD_BUS_TYPE_ARRAY: {
3291 r = signature_element_length(t + 1, &k);
3297 memcpy(s, t + 1, k);
3300 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, s);
3307 if (n_array == (unsigned) -1) {
3312 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
3318 n_array = va_arg(ap, unsigned);
3323 case SD_BUS_TYPE_VARIANT: {
3326 s = va_arg(ap, const char *);
3330 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, s);
3336 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
3341 n_struct = strlen(s);
3342 n_array = (unsigned) -1;
3347 case SD_BUS_TYPE_STRUCT_BEGIN:
3348 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
3351 r = signature_element_length(t, &k);
3357 memcpy(s, t + 1, k - 2);
3360 r = sd_bus_message_enter_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
3367 if (n_array == (unsigned) -1) {
3372 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
3378 n_array = (unsigned) -1;
3391 int sd_bus_message_read(sd_bus_message *m, const char *types, ...) {
3402 va_start(ap, types);
3403 r = message_read_ap(m, types, ap);
3409 int sd_bus_message_read_array(sd_bus_message *m, char type, const void **ptr, size_t *size) {
3410 struct bus_container *c;
3420 if (!bus_type_is_trivial(type))
3426 if (BUS_MESSAGE_NEED_BSWAP(m))
3429 align = bus_type_get_alignment(type);
3433 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
3437 c = message_get_container(m);
3438 sz = BUS_MESSAGE_BSWAP32(m, *c->array_size);
3440 r = message_peek_body(m, &m->rindex, align, sz, &p);
3448 r = sd_bus_message_exit_container(m);
3452 *ptr = (const void*) p;
3458 message_quit_container(m);
3462 static int message_peek_fields(
3473 return buffer_peek(BUS_MESSAGE_FIELDS(m), BUS_MESSAGE_FIELDS_SIZE(m), rindex, align, nbytes, ret);
3476 static int message_peek_field_uint32(
3487 r = message_peek_fields(m, ri, 4, 4, &q);
3492 *ret = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
3497 static int message_peek_field_string(
3499 bool (*validate)(const char *p),
3510 r = message_peek_field_uint32(m, ri, &l);
3514 r = message_peek_fields(m, ri, 1, l+1, &q);
3519 if (!validate_nul(q, l))
3525 if (!validate_string(q, l))
3535 static int message_peek_field_signature(
3547 r = message_peek_fields(m, ri, 1, 1, &q);
3552 r = message_peek_fields(m, ri, 1, l+1, &q);
3556 if (!validate_signature(q, l))
3565 static int message_skip_fields(
3568 uint32_t array_size,
3569 const char **signature) {
3571 size_t original_index;
3578 original_index = *ri;
3584 if (array_size != (uint32_t) -1 &&
3585 array_size <= *ri - original_index)
3592 if (t == SD_BUS_TYPE_STRING) {
3594 r = message_peek_field_string(m, NULL, ri, NULL);
3600 } else if (t == SD_BUS_TYPE_OBJECT_PATH) {
3602 r = message_peek_field_string(m, object_path_is_valid, ri, NULL);
3608 } else if (t == SD_BUS_TYPE_SIGNATURE) {
3610 r = message_peek_field_signature(m, ri, NULL);
3616 } else if (bus_type_is_basic(t)) {
3619 align = bus_type_get_alignment(t);
3620 k = bus_type_get_size(t);
3621 assert(align > 0 && k > 0);
3623 r = message_peek_fields(m, ri, align, k, NULL);
3629 } else if (t == SD_BUS_TYPE_ARRAY) {
3631 r = signature_element_length(*signature+1, &l);
3641 strncpy(sig, *signature + 1, l-1);
3644 alignment = bus_type_get_alignment(sig[0]);
3648 r = message_peek_field_uint32(m, ri, &nas);
3651 if (nas > BUS_ARRAY_MAX_SIZE)
3654 r = message_peek_fields(m, ri, alignment, 0, NULL);
3658 r = message_skip_fields(m, ri, nas, (const char**) &s);
3663 (*signature) += 1 + l;
3665 } else if (t == SD_BUS_TYPE_VARIANT) {
3668 r = message_peek_field_signature(m, ri, &s);
3672 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
3678 } else if (t == SD_BUS_TYPE_STRUCT ||
3679 t == SD_BUS_TYPE_DICT_ENTRY) {
3681 r = signature_element_length(*signature, &l);
3688 strncpy(sig, *signature + 1, l-1);
3691 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
3702 int bus_message_parse_fields(sd_bus_message *m) {
3705 uint32_t unix_fds = 0;
3709 for (ri = 0; ri < BUS_MESSAGE_FIELDS_SIZE(m); ) {
3710 const char *signature;
3713 r = message_peek_fields(m, &ri, 8, 1, (void**) &header);
3717 r = message_peek_field_signature(m, &ri, &signature);
3722 case _SD_BUS_MESSAGE_HEADER_INVALID:
3725 case SD_BUS_MESSAGE_HEADER_PATH:
3730 if (!streq(signature, "o"))
3733 r = message_peek_field_string(m, object_path_is_valid, &ri, &m->path);
3736 case SD_BUS_MESSAGE_HEADER_INTERFACE:
3741 if (!streq(signature, "s"))
3744 r = message_peek_field_string(m, interface_name_is_valid, &ri, &m->interface);
3747 case SD_BUS_MESSAGE_HEADER_MEMBER:
3752 if (!streq(signature, "s"))
3755 r = message_peek_field_string(m, member_name_is_valid, &ri, &m->member);
3758 case SD_BUS_MESSAGE_HEADER_ERROR_NAME:
3763 if (!streq(signature, "s"))
3766 r = message_peek_field_string(m, error_name_is_valid, &ri, &m->error.name);
3769 case SD_BUS_MESSAGE_HEADER_DESTINATION:
3774 if (!streq(signature, "s"))
3777 r = message_peek_field_string(m, service_name_is_valid, &ri, &m->destination);
3780 case SD_BUS_MESSAGE_HEADER_SENDER:
3785 if (!streq(signature, "s"))
3788 r = message_peek_field_string(m, service_name_is_valid, &ri, &m->sender);
3792 case SD_BUS_MESSAGE_HEADER_SIGNATURE: {
3796 if (m->root_container.signature)
3799 if (!streq(signature, "g"))
3802 r = message_peek_field_signature(m, &ri, &s);
3810 free(m->root_container.signature);
3811 m->root_container.signature = c;
3815 case SD_BUS_MESSAGE_HEADER_REPLY_SERIAL:
3816 if (m->reply_serial != 0)
3819 if (!streq(signature, "u"))
3822 r = message_peek_field_uint32(m, &ri, &m->reply_serial);
3826 if (m->reply_serial == 0)
3831 case SD_BUS_MESSAGE_HEADER_UNIX_FDS:
3835 if (!streq(signature, "u"))
3838 r = message_peek_field_uint32(m, &ri, &unix_fds);
3848 r = message_skip_fields(m, &ri, (uint32_t) -1, (const char **) &signature);
3855 if (m->n_fds != unix_fds)
3858 if (isempty(m->root_container.signature) != (BUS_MESSAGE_BODY_SIZE(m) == 0))
3861 switch (m->header->type) {
3863 case SD_BUS_MESSAGE_TYPE_SIGNAL:
3864 if (!m->path || !m->interface || !m->member)
3868 case SD_BUS_MESSAGE_TYPE_METHOD_CALL:
3870 if (!m->path || !m->member)
3875 case SD_BUS_MESSAGE_TYPE_METHOD_RETURN:
3877 if (m->reply_serial == 0)
3881 case SD_BUS_MESSAGE_TYPE_METHOD_ERROR:
3883 if (m->reply_serial == 0 || !m->error.name)
3888 /* Try to read the error message, but if we can't it's a non-issue */
3889 if (m->header->type == SD_BUS_MESSAGE_TYPE_METHOD_ERROR)
3890 sd_bus_message_read(m, "s", &m->error.message);
3895 int bus_message_seal(sd_bus_message *m, uint64_t serial) {
3896 struct bus_body_part *part;
3906 if (m->n_containers > 0)
3912 /* If there's a non-trivial signature set, then add it in here */
3913 if (!isempty(m->root_container.signature)) {
3914 r = message_append_field_signature(m, SD_BUS_MESSAGE_HEADER_SIGNATURE, m->root_container.signature, NULL);
3920 r = message_append_field_uint32(m, SD_BUS_MESSAGE_HEADER_UNIX_FDS, m->n_fds);
3925 /* Add padding at the end of the fields part, since we know
3926 * the body needs to start at an 8 byte alignment. We made
3927 * sure we allocated enough space for this, so all we need to
3928 * do here is to zero it out. */
3929 l = BUS_MESSAGE_FIELDS_SIZE(m);
3932 memset((uint8_t*) BUS_MESSAGE_FIELDS(m) + l, 0, a);
3934 /* If this is something we can send as memfd, then let's seal
3935 the memfd now. Note that we can send memfds as payload only
3936 for directed messages, and not for broadcasts. */
3937 if (m->destination && m->bus && m->bus->use_memfd) {
3938 MESSAGE_FOREACH_PART(part, i, m)
3939 if (part->memfd >= 0 && !part->sealed && (part->size > MEMFD_MIN_SIZE || m->bus->use_memfd < 0)) {
3940 bus_body_part_unmap(part);
3942 if (ioctl(part->memfd, KDBUS_CMD_MEMFD_SEAL_SET, 1) >= 0)
3943 part->sealed = true;
3947 m->header->serial = serial;
3953 int sd_bus_message_set_destination(sd_bus_message *m, const char *destination) {
3963 return message_append_field_string(m, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &m->destination);
3966 int bus_message_dump(sd_bus_message *m) {
3967 const char *u = NULL, *uu = NULL, *s = NULL;
3968 char **cmdline = NULL;
3971 uid_t owner, audit_loginuid;
3972 uint32_t audit_sessionid;
3976 printf("Message %p\n"
3983 "\tfields_size=%u\n"
3988 "\tdestination=%s\n"
3991 "\treply_serial=%u\n"
3993 "\terror.message=%s\n"
3995 "\tn_body_parts=%u\n",
4002 BUS_MESSAGE_SERIAL(m),
4003 BUS_MESSAGE_FIELDS_SIZE(m),
4004 BUS_MESSAGE_BODY_SIZE(m),
4006 strna(m->interface),
4008 strna(m->destination),
4010 strna(m->root_container.signature),
4012 strna(m->error.name),
4013 strna(m->error.message),
4018 printf("\tpid=%lu\n", (unsigned long) m->pid);
4020 printf("\ttid=%lu\n", (unsigned long) m->tid);
4022 printf("\tuid=%lu\n", (unsigned long) m->uid);
4024 printf("\tgid=%lu\n", (unsigned long) m->gid);
4025 if (m->pid_starttime != 0)
4026 printf("\tpid_starttime=%llu\n", (unsigned long long) m->pid_starttime);
4027 if (m->monotonic != 0)
4028 printf("\tmonotonic=%llu\n", (unsigned long long) m->monotonic);
4029 if (m->realtime != 0)
4030 printf("\trealtime=%llu\n", (unsigned long long) m->realtime);
4032 printf("\texe=[%s]\n", m->exe);
4034 printf("\tcomm=[%s]\n", m->comm);
4036 printf("\ttid_comm=[%s]\n", m->tid_comm);
4038 printf("\tlabel=[%s]\n", m->label);
4040 printf("\tcgroup=[%s]\n", m->cgroup);
4042 sd_bus_message_get_unit(m, &u);
4044 printf("\tunit=[%s]\n", u);
4045 sd_bus_message_get_user_unit(m, &uu);
4047 printf("\tuser_unit=[%s]\n", uu);
4048 sd_bus_message_get_session(m, &s);
4050 printf("\tsession=[%s]\n", s);
4051 if (sd_bus_message_get_owner_uid(m, &owner) >= 0)
4052 printf("\towner_uid=%lu\n", (unsigned long) owner);
4053 if (sd_bus_message_get_audit_loginuid(m, &audit_loginuid) >= 0)
4054 printf("\taudit_loginuid=%lu\n", (unsigned long) audit_loginuid);
4055 if (sd_bus_message_get_audit_sessionid(m, &audit_sessionid) >= 0)
4056 printf("\taudit_sessionid=%lu\n", (unsigned long) audit_sessionid);
4058 printf("\tCAP_KILL=%i\n", sd_bus_message_has_effective_cap(m, 5));
4060 if (sd_bus_message_get_cmdline(m, &cmdline) >= 0) {
4063 fputs("\tcmdline=[", stdout);
4064 STRV_FOREACH(c, cmdline) {
4071 fputs("]\n", stdout);
4074 r = sd_bus_message_rewind(m, true);
4076 log_error("Failed to rewind: %s", strerror(-r));
4080 printf("BEGIN_MESSAGE \"%s\" {\n", strempty(m->root_container.signature));
4083 _cleanup_free_ char *prefix = NULL;
4084 const char *contents = NULL;
4099 r = sd_bus_message_peek_type(m, &type, &contents);
4101 log_error("Failed to peek type: %s", strerror(-r));
4108 r = sd_bus_message_exit_container(m);
4110 log_error("Failed to exit container: %s", strerror(-r));
4116 prefix = strrep("\t", level);
4120 if (type == SD_BUS_TYPE_ARRAY)
4121 printf("%s} END_ARRAY \n", prefix);
4122 else if (type == SD_BUS_TYPE_VARIANT)
4123 printf("%s} END_VARIANT\n", prefix);
4124 else if (type == SD_BUS_TYPE_STRUCT)
4125 printf("%s} END_STRUCT\n", prefix);
4126 else if (type == SD_BUS_TYPE_DICT_ENTRY)
4127 printf("%s} END_DICT_ENTRY\n", prefix);
4132 prefix = strrep("\t", level);
4136 if (bus_type_is_container(type) > 0) {
4137 r = sd_bus_message_enter_container(m, type, contents);
4139 log_error("Failed to enter container: %s", strerror(-r));
4143 if (type == SD_BUS_TYPE_ARRAY)
4144 printf("%sBEGIN_ARRAY \"%s\" {\n", prefix, contents);
4145 else if (type == SD_BUS_TYPE_VARIANT)
4146 printf("%sBEGIN_VARIANT \"%s\" {\n", prefix, contents);
4147 else if (type == SD_BUS_TYPE_STRUCT)
4148 printf("%sBEGIN_STRUCT \"%s\" {\n", prefix, contents);
4149 else if (type == SD_BUS_TYPE_DICT_ENTRY)
4150 printf("%sBEGIN_DICT_ENTRY \"%s\" {\n", prefix, contents);
4157 r = sd_bus_message_read_basic(m, type, &basic);
4159 log_error("Failed to get basic: %s", strerror(-r));
4165 case SD_BUS_TYPE_BYTE:
4166 printf("%sBYTE: %u\n", prefix, basic.u8);
4169 case SD_BUS_TYPE_BOOLEAN:
4170 printf("%sBOOLEAN: %s\n", prefix, yes_no(basic.i));
4173 case SD_BUS_TYPE_INT16:
4174 printf("%sINT16: %i\n", prefix, basic.s16);
4177 case SD_BUS_TYPE_UINT16:
4178 printf("%sUINT16: %u\n", prefix, basic.u16);
4181 case SD_BUS_TYPE_INT32:
4182 printf("%sINT32: %i\n", prefix, basic.s32);
4185 case SD_BUS_TYPE_UINT32:
4186 printf("%sUINT32: %u\n", prefix, basic.u32);
4189 case SD_BUS_TYPE_INT64:
4190 printf("%sINT64: %lli\n", prefix, (long long) basic.s64);
4193 case SD_BUS_TYPE_UINT64:
4194 printf("%sUINT64: %llu\n", prefix, (unsigned long long) basic.u64);
4197 case SD_BUS_TYPE_DOUBLE:
4198 printf("%sDOUBLE: %g\n", prefix, basic.d64);
4201 case SD_BUS_TYPE_STRING:
4202 printf("%sSTRING: \"%s\"\n", prefix, basic.string);
4205 case SD_BUS_TYPE_OBJECT_PATH:
4206 printf("%sOBJECT_PATH: \"%s\"\n", prefix, basic.string);
4209 case SD_BUS_TYPE_SIGNATURE:
4210 printf("%sSIGNATURE: \"%s\"\n", prefix, basic.string);
4213 case SD_BUS_TYPE_UNIX_FD:
4214 printf("%sUNIX_FD: %i\n", prefix, basic.i);
4218 assert_not_reached("Unknown basic type.");
4222 printf("} END_MESSAGE\n");
4226 int bus_message_get_blob(sd_bus_message *m, void **buffer, size_t *sz) {
4230 struct bus_body_part *part;
4236 total = BUS_MESSAGE_SIZE(m);
4242 e = mempcpy(p, m->header, BUS_MESSAGE_BODY_BEGIN(m));
4243 MESSAGE_FOREACH_PART(part, i, m)
4244 e = mempcpy(e, part->data, part->size);
4246 assert(total == (size_t) ((uint8_t*) e - (uint8_t*) p));
4254 int bus_message_read_strv_extend(sd_bus_message *m, char ***l) {
4260 r = sd_bus_message_enter_container(m, 'a', "s");
4267 r = sd_bus_message_read_basic(m, 's', &s);
4273 r = strv_extend(l, s);
4278 r = sd_bus_message_exit_container(m);
4285 const char* bus_message_get_arg(sd_bus_message *m, unsigned i) {
4287 const char *t = NULL;
4292 r = sd_bus_message_rewind(m, true);
4296 for (j = 0; j <= i; j++) {
4299 r = sd_bus_message_peek_type(m, &type, NULL);
4303 if (type != SD_BUS_TYPE_STRING &&
4304 type != SD_BUS_TYPE_OBJECT_PATH &&
4305 type != SD_BUS_TYPE_SIGNATURE)
4308 r = sd_bus_message_read_basic(m, type, &t);
4316 bool bus_header_is_complete(struct bus_header *h, size_t size) {
4322 if (size < sizeof(struct bus_header))
4325 full = sizeof(struct bus_header) +
4326 (h->endian == SD_BUS_NATIVE_ENDIAN ? h->fields_size : bswap_32(h->fields_size));
4328 return size >= full;
4331 int bus_header_message_size(struct bus_header *h, size_t *sum) {
4337 if (h->endian == SD_BUS_NATIVE_ENDIAN) {
4338 fs = h->fields_size;
4340 } else if (h->endian == SD_BUS_REVERSE_ENDIAN) {
4341 fs = bswap_32(h->fields_size);
4342 bs = bswap_32(h->body_size);
4346 *sum = sizeof(struct bus_header) + ALIGN8(fs) + bs;
4350 int bus_message_to_errno(sd_bus_message *m) {
4353 if (m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_ERROR)
4356 return bus_error_to_errno(&m->error);
4359 int sd_bus_message_get_signature(sd_bus_message *m, int complete, const char **signature) {
4360 struct bus_container *c;
4367 c = complete ? &m->root_container : message_get_container(m);
4368 *signature = c->signature ?: "";