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) {
505 if (bus && bus->state == BUS_UNSET)
508 t = message_new(bus, SD_BUS_MESSAGE_TYPE_METHOD_CALL);
512 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_PATH, SD_BUS_TYPE_OBJECT_PATH, path, &t->path);
515 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_MEMBER, SD_BUS_TYPE_STRING, member, &t->member);
520 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_INTERFACE, SD_BUS_TYPE_STRING, interface, &t->interface);
526 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &t->destination);
539 static int message_new_reply(
541 sd_bus_message *call,
543 sd_bus_message **m) {
552 if (call->header->type != SD_BUS_MESSAGE_TYPE_METHOD_CALL)
556 if (bus && bus->state == BUS_UNSET)
559 t = message_new(bus, type);
563 t->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
564 t->reply_serial = BUS_MESSAGE_SERIAL(call);
566 r = message_append_field_uint32(t, SD_BUS_MESSAGE_HEADER_REPLY_SERIAL, t->reply_serial);
571 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, call->sender, &t->destination);
576 t->dont_send = !!(call->header->flags & SD_BUS_MESSAGE_NO_REPLY_EXPECTED);
586 int sd_bus_message_new_method_return(
588 sd_bus_message *call,
589 sd_bus_message **m) {
591 return message_new_reply(bus, call, SD_BUS_MESSAGE_TYPE_METHOD_RETURN, m);
594 int sd_bus_message_new_method_error(
596 sd_bus_message *call,
597 const sd_bus_error *e,
598 sd_bus_message **m) {
603 if (!sd_bus_error_is_set(e))
608 r = message_new_reply(bus, call, SD_BUS_MESSAGE_TYPE_METHOD_ERROR, &t);
612 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_ERROR_NAME, SD_BUS_TYPE_STRING, e->name, &t->error.name);
617 r = message_append_basic(t, SD_BUS_TYPE_STRING, e->message, (const void**) &t->error.message);
630 int bus_message_new_synthetic_error(
633 const sd_bus_error *e,
634 sd_bus_message **m) {
639 assert(sd_bus_error_is_set(e));
642 t = message_new(bus, SD_BUS_MESSAGE_TYPE_METHOD_ERROR);
646 t->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
647 t->reply_serial = serial;
649 r = message_append_field_uint32(t, SD_BUS_MESSAGE_HEADER_REPLY_SERIAL, t->reply_serial);
653 if (bus && bus->unique_name) {
654 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, bus->unique_name, &t->destination);
667 sd_bus_message* sd_bus_message_ref(sd_bus_message *m) {
671 assert(m->n_ref > 0);
677 sd_bus_message* sd_bus_message_unref(sd_bus_message *m) {
681 assert(m->n_ref > 0);
690 int sd_bus_message_get_type(sd_bus_message *m, uint8_t *type) {
696 *type = m->header->type;
700 int sd_bus_message_get_serial(sd_bus_message *m, uint64_t *serial) {
705 if (m->header->serial == 0)
708 *serial = BUS_MESSAGE_SERIAL(m);
712 int sd_bus_message_get_reply_serial(sd_bus_message *m, uint64_t *serial) {
717 if (m->reply_serial == 0)
720 *serial = m->reply_serial;
724 int sd_bus_message_get_no_reply(sd_bus_message *m) {
728 return m->header->type == SD_BUS_MESSAGE_TYPE_METHOD_CALL ? !!(m->header->flags & SD_BUS_MESSAGE_NO_REPLY_EXPECTED) : 0;
731 const char *sd_bus_message_get_path(sd_bus_message *m) {
738 const char *sd_bus_message_get_interface(sd_bus_message *m) {
745 const char *sd_bus_message_get_member(sd_bus_message *m) {
751 const char *sd_bus_message_get_destination(sd_bus_message *m) {
755 return m->destination;
758 const char *sd_bus_message_get_sender(sd_bus_message *m) {
765 const sd_bus_error *sd_bus_message_get_error(sd_bus_message *m) {
769 if (!sd_bus_error_is_set(&m->error))
775 int sd_bus_message_get_uid(sd_bus_message *m, uid_t *uid) {
787 int sd_bus_message_get_gid(sd_bus_message *m, gid_t *gid) {
799 int sd_bus_message_get_pid(sd_bus_message *m, pid_t *pid) {
811 int sd_bus_message_get_tid(sd_bus_message *m, pid_t *tid) {
823 int sd_bus_message_get_pid_starttime(sd_bus_message *m, uint64_t *usec) {
828 if (m->pid_starttime <= 0)
831 *usec = m->pid_starttime;
835 int sd_bus_message_get_selinux_context(sd_bus_message *m, const char **ret) {
845 int sd_bus_message_get_monotonic_timestamp(sd_bus_message *m, uint64_t *usec) {
850 if (m->monotonic <= 0)
853 *usec = m->monotonic;
857 int sd_bus_message_get_realtime_timestamp(sd_bus_message *m, uint64_t *usec) {
862 if (m->realtime <= 0)
869 int sd_bus_message_get_comm(sd_bus_message *m, const char **ret) {
881 int sd_bus_message_get_tid_comm(sd_bus_message *m, const char **ret) {
893 int sd_bus_message_get_exe(sd_bus_message *m, const char **ret) {
905 int sd_bus_message_get_cgroup(sd_bus_message *m, const char **ret) {
917 int sd_bus_message_get_unit(sd_bus_message *m, const char **ret) {
928 r = cg_path_get_unit(m->cgroup, &m->unit);
937 int sd_bus_message_get_user_unit(sd_bus_message *m, const char **ret) {
948 r = cg_path_get_user_unit(m->cgroup, &m->user_unit);
957 int sd_bus_message_get_session(sd_bus_message *m, const char **ret) {
968 r = cg_path_get_session(m->cgroup, &m->session);
977 int sd_bus_message_get_owner_uid(sd_bus_message *m, uid_t *uid) {
985 return cg_path_get_owner_uid(m->cgroup, uid);
988 int sd_bus_message_get_cmdline(sd_bus_message *m, char ***cmdline) {
999 for (p = m->cmdline, n = 0; p < m->cmdline + m->cmdline_length; p++)
1003 m->cmdline_array = new(char*, n + 1);
1004 if (!m->cmdline_array)
1007 for (p = m->cmdline, i = 0, first = true; p < m->cmdline + m->cmdline_length; p++) {
1009 m->cmdline_array[i++] = (char*) p;
1014 m->cmdline_array[i] = NULL;
1015 *cmdline = m->cmdline_array;
1020 int sd_bus_message_get_audit_sessionid(sd_bus_message *m, uint32_t *sessionid) {
1028 *sessionid = m->audit->sessionid;
1032 int sd_bus_message_get_audit_loginuid(sd_bus_message *m, uid_t *uid) {
1040 *uid = m->audit->loginuid;
1044 int sd_bus_message_has_effective_cap(sd_bus_message *m, int capability) {
1054 sz = m->capability_size / 4;
1055 if ((unsigned) capability >= sz*8)
1058 return !!(m->capability[2 * sz + (capability / 8)] & (1 << (capability % 8)));
1061 int sd_bus_message_is_signal(sd_bus_message *m, const char *interface, const char *member) {
1065 if (m->header->type != SD_BUS_MESSAGE_TYPE_SIGNAL)
1068 if (interface && (!m->interface || !streq(m->interface, interface)))
1071 if (member && (!m->member || !streq(m->member, member)))
1077 int sd_bus_message_is_method_call(sd_bus_message *m, const char *interface, const char *member) {
1081 if (m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_CALL)
1084 if (interface && (!m->interface || !streq(m->interface, interface)))
1087 if (member && (!m->member || !streq(m->member, member)))
1093 int sd_bus_message_is_method_error(sd_bus_message *m, const char *name) {
1097 if (m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_ERROR)
1100 if (name && (!m->error.name || !streq(m->error.name, name)))
1106 int sd_bus_message_set_no_reply(sd_bus_message *m, int b) {
1111 if (m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_CALL)
1115 m->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
1117 m->header->flags &= ~SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
1122 static struct bus_container *message_get_container(sd_bus_message *m) {
1125 if (m->n_containers == 0)
1126 return &m->root_container;
1128 assert(m->containers);
1129 return m->containers + m->n_containers - 1;
1132 struct bus_body_part *message_append_part(sd_bus_message *m) {
1133 struct bus_body_part *part;
1140 if (m->n_body_parts <= 0) {
1144 assert(m->body_end);
1146 part = new0(struct bus_body_part, 1);
1152 m->body_end->next = part;
1162 static void part_zero(struct bus_body_part *part, size_t sz) {
1167 /* All other fields can be left in their defaults */
1168 assert(!part->data);
1169 assert(part->memfd < 0);
1172 part->is_zero = true;
1173 part->sealed = true;
1176 static int part_make_space(
1177 struct sd_bus_message *m,
1178 struct bus_body_part *part,
1187 assert(!part->sealed);
1192 if (!part->data && part->memfd < 0)
1193 part->memfd = bus_kernel_pop_memfd(m->bus, &part->data, &part->mapped);
1195 if (part->memfd >= 0) {
1198 r = ioctl(part->memfd, KDBUS_CMD_MEMFD_SIZE_SET, &u);
1204 if (!part->data || sz > part->mapped) {
1205 size_t psz = PAGE_ALIGN(sz > 0 ? sz : 1);
1207 if (part->mapped <= 0)
1208 n = mmap(NULL, psz, PROT_READ|PROT_WRITE, MAP_SHARED, part->memfd, 0);
1210 n = mremap(part->data, part->mapped, psz, MREMAP_MAYMOVE);
1212 if (n == MAP_FAILED) {
1219 part->munmap_this = true;
1222 n = realloc(part->data, sz);
1229 part->free_this = true;
1233 *q = part->data ? (uint8_t*) part->data + part->size : NULL;
1239 static void message_extend_containers(sd_bus_message *m, size_t expand) {
1240 struct bus_container *c;
1247 /* Update counters */
1248 for (c = m->containers; c < m->containers + m->n_containers; c++)
1250 *c->array_size += expand;
1253 static void *message_extend_body(sd_bus_message *m, size_t align, size_t sz) {
1254 struct bus_body_part *part = NULL;
1255 size_t start_body, end_body, padding, start_part, end_part, added;
1267 start_body = ALIGN_TO((size_t) m->header->body_size, align);
1268 end_body = start_body + sz;
1270 padding = start_body - m->header->body_size;
1271 added = padding + sz;
1273 /* Check for 32bit overflows */
1274 if (end_body > (size_t) ((uint32_t) -1)) {
1280 m->n_body_parts <= 0 ||
1281 m->body_end->sealed ||
1282 padding != ALIGN_TO(m->body_end->size, align) - m->body_end->size;
1286 part = message_append_part(m);
1290 part_zero(part, padding);
1293 part = message_append_part(m);
1297 r = part_make_space(m, part, sz, &p);
1301 struct bus_container *c;
1309 start_part = ALIGN_TO(part->size, align);
1310 end_part = start_part + sz;
1312 r = part_make_space(m, part, end_part, &p);
1317 memset(p, 0, padding);
1318 p = (uint8_t*) p + padding;
1321 /* Readjust pointers */
1322 for (c = m->containers; c < m->containers + m->n_containers; c++)
1323 c->array_size = adjust_pointer(c->array_size, op, os, part->data);
1325 m->error.message = (const char*) adjust_pointer(m->error.message, op, os, part->data);
1328 m->header->body_size = end_body;
1329 message_extend_containers(m, added);
1334 int message_append_basic(sd_bus_message *m, char type, const void *p, const void **stored) {
1335 struct bus_container *c;
1349 if (!bus_type_is_basic(type))
1354 c = message_get_container(m);
1356 if (c->signature && c->signature[c->index]) {
1357 /* Container signature is already set */
1359 if (c->signature[c->index] != type)
1364 /* Maybe we can append to the signature? But only if this is the top-level container*/
1365 if (c->enclosing != 0)
1368 e = strextend(&c->signature, CHAR_TO_STR(type), NULL);
1377 case SD_BUS_TYPE_STRING:
1378 case SD_BUS_TYPE_OBJECT_PATH:
1381 sz = 4 + strlen(p) + 1;
1384 case SD_BUS_TYPE_SIGNATURE:
1387 sz = 1 + strlen(p) + 1;
1390 case SD_BUS_TYPE_BOOLEAN:
1393 assert_cc(sizeof(int) == sizeof(uint32_t));
1399 case SD_BUS_TYPE_UNIX_FD: {
1402 if (!m->allow_fds) {
1415 fd = fcntl(z, F_DUPFD_CLOEXEC, 3);
1421 f = realloc(m->fds, sizeof(int) * (m->n_fds + 1));
1436 align = bus_type_get_alignment(type);
1437 sz = bus_type_get_size(type);
1444 a = message_extend_body(m, align, sz);
1450 if (type == SD_BUS_TYPE_STRING || type == SD_BUS_TYPE_OBJECT_PATH) {
1451 *(uint32_t*) a = sz - 5;
1452 memcpy((uint8_t*) a + 4, p, sz - 4);
1455 *stored = (const uint8_t*) a + 4;
1457 } else if (type == SD_BUS_TYPE_SIGNATURE) {
1458 *(uint8_t*) a = sz - 1;
1459 memcpy((uint8_t*) a + 1, p, sz - 1);
1462 *stored = (const uint8_t*) a + 1;
1463 } else if (type == SD_BUS_TYPE_UNIX_FD) {
1464 *(uint32_t*) a = fdi;
1478 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1485 close_nointr_nofail(fd);
1490 int sd_bus_message_append_basic(sd_bus_message *m, char type, const void *p) {
1491 return message_append_basic(m, type, p, NULL);
1494 int sd_bus_message_append_string_space(sd_bus_message *m, size_t size, char **s) {
1495 struct bus_container *c;
1507 c = message_get_container(m);
1509 if (c->signature && c->signature[c->index]) {
1510 /* Container signature is already set */
1512 if (c->signature[c->index] != SD_BUS_TYPE_STRING)
1517 /* Maybe we can append to the signature? But only if this is the top-level container*/
1518 if (c->enclosing != 0)
1521 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRING), NULL);
1528 a = message_extend_body(m, 4, 4 + size + 1);
1532 *(uint32_t*) a = size;
1537 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1543 static int bus_message_open_array(
1545 struct bus_container *c,
1546 const char *contents,
1547 uint32_t **array_size) {
1553 struct bus_body_part *o;
1560 if (!signature_is_single(contents))
1563 alignment = bus_type_get_alignment(contents[0]);
1567 if (c->signature && c->signature[c->index]) {
1569 /* Verify the existing signature */
1571 if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
1574 if (!startswith(c->signature + c->index + 1, contents))
1577 nindex = c->index + 1 + strlen(contents);
1581 if (c->enclosing != 0)
1584 /* Extend the existing signature */
1586 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_ARRAY), contents, NULL);
1592 nindex = e - c->signature;
1595 a = message_extend_body(m, 4, 4);
1600 op = m->body_end->data;
1601 os = m->body_end->size;
1603 /* Add alignment between size and first element */
1604 if (!message_extend_body(m, alignment, 0))
1607 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1610 /* location of array size might have changed so let's readjust a */
1611 if (o == m->body_end)
1612 a = adjust_pointer(a, op, os, m->body_end->data);
1619 static int bus_message_open_variant(
1621 struct bus_container *c,
1622 const char *contents) {
1631 if (!signature_is_single(contents))
1634 if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
1637 if (c->signature && c->signature[c->index]) {
1639 if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
1645 if (c->enclosing != 0)
1648 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_VARIANT), NULL);
1655 l = strlen(contents);
1656 a = message_extend_body(m, 1, 1 + l + 1);
1661 memcpy((uint8_t*) a + 1, contents, l + 1);
1663 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1669 static int bus_message_open_struct(
1671 struct bus_container *c,
1672 const char *contents) {
1680 if (!signature_is_valid(contents, false))
1683 if (c->signature && c->signature[c->index]) {
1686 l = strlen(contents);
1688 if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
1689 !startswith(c->signature + c->index + 1, contents) ||
1690 c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
1693 nindex = c->index + 1 + l + 1;
1697 if (c->enclosing != 0)
1700 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_BEGIN), contents, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_END), NULL);
1706 nindex = e - c->signature;
1709 /* Align contents to 8 byte boundary */
1710 if (!message_extend_body(m, 8, 0))
1713 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1719 static int bus_message_open_dict_entry(
1721 struct bus_container *c,
1722 const char *contents) {
1730 if (!signature_is_pair(contents))
1733 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1736 if (c->signature && c->signature[c->index]) {
1739 l = strlen(contents);
1741 if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
1742 !startswith(c->signature + c->index + 1, contents) ||
1743 c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
1746 nindex = c->index + 1 + l + 1;
1750 /* Align contents to 8 byte boundary */
1751 if (!message_extend_body(m, 8, 0))
1754 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1760 int sd_bus_message_open_container(
1763 const char *contents) {
1765 struct bus_container *c, *w;
1766 uint32_t *array_size = NULL;
1780 /* Make sure we have space for one more container */
1781 w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
1789 c = message_get_container(m);
1791 signature = strdup(contents);
1797 /* Save old index in the parent container, in case we have to
1798 * abort this container */
1799 c->saved_index = c->index;
1800 before = m->header->body_size;
1802 if (type == SD_BUS_TYPE_ARRAY)
1803 r = bus_message_open_array(m, c, contents, &array_size);
1804 else if (type == SD_BUS_TYPE_VARIANT)
1805 r = bus_message_open_variant(m, c, contents);
1806 else if (type == SD_BUS_TYPE_STRUCT)
1807 r = bus_message_open_struct(m, c, contents);
1808 else if (type == SD_BUS_TYPE_DICT_ENTRY)
1809 r = bus_message_open_dict_entry(m, c, contents);
1818 /* OK, let's fill it in */
1819 w += m->n_containers++;
1820 w->enclosing = type;
1821 w->signature = signature;
1823 w->array_size = array_size;
1825 w->begin = m->rindex;
1830 int sd_bus_message_close_container(sd_bus_message *m) {
1831 struct bus_container *c;
1837 if (m->n_containers <= 0)
1842 c = message_get_container(m);
1843 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1844 if (c->signature && c->signature[c->index] != 0)
1859 static int type_stack_push(TypeStack *stack, unsigned max, unsigned *i, const char *types, unsigned n_struct, unsigned n_array) {
1866 stack[*i].types = types;
1867 stack[*i].n_struct = n_struct;
1868 stack[*i].n_array = n_array;
1874 static int type_stack_pop(TypeStack *stack, unsigned max, unsigned *i, const char **types, unsigned *n_struct, unsigned *n_array) {
1885 *types = stack[*i].types;
1886 *n_struct = stack[*i].n_struct;
1887 *n_array = stack[*i].n_array;
1892 int bus_message_append_ap(
1897 unsigned n_array, n_struct;
1898 TypeStack stack[BUS_CONTAINER_DEPTH];
1899 unsigned stack_ptr = 0;
1907 n_array = (unsigned) -1;
1908 n_struct = strlen(types);
1913 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
1914 r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
1920 r = sd_bus_message_close_container(m);
1928 if (n_array != (unsigned) -1)
1937 case SD_BUS_TYPE_BYTE: {
1940 x = (uint8_t) va_arg(ap, int);
1941 r = sd_bus_message_append_basic(m, *t, &x);
1945 case SD_BUS_TYPE_BOOLEAN:
1946 case SD_BUS_TYPE_INT32:
1947 case SD_BUS_TYPE_UINT32:
1948 case SD_BUS_TYPE_UNIX_FD: {
1951 /* We assume a boolean is the same as int32_t */
1952 assert_cc(sizeof(int32_t) == sizeof(int));
1954 x = va_arg(ap, uint32_t);
1955 r = sd_bus_message_append_basic(m, *t, &x);
1959 case SD_BUS_TYPE_INT16:
1960 case SD_BUS_TYPE_UINT16: {
1963 x = (uint16_t) va_arg(ap, int);
1964 r = sd_bus_message_append_basic(m, *t, &x);
1968 case SD_BUS_TYPE_INT64:
1969 case SD_BUS_TYPE_UINT64:
1970 case SD_BUS_TYPE_DOUBLE: {
1973 x = va_arg(ap, uint64_t);
1974 r = sd_bus_message_append_basic(m, *t, &x);
1978 case SD_BUS_TYPE_STRING:
1979 case SD_BUS_TYPE_OBJECT_PATH:
1980 case SD_BUS_TYPE_SIGNATURE: {
1983 x = va_arg(ap, const char*);
1984 r = sd_bus_message_append_basic(m, *t, x);
1988 case SD_BUS_TYPE_ARRAY: {
1991 r = signature_element_length(t + 1, &k);
1997 memcpy(s, t + 1, k);
2000 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, s);
2005 if (n_array == (unsigned) -1) {
2010 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2016 n_array = va_arg(ap, unsigned);
2021 case SD_BUS_TYPE_VARIANT: {
2024 s = va_arg(ap, const char*);
2028 r = sd_bus_message_open_container(m, SD_BUS_TYPE_VARIANT, s);
2032 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2037 n_struct = strlen(s);
2038 n_array = (unsigned) -1;
2043 case SD_BUS_TYPE_STRUCT_BEGIN:
2044 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
2047 r = signature_element_length(t, &k);
2054 memcpy(s, t + 1, k - 2);
2057 r = sd_bus_message_open_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
2062 if (n_array == (unsigned) -1) {
2067 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2073 n_array = (unsigned) -1;
2089 int sd_bus_message_append(sd_bus_message *m, const char *types, ...) {
2102 va_start(ap, types);
2103 r = bus_message_append_ap(m, types, ap);
2109 int sd_bus_message_append_array_space(sd_bus_message *m, char type, size_t size, void **ptr) {
2118 if (!bus_type_is_trivial(type))
2120 if (!ptr && size > 0)
2125 align = bus_type_get_alignment(type);
2126 sz = bus_type_get_size(type);
2128 assert_se(align > 0);
2134 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
2138 a = message_extend_body(m, align, size);
2142 r = sd_bus_message_close_container(m);
2150 int sd_bus_message_append_array(sd_bus_message *m, char type, const void *ptr, size_t size) {
2154 if (!ptr && size > 0)
2157 r = sd_bus_message_append_array_space(m, type, size, &p);
2162 memcpy(p, ptr, size);
2167 int sd_bus_message_append_array_memfd(sd_bus_message *m, char type, sd_memfd *memfd) {
2168 _cleanup_close_ int copy_fd = -1;
2169 struct bus_body_part *part;
2181 if (!bus_type_is_trivial(type))
2186 r = sd_memfd_set_sealed(memfd, true);
2190 copy_fd = sd_memfd_dup_fd(memfd);
2194 r = sd_memfd_get_size(memfd, &size);
2198 align = bus_type_get_alignment(type);
2199 sz = bus_type_get_size(type);
2201 assert_se(align > 0);
2207 if (size > (uint64_t) (uint32_t) -1)
2210 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
2214 a = message_extend_body(m, align, 0);
2218 part = message_append_part(m);
2222 part->memfd = copy_fd;
2223 part->sealed = true;
2227 message_extend_containers(m, size);
2228 m->header->body_size += size;
2230 return sd_bus_message_close_container(m);
2233 int sd_bus_message_append_string_memfd(sd_bus_message *m, sd_memfd *memfd) {
2234 _cleanup_close_ int copy_fd = -1;
2235 struct bus_body_part *part;
2236 struct bus_container *c;
2250 r = sd_memfd_set_sealed(memfd, true);
2254 copy_fd = sd_memfd_dup_fd(memfd);
2258 r = sd_memfd_get_size(memfd, &size);
2262 /* We require this to be NUL terminated */
2266 if (size > (uint64_t) (uint32_t) -1)
2269 c = message_get_container(m);
2270 if (c->signature && c->signature[c->index]) {
2271 /* Container signature is already set */
2273 if (c->signature[c->index] != SD_BUS_TYPE_STRING)
2278 /* Maybe we can append to the signature? But only if this is the top-level container*/
2279 if (c->enclosing != 0)
2282 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRING), NULL);
2289 a = message_extend_body(m, 4, 4);
2293 *(uint32_t*) a = size - 1;
2295 part = message_append_part(m);
2299 part->memfd = copy_fd;
2300 part->sealed = true;
2304 message_extend_containers(m, size);
2305 m->header->body_size += size;
2307 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2313 int bus_body_part_map(struct bus_body_part *part) {
2322 if (part->size <= 0)
2325 /* For smaller zero parts (as used for padding) we don't need to map anything... */
2326 if (part->memfd < 0 && part->is_zero && part->size < 8) {
2327 static const uint8_t zeroes[7] = { };
2328 part->data = (void*) zeroes;
2332 psz = PAGE_ALIGN(part->size);
2334 if (part->memfd >= 0)
2335 p = mmap(NULL, psz, PROT_READ, MAP_SHARED, part->memfd, 0);
2336 else if (part->is_zero)
2337 p = mmap(NULL, psz, PROT_READ, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
2341 if (p == MAP_FAILED)
2346 part->munmap_this = true;
2351 void bus_body_part_unmap(struct bus_body_part *part) {
2355 if (part->memfd < 0)
2361 if (!part->munmap_this)
2364 assert_se(munmap(part->data, part->mapped) == 0);
2368 part->munmap_this = false;
2373 static int buffer_peek(const void *p, uint32_t sz, size_t *rindex, size_t align, size_t nbytes, void **r) {
2374 size_t k, start, end;
2379 start = ALIGN_TO((size_t) *rindex, align);
2380 end = start + nbytes;
2385 /* Verify that padding is 0 */
2386 for (k = *rindex; k < start; k++)
2387 if (((const uint8_t*) p)[k] != 0)
2391 *r = (uint8_t*) p + start;
2398 static bool message_end_of_array(sd_bus_message *m, size_t index) {
2399 struct bus_container *c;
2403 c = message_get_container(m);
2407 return index >= c->begin + BUS_MESSAGE_BSWAP32(m, *c->array_size);
2410 static struct bus_body_part* find_part(sd_bus_message *m, size_t index, size_t sz, void **p) {
2411 struct bus_body_part *part;
2417 if (m->cached_rindex_part && index >= m->cached_rindex_part_begin) {
2418 part = m->cached_rindex_part;
2419 begin = m->cached_rindex_part_begin;
2429 if (index + sz <= begin + part->size) {
2431 r = bus_body_part_map(part);
2436 *p = (uint8_t*) part->data + index - begin;
2438 m->cached_rindex_part = part;
2439 m->cached_rindex_part_begin = begin;
2444 begin += part->size;
2451 static int message_peek_body(
2458 size_t k, start, end, padding;
2459 struct bus_body_part *part;
2466 if (message_end_of_array(m, *rindex))
2469 start = ALIGN_TO((size_t) *rindex, align);
2470 padding = start - *rindex;
2471 end = start + nbytes;
2473 if (end > BUS_MESSAGE_BODY_SIZE(m))
2476 part = find_part(m, *rindex, padding, (void**) &q);
2481 /* Verify padding */
2482 for (k = 0; k < padding; k++)
2487 part = find_part(m, start, nbytes, (void**) &q);
2499 static bool validate_nul(const char *s, size_t l) {
2501 /* Check for NUL chars in the string */
2502 if (memchr(s, 0, l))
2505 /* Check for NUL termination */
2512 static bool validate_string(const char *s, size_t l) {
2514 if (!validate_nul(s, l))
2517 /* Check if valid UTF8 */
2518 if (!utf8_is_valid(s))
2524 static bool validate_signature(const char *s, size_t l) {
2526 if (!validate_nul(s, l))
2529 /* Check if valid signature */
2530 if (!signature_is_valid(s, true))
2536 static bool validate_object_path(const char *s, size_t l) {
2538 if (!validate_nul(s, l))
2541 if (!object_path_is_valid(s))
2547 int sd_bus_message_read_basic(sd_bus_message *m, char type, void *p) {
2548 struct bus_container *c;
2556 if (!bus_type_is_basic(type))
2561 c = message_get_container(m);
2563 if (!c->signature || c->signature[c->index] == 0)
2566 if (c->signature[c->index] != type)
2571 case SD_BUS_TYPE_STRING:
2572 case SD_BUS_TYPE_OBJECT_PATH: {
2577 r = message_peek_body(m, &rindex, 4, 4, &q);
2581 l = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2582 r = message_peek_body(m, &rindex, 1, l+1, &q);
2588 if (type == SD_BUS_TYPE_OBJECT_PATH) {
2589 if (!validate_object_path(q, l))
2592 if (!validate_string(q, l))
2597 *(const char**) p = q;
2601 case SD_BUS_TYPE_SIGNATURE: {
2606 r = message_peek_body(m, &rindex, 1, 1, &q);
2611 r = message_peek_body(m, &rindex, 1, l+1, &q);
2617 if (!validate_signature(q, l))
2621 *(const char**) p = q;
2629 align = bus_type_get_alignment(type);
2630 sz = bus_type_get_size(type);
2631 assert(align > 0 && sz > 0);
2634 r = message_peek_body(m, &rindex, align, sz, &q);
2640 case SD_BUS_TYPE_BYTE:
2641 *(uint8_t*) p = *(uint8_t*) q;
2644 case SD_BUS_TYPE_BOOLEAN:
2645 *(int*) p = !!*(uint32_t*) q;
2648 case SD_BUS_TYPE_INT16:
2649 case SD_BUS_TYPE_UINT16:
2650 *(uint16_t*) p = BUS_MESSAGE_BSWAP16(m, *(uint16_t*) q);
2653 case SD_BUS_TYPE_INT32:
2654 case SD_BUS_TYPE_UINT32:
2655 *(uint32_t*) p = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2658 case SD_BUS_TYPE_INT64:
2659 case SD_BUS_TYPE_UINT64:
2660 case SD_BUS_TYPE_DOUBLE:
2661 *(uint64_t*) p = BUS_MESSAGE_BSWAP64(m, *(uint64_t*) q);
2664 case SD_BUS_TYPE_UNIX_FD: {
2667 j = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2671 *(int*) p = m->fds[j];
2676 assert_not_reached("Unknown basic type...");
2685 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2691 static int bus_message_enter_array(
2693 struct bus_container *c,
2694 const char *contents,
2695 uint32_t **array_size) {
2706 if (!signature_is_single(contents))
2709 alignment = bus_type_get_alignment(contents[0]);
2713 if (!c->signature || c->signature[c->index] == 0)
2716 if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
2719 if (!startswith(c->signature + c->index + 1, contents))
2723 r = message_peek_body(m, &rindex, 4, 4, &q);
2727 if (BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q) > BUS_ARRAY_MAX_SIZE)
2730 r = message_peek_body(m, &rindex, alignment, 0, NULL);
2736 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2737 c->index += 1 + strlen(contents);
2741 *array_size = (uint32_t*) q;
2746 static int bus_message_enter_variant(
2748 struct bus_container *c,
2749 const char *contents) {
2760 if (!signature_is_single(contents))
2763 if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
2766 if (!c->signature || c->signature[c->index] == 0)
2769 if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
2773 r = message_peek_body(m, &rindex, 1, 1, &q);
2778 r = message_peek_body(m, &rindex, 1, l+1, &q);
2784 if (!validate_signature(q, l))
2787 if (!streq(q, contents))
2790 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2798 static int bus_message_enter_struct(
2800 struct bus_container *c,
2801 const char *contents) {
2810 if (!signature_is_valid(contents, false))
2813 if (!c->signature || c->signature[c->index] == 0)
2816 l = strlen(contents);
2818 if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
2819 !startswith(c->signature + c->index + 1, contents) ||
2820 c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
2823 r = message_peek_body(m, &m->rindex, 8, 0, NULL);
2827 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2828 c->index += 1 + l + 1;
2833 static int bus_message_enter_dict_entry(
2835 struct bus_container *c,
2836 const char *contents) {
2845 if (!signature_is_pair(contents))
2848 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2851 if (!c->signature || c->signature[c->index] == 0)
2854 l = strlen(contents);
2856 if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
2857 !startswith(c->signature + c->index + 1, contents) ||
2858 c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
2861 r = message_peek_body(m, &m->rindex, 8, 0, NULL);
2865 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2866 c->index += 1 + l + 1;
2871 int sd_bus_message_enter_container(sd_bus_message *m, char type, const char *contents) {
2872 struct bus_container *c, *w;
2873 uint32_t *array_size = NULL;
2886 * We enforce a global limit on container depth, that is much
2887 * higher than the 32 structs and 32 arrays the specification
2888 * mandates. This is simpler to implement for us, and we need
2889 * this only to ensure our container array doesn't grow
2890 * without bounds. We are happy to return any data from a
2891 * message as long as the data itself is valid, even if the
2892 * overall message might be not.
2894 * Note that the message signature is validated when
2895 * parsing the headers, and that validation does check the
2898 * Note that the specification defines no limits on the depth
2899 * of stacked variants, but we do.
2901 if (m->n_containers >= BUS_CONTAINER_DEPTH)
2904 w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
2909 c = message_get_container(m);
2911 if (!c->signature || c->signature[c->index] == 0)
2914 signature = strdup(contents);
2918 c->saved_index = c->index;
2921 if (type == SD_BUS_TYPE_ARRAY)
2922 r = bus_message_enter_array(m, c, contents, &array_size);
2923 else if (type == SD_BUS_TYPE_VARIANT)
2924 r = bus_message_enter_variant(m, c, contents);
2925 else if (type == SD_BUS_TYPE_STRUCT)
2926 r = bus_message_enter_struct(m, c, contents);
2927 else if (type == SD_BUS_TYPE_DICT_ENTRY)
2928 r = bus_message_enter_dict_entry(m, c, contents);
2937 /* OK, let's fill it in */
2938 w += m->n_containers++;
2939 w->enclosing = type;
2940 w->signature = signature;
2942 w->array_size = array_size;
2944 w->begin = m->rindex;
2949 int sd_bus_message_exit_container(sd_bus_message *m) {
2950 struct bus_container *c;
2956 if (m->n_containers <= 0)
2959 c = message_get_container(m);
2960 if (c->enclosing == SD_BUS_TYPE_ARRAY) {
2963 l = BUS_MESSAGE_BSWAP32(m, *c->array_size);
2964 if (c->begin + l != m->rindex)
2968 if (c->signature && c->signature[c->index] != 0)
2978 static void message_quit_container(sd_bus_message *m) {
2979 struct bus_container *c;
2983 assert(m->n_containers > 0);
2985 c = message_get_container(m);
2988 assert(m->rindex >= c->before);
2989 m->rindex = c->before;
2991 /* Free container */
2995 /* Correct index of new top-level container */
2996 c = message_get_container(m);
2997 c->index = c->saved_index;
3000 int sd_bus_message_peek_type(sd_bus_message *m, char *type, const char **contents) {
3001 struct bus_container *c;
3009 c = message_get_container(m);
3011 if (!c->signature || c->signature[c->index] == 0)
3014 if (message_end_of_array(m, m->rindex))
3017 if (bus_type_is_basic(c->signature[c->index])) {
3021 *type = c->signature[c->index];
3025 if (c->signature[c->index] == SD_BUS_TYPE_ARRAY) {
3031 r = signature_element_length(c->signature+c->index+1, &l);
3037 sig = strndup(c->signature + c->index + 1, l);
3041 free(m->peeked_signature);
3042 m->peeked_signature = sig;
3048 *type = SD_BUS_TYPE_ARRAY;
3053 if (c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ||
3054 c->signature[c->index] == SD_BUS_TYPE_DICT_ENTRY_BEGIN) {
3060 r = signature_element_length(c->signature+c->index, &l);
3065 sig = strndup(c->signature + c->index + 1, l - 2);
3069 free(m->peeked_signature);
3070 m->peeked_signature = sig;
3076 *type = c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY;
3081 if (c->signature[c->index] == SD_BUS_TYPE_VARIANT) {
3087 r = message_peek_body(m, &rindex, 1, 1, &q);
3094 r = message_peek_body(m, &rindex, 1, l+1, &q);
3100 if (!validate_signature(q, l))
3107 *type = SD_BUS_TYPE_VARIANT;
3116 *type = c->enclosing;
3122 int sd_bus_message_rewind(sd_bus_message *m, int complete) {
3123 struct bus_container *c;
3131 message_reset_containers(m);
3133 m->root_container.index = 0;
3135 c = message_get_container(m);
3137 c = message_get_container(m);
3140 m->rindex = c->begin;
3143 return !isempty(c->signature);
3145 static int message_read_ap(
3150 unsigned n_array, n_struct;
3151 TypeStack stack[BUS_CONTAINER_DEPTH];
3152 unsigned stack_ptr = 0;
3160 /* Ideally, we'd just call ourselves recursively on every
3161 * complex type. However, the state of a va_list that is
3162 * passed to a function is undefined after that function
3163 * returns. This means we need to docode the va_list linearly
3164 * in a single stackframe. We hence implement our own
3165 * home-grown stack in an array. */
3167 n_array = (unsigned) -1;
3168 n_struct = strlen(types);
3173 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
3174 r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
3180 r = sd_bus_message_exit_container(m);
3188 if (n_array != (unsigned) -1)
3197 case SD_BUS_TYPE_BYTE:
3198 case SD_BUS_TYPE_BOOLEAN:
3199 case SD_BUS_TYPE_INT16:
3200 case SD_BUS_TYPE_UINT16:
3201 case SD_BUS_TYPE_INT32:
3202 case SD_BUS_TYPE_UINT32:
3203 case SD_BUS_TYPE_INT64:
3204 case SD_BUS_TYPE_UINT64:
3205 case SD_BUS_TYPE_DOUBLE:
3206 case SD_BUS_TYPE_STRING:
3207 case SD_BUS_TYPE_OBJECT_PATH:
3208 case SD_BUS_TYPE_SIGNATURE:
3209 case SD_BUS_TYPE_UNIX_FD: {
3212 p = va_arg(ap, void*);
3213 r = sd_bus_message_read_basic(m, *t, p);
3222 case SD_BUS_TYPE_ARRAY: {
3225 r = signature_element_length(t + 1, &k);
3231 memcpy(s, t + 1, k);
3234 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, s);
3241 if (n_array == (unsigned) -1) {
3246 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
3252 n_array = va_arg(ap, unsigned);
3257 case SD_BUS_TYPE_VARIANT: {
3260 s = va_arg(ap, const char *);
3264 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, s);
3270 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
3275 n_struct = strlen(s);
3276 n_array = (unsigned) -1;
3281 case SD_BUS_TYPE_STRUCT_BEGIN:
3282 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
3285 r = signature_element_length(t, &k);
3291 memcpy(s, t + 1, k - 2);
3294 r = sd_bus_message_enter_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
3301 if (n_array == (unsigned) -1) {
3306 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
3312 n_array = (unsigned) -1;
3325 int sd_bus_message_read(sd_bus_message *m, const char *types, ...) {
3336 va_start(ap, types);
3337 r = message_read_ap(m, types, ap);
3343 int sd_bus_message_read_array(sd_bus_message *m, char type, const void **ptr, size_t *size) {
3344 struct bus_container *c;
3354 if (!bus_type_is_trivial(type))
3360 if (BUS_MESSAGE_NEED_BSWAP(m))
3363 align = bus_type_get_alignment(type);
3367 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
3371 c = message_get_container(m);
3372 sz = BUS_MESSAGE_BSWAP32(m, *c->array_size);
3374 r = message_peek_body(m, &m->rindex, align, sz, &p);
3382 r = sd_bus_message_exit_container(m);
3386 *ptr = (const void*) p;
3392 message_quit_container(m);
3396 static int message_peek_fields(
3407 return buffer_peek(BUS_MESSAGE_FIELDS(m), BUS_MESSAGE_FIELDS_SIZE(m), rindex, align, nbytes, ret);
3410 static int message_peek_field_uint32(
3421 r = message_peek_fields(m, ri, 4, 4, &q);
3426 *ret = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
3431 static int message_peek_field_string(
3433 bool (*validate)(const char *p),
3444 r = message_peek_field_uint32(m, ri, &l);
3448 r = message_peek_fields(m, ri, 1, l+1, &q);
3453 if (!validate_nul(q, l))
3459 if (!validate_string(q, l))
3469 static int message_peek_field_signature(
3481 r = message_peek_fields(m, ri, 1, 1, &q);
3486 r = message_peek_fields(m, ri, 1, l+1, &q);
3490 if (!validate_signature(q, l))
3499 static int message_skip_fields(
3502 uint32_t array_size,
3503 const char **signature) {
3505 size_t original_index;
3512 original_index = *ri;
3518 if (array_size != (uint32_t) -1 &&
3519 array_size <= *ri - original_index)
3526 if (t == SD_BUS_TYPE_STRING) {
3528 r = message_peek_field_string(m, NULL, ri, NULL);
3534 } else if (t == SD_BUS_TYPE_OBJECT_PATH) {
3536 r = message_peek_field_string(m, object_path_is_valid, ri, NULL);
3542 } else if (t == SD_BUS_TYPE_SIGNATURE) {
3544 r = message_peek_field_signature(m, ri, NULL);
3550 } else if (bus_type_is_basic(t)) {
3553 align = bus_type_get_alignment(t);
3554 k = bus_type_get_size(t);
3555 assert(align > 0 && k > 0);
3557 r = message_peek_fields(m, ri, align, k, NULL);
3563 } else if (t == SD_BUS_TYPE_ARRAY) {
3565 r = signature_element_length(*signature+1, &l);
3575 strncpy(sig, *signature + 1, l-1);
3578 alignment = bus_type_get_alignment(sig[0]);
3582 r = message_peek_field_uint32(m, ri, &nas);
3585 if (nas > BUS_ARRAY_MAX_SIZE)
3588 r = message_peek_fields(m, ri, alignment, 0, NULL);
3592 r = message_skip_fields(m, ri, nas, (const char**) &s);
3597 (*signature) += 1 + l;
3599 } else if (t == SD_BUS_TYPE_VARIANT) {
3602 r = message_peek_field_signature(m, ri, &s);
3606 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
3612 } else if (t == SD_BUS_TYPE_STRUCT ||
3613 t == SD_BUS_TYPE_DICT_ENTRY) {
3615 r = signature_element_length(*signature, &l);
3622 strncpy(sig, *signature + 1, l-1);
3625 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
3636 int bus_message_parse_fields(sd_bus_message *m) {
3639 uint32_t unix_fds = 0;
3643 for (ri = 0; ri < BUS_MESSAGE_FIELDS_SIZE(m); ) {
3644 const char *signature;
3647 r = message_peek_fields(m, &ri, 8, 1, (void**) &header);
3651 r = message_peek_field_signature(m, &ri, &signature);
3656 case _SD_BUS_MESSAGE_HEADER_INVALID:
3659 case SD_BUS_MESSAGE_HEADER_PATH:
3664 if (!streq(signature, "o"))
3667 r = message_peek_field_string(m, object_path_is_valid, &ri, &m->path);
3670 case SD_BUS_MESSAGE_HEADER_INTERFACE:
3675 if (!streq(signature, "s"))
3678 r = message_peek_field_string(m, interface_name_is_valid, &ri, &m->interface);
3681 case SD_BUS_MESSAGE_HEADER_MEMBER:
3686 if (!streq(signature, "s"))
3689 r = message_peek_field_string(m, member_name_is_valid, &ri, &m->member);
3692 case SD_BUS_MESSAGE_HEADER_ERROR_NAME:
3697 if (!streq(signature, "s"))
3700 r = message_peek_field_string(m, error_name_is_valid, &ri, &m->error.name);
3703 case SD_BUS_MESSAGE_HEADER_DESTINATION:
3708 if (!streq(signature, "s"))
3711 r = message_peek_field_string(m, service_name_is_valid, &ri, &m->destination);
3714 case SD_BUS_MESSAGE_HEADER_SENDER:
3719 if (!streq(signature, "s"))
3722 r = message_peek_field_string(m, service_name_is_valid, &ri, &m->sender);
3726 case SD_BUS_MESSAGE_HEADER_SIGNATURE: {
3730 if (m->root_container.signature)
3733 if (!streq(signature, "g"))
3736 r = message_peek_field_signature(m, &ri, &s);
3744 free(m->root_container.signature);
3745 m->root_container.signature = c;
3749 case SD_BUS_MESSAGE_HEADER_REPLY_SERIAL:
3750 if (m->reply_serial != 0)
3753 if (!streq(signature, "u"))
3756 r = message_peek_field_uint32(m, &ri, &m->reply_serial);
3760 if (m->reply_serial == 0)
3765 case SD_BUS_MESSAGE_HEADER_UNIX_FDS:
3769 if (!streq(signature, "u"))
3772 r = message_peek_field_uint32(m, &ri, &unix_fds);
3782 r = message_skip_fields(m, &ri, (uint32_t) -1, (const char **) &signature);
3789 if (m->n_fds != unix_fds)
3792 if (isempty(m->root_container.signature) != (BUS_MESSAGE_BODY_SIZE(m) == 0))
3795 switch (m->header->type) {
3797 case SD_BUS_MESSAGE_TYPE_SIGNAL:
3798 if (!m->path || !m->interface || !m->member)
3802 case SD_BUS_MESSAGE_TYPE_METHOD_CALL:
3804 if (!m->path || !m->member)
3809 case SD_BUS_MESSAGE_TYPE_METHOD_RETURN:
3811 if (m->reply_serial == 0)
3815 case SD_BUS_MESSAGE_TYPE_METHOD_ERROR:
3817 if (m->reply_serial == 0 || !m->error.name)
3822 /* Try to read the error message, but if we can't it's a non-issue */
3823 if (m->header->type == SD_BUS_MESSAGE_TYPE_METHOD_ERROR)
3824 sd_bus_message_read(m, "s", &m->error.message);
3829 int bus_message_seal(sd_bus_message *m, uint64_t serial) {
3830 struct bus_body_part *part;
3840 if (m->n_containers > 0)
3846 /* If there's a non-trivial signature set, then add it in here */
3847 if (!isempty(m->root_container.signature)) {
3848 r = message_append_field_signature(m, SD_BUS_MESSAGE_HEADER_SIGNATURE, m->root_container.signature, NULL);
3854 r = message_append_field_uint32(m, SD_BUS_MESSAGE_HEADER_UNIX_FDS, m->n_fds);
3859 /* Add padding at the end of the fields part, since we know
3860 * the body needs to start at an 8 byte alignment. We made
3861 * sure we allocated enough space for this, so all we need to
3862 * do here is to zero it out. */
3863 l = BUS_MESSAGE_FIELDS_SIZE(m);
3866 memset((uint8_t*) BUS_MESSAGE_FIELDS(m) + l, 0, a);
3868 /* If this is something we can send as memfd, then let's seal
3869 the memfd now. Note that we can send memfds as payload only
3870 for directed messages, and not for broadcasts. */
3871 if (m->destination && m->bus && m->bus->use_memfd) {
3872 MESSAGE_FOREACH_PART(part, i, m)
3873 if (part->memfd >= 0 && !part->sealed && (part->size > MEMFD_MIN_SIZE || m->bus->use_memfd < 0)) {
3874 bus_body_part_unmap(part);
3876 if (ioctl(part->memfd, KDBUS_CMD_MEMFD_SEAL_SET, 1) >= 0)
3877 part->sealed = true;
3881 m->header->serial = serial;
3887 int sd_bus_message_set_destination(sd_bus_message *m, const char *destination) {
3897 return message_append_field_string(m, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &m->destination);
3900 int bus_message_dump(sd_bus_message *m) {
3901 const char *u = NULL, *uu = NULL, *s = NULL;
3902 char **cmdline = NULL;
3905 uid_t owner, audit_loginuid;
3906 uint32_t audit_sessionid;
3910 printf("Message %p\n"
3917 "\tfields_size=%u\n"
3922 "\tdestination=%s\n"
3925 "\treply_serial=%u\n"
3927 "\terror.message=%s\n"
3929 "\tn_body_parts=%u\n",
3936 BUS_MESSAGE_SERIAL(m),
3937 BUS_MESSAGE_FIELDS_SIZE(m),
3938 BUS_MESSAGE_BODY_SIZE(m),
3940 strna(m->interface),
3942 strna(m->destination),
3944 strna(m->root_container.signature),
3946 strna(m->error.name),
3947 strna(m->error.message),
3952 printf("\tpid=%lu\n", (unsigned long) m->pid);
3954 printf("\ttid=%lu\n", (unsigned long) m->tid);
3956 printf("\tuid=%lu\n", (unsigned long) m->uid);
3958 printf("\tgid=%lu\n", (unsigned long) m->gid);
3959 if (m->pid_starttime != 0)
3960 printf("\tpid_starttime=%llu\n", (unsigned long long) m->pid_starttime);
3961 if (m->monotonic != 0)
3962 printf("\tmonotonic=%llu\n", (unsigned long long) m->monotonic);
3963 if (m->realtime != 0)
3964 printf("\trealtime=%llu\n", (unsigned long long) m->realtime);
3966 printf("\texe=[%s]\n", m->exe);
3968 printf("\tcomm=[%s]\n", m->comm);
3970 printf("\ttid_comm=[%s]\n", m->tid_comm);
3972 printf("\tlabel=[%s]\n", m->label);
3974 printf("\tcgroup=[%s]\n", m->cgroup);
3976 sd_bus_message_get_unit(m, &u);
3978 printf("\tunit=[%s]\n", u);
3979 sd_bus_message_get_user_unit(m, &uu);
3981 printf("\tuser_unit=[%s]\n", uu);
3982 sd_bus_message_get_session(m, &s);
3984 printf("\tsession=[%s]\n", s);
3985 if (sd_bus_message_get_owner_uid(m, &owner) >= 0)
3986 printf("\towner_uid=%lu\n", (unsigned long) owner);
3987 if (sd_bus_message_get_audit_loginuid(m, &audit_loginuid) >= 0)
3988 printf("\taudit_loginuid=%lu\n", (unsigned long) audit_loginuid);
3989 if (sd_bus_message_get_audit_sessionid(m, &audit_sessionid) >= 0)
3990 printf("\taudit_sessionid=%lu\n", (unsigned long) audit_sessionid);
3992 printf("\tCAP_KILL=%i\n", sd_bus_message_has_effective_cap(m, 5));
3994 if (sd_bus_message_get_cmdline(m, &cmdline) >= 0) {
3997 fputs("\tcmdline=[", stdout);
3998 STRV_FOREACH(c, cmdline) {
4005 fputs("]\n", stdout);
4008 r = sd_bus_message_rewind(m, true);
4010 log_error("Failed to rewind: %s", strerror(-r));
4014 printf("BEGIN_MESSAGE \"%s\" {\n", strempty(m->root_container.signature));
4017 _cleanup_free_ char *prefix = NULL;
4018 const char *contents = NULL;
4033 r = sd_bus_message_peek_type(m, &type, &contents);
4035 log_error("Failed to peek type: %s", strerror(-r));
4042 r = sd_bus_message_exit_container(m);
4044 log_error("Failed to exit container: %s", strerror(-r));
4050 prefix = strrep("\t", level);
4054 if (type == SD_BUS_TYPE_ARRAY)
4055 printf("%s} END_ARRAY \n", prefix);
4056 else if (type == SD_BUS_TYPE_VARIANT)
4057 printf("%s} END_VARIANT\n", prefix);
4058 else if (type == SD_BUS_TYPE_STRUCT)
4059 printf("%s} END_STRUCT\n", prefix);
4060 else if (type == SD_BUS_TYPE_DICT_ENTRY)
4061 printf("%s} END_DICT_ENTRY\n", prefix);
4066 prefix = strrep("\t", level);
4070 if (bus_type_is_container(type) > 0) {
4071 r = sd_bus_message_enter_container(m, type, contents);
4073 log_error("Failed to enter container: %s", strerror(-r));
4077 if (type == SD_BUS_TYPE_ARRAY)
4078 printf("%sBEGIN_ARRAY \"%s\" {\n", prefix, contents);
4079 else if (type == SD_BUS_TYPE_VARIANT)
4080 printf("%sBEGIN_VARIANT \"%s\" {\n", prefix, contents);
4081 else if (type == SD_BUS_TYPE_STRUCT)
4082 printf("%sBEGIN_STRUCT \"%s\" {\n", prefix, contents);
4083 else if (type == SD_BUS_TYPE_DICT_ENTRY)
4084 printf("%sBEGIN_DICT_ENTRY \"%s\" {\n", prefix, contents);
4091 r = sd_bus_message_read_basic(m, type, &basic);
4093 log_error("Failed to get basic: %s", strerror(-r));
4099 case SD_BUS_TYPE_BYTE:
4100 printf("%sBYTE: %u\n", prefix, basic.u8);
4103 case SD_BUS_TYPE_BOOLEAN:
4104 printf("%sBOOLEAN: %s\n", prefix, yes_no(basic.i));
4107 case SD_BUS_TYPE_INT16:
4108 printf("%sINT16: %i\n", prefix, basic.s16);
4111 case SD_BUS_TYPE_UINT16:
4112 printf("%sUINT16: %u\n", prefix, basic.u16);
4115 case SD_BUS_TYPE_INT32:
4116 printf("%sINT32: %i\n", prefix, basic.s32);
4119 case SD_BUS_TYPE_UINT32:
4120 printf("%sUINT32: %u\n", prefix, basic.u32);
4123 case SD_BUS_TYPE_INT64:
4124 printf("%sINT64: %lli\n", prefix, (long long) basic.s64);
4127 case SD_BUS_TYPE_UINT64:
4128 printf("%sUINT64: %llu\n", prefix, (unsigned long long) basic.u64);
4131 case SD_BUS_TYPE_DOUBLE:
4132 printf("%sDOUBLE: %g\n", prefix, basic.d64);
4135 case SD_BUS_TYPE_STRING:
4136 printf("%sSTRING: \"%s\"\n", prefix, basic.string);
4139 case SD_BUS_TYPE_OBJECT_PATH:
4140 printf("%sOBJECT_PATH: \"%s\"\n", prefix, basic.string);
4143 case SD_BUS_TYPE_SIGNATURE:
4144 printf("%sSIGNATURE: \"%s\"\n", prefix, basic.string);
4147 case SD_BUS_TYPE_UNIX_FD:
4148 printf("%sUNIX_FD: %i\n", prefix, basic.i);
4152 assert_not_reached("Unknown basic type.");
4156 printf("} END_MESSAGE\n");
4160 int bus_message_get_blob(sd_bus_message *m, void **buffer, size_t *sz) {
4164 struct bus_body_part *part;
4170 total = BUS_MESSAGE_SIZE(m);
4176 e = mempcpy(p, m->header, BUS_MESSAGE_BODY_BEGIN(m));
4177 MESSAGE_FOREACH_PART(part, i, m)
4178 e = mempcpy(e, part->data, part->size);
4180 assert(total == (size_t) ((uint8_t*) e - (uint8_t*) p));
4188 int bus_message_read_strv_extend(sd_bus_message *m, char ***l) {
4194 r = sd_bus_message_enter_container(m, 'a', "s");
4201 r = sd_bus_message_read_basic(m, 's', &s);
4207 r = strv_extend(l, s);
4212 r = sd_bus_message_exit_container(m);
4219 const char* bus_message_get_arg(sd_bus_message *m, unsigned i) {
4221 const char *t = NULL;
4226 r = sd_bus_message_rewind(m, true);
4230 for (j = 0; j <= i; j++) {
4233 r = sd_bus_message_peek_type(m, &type, NULL);
4237 if (type != SD_BUS_TYPE_STRING &&
4238 type != SD_BUS_TYPE_OBJECT_PATH &&
4239 type != SD_BUS_TYPE_SIGNATURE)
4242 r = sd_bus_message_read_basic(m, type, &t);
4250 bool bus_header_is_complete(struct bus_header *h, size_t size) {
4256 if (size < sizeof(struct bus_header))
4259 full = sizeof(struct bus_header) +
4260 (h->endian == SD_BUS_NATIVE_ENDIAN ? h->fields_size : bswap_32(h->fields_size));
4262 return size >= full;
4265 int bus_header_message_size(struct bus_header *h, size_t *sum) {
4271 if (h->endian == SD_BUS_NATIVE_ENDIAN) {
4272 fs = h->fields_size;
4274 } else if (h->endian == SD_BUS_REVERSE_ENDIAN) {
4275 fs = bswap_32(h->fields_size);
4276 bs = bswap_32(h->body_size);
4280 *sum = sizeof(struct bus_header) + ALIGN8(fs) + bs;
4284 int bus_message_to_errno(sd_bus_message *m) {
4287 if (m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_ERROR)
4290 return bus_error_to_errno(&m->error);