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) {
64 bus_kernel_push_memfd(m->bus, part->memfd, part->data, part->mapped);
67 assert_se(munmap(part->data, PAGE_ALIGN(part->size)) == 0);
69 close_nointr_nofail(part->memfd);
72 } else if (part->munmap_this)
73 munmap(part->data, part->mapped);
74 else if (part->free_this)
81 static void message_reset_parts(sd_bus_message *m) {
82 struct bus_body_part *part;
87 while (m->n_body_parts > 0) {
88 struct bus_body_part *next = part->next;
89 message_free_part(m, part);
96 m->cached_rindex_part = NULL;
97 m->cached_rindex_part_begin = 0;
100 static void message_reset_containers(sd_bus_message *m) {
105 for (i = 0; i < m->n_containers; i++)
106 free(m->containers[i].signature);
109 m->containers = NULL;
112 m->root_container.index = 0;
115 static void message_free(sd_bus_message *m) {
121 message_reset_parts(m);
126 if (m->release_kdbus)
127 ioctl(m->bus->input_fd, KDBUS_CMD_MSG_RELEASE, m->kdbus);
130 close_many(m->fds, m->n_fds);
135 sd_bus_unref(m->bus);
137 if (m->iovec != m->iovec_fixed)
140 free(m->cmdline_array);
142 message_reset_containers(m);
143 free(m->root_container.signature);
145 free(m->peeked_signature);
153 static void *message_extend_fields(sd_bus_message *m, size_t align, size_t sz) {
155 size_t old_size, new_size, start;
162 old_size = sizeof(struct bus_header) + m->header->fields_size;
163 start = ALIGN_TO(old_size, align);
164 new_size = start + sz;
166 if (old_size == new_size)
167 return (uint8_t*) m->header + old_size;
169 if (new_size > (size_t) ((uint32_t) -1))
172 if (m->free_header) {
173 np = realloc(m->header, ALIGN8(new_size));
177 /* Initially, the header is allocated as part of of
178 * the sd_bus_message itself, let's replace it by
181 np = malloc(ALIGN8(new_size));
185 memcpy(np, m->header, sizeof(struct bus_header));
188 /* Zero out padding */
189 if (start > old_size)
190 memset((uint8_t*) np + old_size, 0, start - old_size);
194 m->header->fields_size = new_size - sizeof(struct bus_header);
196 /* Adjust quick access pointers */
197 m->path = adjust_pointer(m->path, op, old_size, m->header);
198 m->interface = adjust_pointer(m->interface, op, old_size, m->header);
199 m->member = adjust_pointer(m->member, op, old_size, m->header);
200 m->destination = adjust_pointer(m->destination, op, old_size, m->header);
201 m->sender = adjust_pointer(m->sender, op, old_size, m->header);
202 m->error.name = adjust_pointer(m->error.name, op, old_size, m->header);
204 m->free_header = true;
206 return (uint8_t*) np + start;
213 static int message_append_field_string(
226 if (l > (size_t) (uint32_t) -1)
229 /* field id byte + signature length + signature 's' + NUL + string length + string + NUL */
230 p = message_extend_fields(m, 8, 4 + 4 + l + 1);
239 ((uint32_t*) p)[1] = l;
240 memcpy(p + 8, s, l + 1);
243 *ret = (char*) p + 8;
248 static int message_append_field_signature(
263 /* field id byte + signature length + signature 'g' + NUL + string length + string + NUL */
264 p = message_extend_fields(m, 8, 4 + 1 + l + 1);
270 p[2] = SD_BUS_TYPE_SIGNATURE;
273 memcpy(p + 5, s, l + 1);
276 *ret = (const char*) p + 5;
281 static int message_append_field_uint32(sd_bus_message *m, uint8_t h, uint32_t x) {
286 /* field id byte + signature length + signature 'u' + NUL + value */
287 p = message_extend_fields(m, 8, 4 + 4);
293 p[2] = SD_BUS_TYPE_UINT32;
296 ((uint32_t*) p)[1] = x;
301 int bus_message_from_header(
306 const struct ucred *ucred,
309 sd_bus_message **ret) {
312 struct bus_header *h;
315 assert(buffer || length <= 0);
316 assert(fds || n_fds <= 0);
319 if (length < sizeof(struct bus_header))
329 if (h->type == _SD_BUS_MESSAGE_TYPE_INVALID)
332 if (h->endian != SD_BUS_LITTLE_ENDIAN &&
333 h->endian != SD_BUS_BIG_ENDIAN)
336 a = ALIGN(sizeof(sd_bus_message)) + ALIGN(extra);
339 label_sz = strlen(label);
357 m->uid_valid = m->gid_valid = true;
361 m->label = (char*) m + ALIGN(sizeof(sd_bus_message)) + ALIGN(extra);
362 memcpy(m->label, label, label_sz + 1);
369 int bus_message_from_malloc(
374 const struct ucred *ucred,
376 sd_bus_message **ret) {
381 r = bus_message_from_header(buffer, length, fds, n_fds, ucred, label, 0, &m);
385 if (length != BUS_MESSAGE_SIZE(m)) {
391 m->body.data = (uint8_t*) buffer + sizeof(struct bus_header) + ALIGN8(BUS_MESSAGE_FIELDS_SIZE(m));
392 m->body.size = length - sizeof(struct bus_header) - ALIGN8(BUS_MESSAGE_FIELDS_SIZE(m));
393 m->body.sealed = true;
397 m->iovec = m->iovec_fixed;
398 m->iovec[0].iov_base = buffer;
399 m->iovec[0].iov_len = length;
401 r = bus_message_parse_fields(m);
405 /* We take possession of the memory and fds now */
406 m->free_header = true;
417 static sd_bus_message *message_new(sd_bus *bus, uint8_t type) {
420 m = malloc0(ALIGN(sizeof(sd_bus_message)) + sizeof(struct bus_header));
425 m->header = (struct bus_header*) ((uint8_t*) m + ALIGN(sizeof(struct sd_bus_message)));
426 m->header->endian = SD_BUS_NATIVE_ENDIAN;
427 m->header->type = type;
428 m->header->version = bus ? bus->message_version : 1;
429 m->allow_fds = !bus || bus->can_fds || (bus->state != BUS_HELLO && bus->state != BUS_RUNNING);
432 m->bus = sd_bus_ref(bus);
437 int sd_bus_message_new_signal(
440 const char *interface,
442 sd_bus_message **m) {
455 if (bus && bus->state == BUS_UNSET)
458 t = message_new(bus, SD_BUS_MESSAGE_TYPE_SIGNAL);
462 t->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
464 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_PATH, SD_BUS_TYPE_OBJECT_PATH, path, &t->path);
467 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_INTERFACE, SD_BUS_TYPE_STRING, interface, &t->interface);
470 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_MEMBER, SD_BUS_TYPE_STRING, member, &t->member);
478 sd_bus_message_unref(t);
482 int sd_bus_message_new_method_call(
484 const char *destination,
486 const char *interface,
488 sd_bus_message **m) {
499 if (bus && bus->state == BUS_UNSET)
502 t = message_new(bus, SD_BUS_MESSAGE_TYPE_METHOD_CALL);
506 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_PATH, SD_BUS_TYPE_OBJECT_PATH, path, &t->path);
509 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_MEMBER, SD_BUS_TYPE_STRING, member, &t->member);
514 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_INTERFACE, SD_BUS_TYPE_STRING, interface, &t->interface);
520 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &t->destination);
533 static int message_new_reply(
535 sd_bus_message *call,
537 sd_bus_message **m) {
546 if (call->header->type != SD_BUS_MESSAGE_TYPE_METHOD_CALL)
550 if (bus && bus->state == BUS_UNSET)
553 t = message_new(bus, type);
557 t->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
558 t->reply_serial = BUS_MESSAGE_SERIAL(call);
560 r = message_append_field_uint32(t, SD_BUS_MESSAGE_HEADER_REPLY_SERIAL, t->reply_serial);
565 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, call->sender, &t->sender);
570 t->dont_send = !!(call->header->flags & SD_BUS_MESSAGE_NO_REPLY_EXPECTED);
580 int sd_bus_message_new_method_return(
582 sd_bus_message *call,
583 sd_bus_message **m) {
585 return message_new_reply(bus, call, SD_BUS_MESSAGE_TYPE_METHOD_RETURN, m);
588 int sd_bus_message_new_method_error(
590 sd_bus_message *call,
591 const sd_bus_error *e,
592 sd_bus_message **m) {
597 if (!sd_bus_error_is_set(e))
602 r = message_new_reply(bus, call, SD_BUS_MESSAGE_TYPE_METHOD_ERROR, &t);
606 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_ERROR_NAME, SD_BUS_TYPE_STRING, e->name, &t->error.name);
611 r = message_append_basic(t, SD_BUS_TYPE_STRING, e->message, (const void**) &t->error.message);
624 sd_bus_message* sd_bus_message_ref(sd_bus_message *m) {
628 assert(m->n_ref > 0);
634 sd_bus_message* sd_bus_message_unref(sd_bus_message *m) {
638 assert(m->n_ref > 0);
647 int sd_bus_message_get_type(sd_bus_message *m, uint8_t *type) {
653 *type = m->header->type;
657 int sd_bus_message_get_serial(sd_bus_message *m, uint64_t *serial) {
662 if (m->header->serial == 0)
665 *serial = BUS_MESSAGE_SERIAL(m);
669 int sd_bus_message_get_reply_serial(sd_bus_message *m, uint64_t *serial) {
674 if (m->reply_serial == 0)
677 *serial = m->reply_serial;
681 int sd_bus_message_get_no_reply(sd_bus_message *m) {
685 return m->header->type == SD_BUS_MESSAGE_TYPE_METHOD_CALL ? !!(m->header->flags & SD_BUS_MESSAGE_NO_REPLY_EXPECTED) : 0;
688 const char *sd_bus_message_get_path(sd_bus_message *m) {
695 const char *sd_bus_message_get_interface(sd_bus_message *m) {
702 const char *sd_bus_message_get_member(sd_bus_message *m) {
708 const char *sd_bus_message_get_destination(sd_bus_message *m) {
712 return m->destination;
715 const char *sd_bus_message_get_sender(sd_bus_message *m) {
722 const sd_bus_error *sd_bus_message_get_error(sd_bus_message *m) {
726 if (!sd_bus_error_is_set(&m->error))
732 int sd_bus_message_get_uid(sd_bus_message *m, uid_t *uid) {
744 int sd_bus_message_get_gid(sd_bus_message *m, gid_t *gid) {
756 int sd_bus_message_get_pid(sd_bus_message *m, pid_t *pid) {
768 int sd_bus_message_get_tid(sd_bus_message *m, pid_t *tid) {
780 int sd_bus_message_get_pid_starttime(sd_bus_message *m, uint64_t *usec) {
785 if (m->pid_starttime <= 0)
788 *usec = m->pid_starttime;
792 int sd_bus_message_get_selinux_context(sd_bus_message *m, const char **ret) {
802 int sd_bus_message_get_monotonic_timestamp(sd_bus_message *m, uint64_t *usec) {
807 if (m->monotonic <= 0)
810 *usec = m->monotonic;
814 int sd_bus_message_get_realtime_timestamp(sd_bus_message *m, uint64_t *usec) {
819 if (m->realtime <= 0)
826 int sd_bus_message_get_comm(sd_bus_message *m, const char **ret) {
838 int sd_bus_message_get_tid_comm(sd_bus_message *m, const char **ret) {
850 int sd_bus_message_get_exe(sd_bus_message *m, const char **ret) {
862 int sd_bus_message_get_cgroup(sd_bus_message *m, const char **ret) {
874 int sd_bus_message_get_unit(sd_bus_message *m, const char **ret) {
885 r = cg_path_get_unit(m->cgroup, &m->unit);
894 int sd_bus_message_get_user_unit(sd_bus_message *m, const char **ret) {
905 r = cg_path_get_user_unit(m->cgroup, &m->user_unit);
914 int sd_bus_message_get_session(sd_bus_message *m, const char **ret) {
925 r = cg_path_get_session(m->cgroup, &m->session);
934 int sd_bus_message_get_owner_uid(sd_bus_message *m, uid_t *uid) {
942 return cg_path_get_owner_uid(m->cgroup, uid);
945 int sd_bus_message_get_cmdline(sd_bus_message *m, char ***cmdline) {
956 for (p = m->cmdline, n = 0; p < m->cmdline + m->cmdline_length; p++)
960 m->cmdline_array = new(char*, n + 1);
961 if (!m->cmdline_array)
964 for (p = m->cmdline, i = 0, first = true; p < m->cmdline + m->cmdline_length; p++) {
966 m->cmdline_array[i++] = (char*) p;
971 m->cmdline_array[i] = NULL;
972 *cmdline = m->cmdline_array;
977 int sd_bus_message_get_audit_sessionid(sd_bus_message *m, uint32_t *sessionid) {
985 *sessionid = m->audit->sessionid;
989 int sd_bus_message_get_audit_loginuid(sd_bus_message *m, uid_t *uid) {
997 *uid = m->audit->loginuid;
1001 int sd_bus_message_has_effective_cap(sd_bus_message *m, int capability) {
1011 sz = m->capability_size / 4;
1012 if ((unsigned) capability >= sz*8)
1015 return !!(m->capability[2 * sz + (capability / 8)] & (1 << (capability % 8)));
1018 int sd_bus_message_is_signal(sd_bus_message *m, const char *interface, const char *member) {
1022 if (m->header->type != SD_BUS_MESSAGE_TYPE_SIGNAL)
1025 if (interface && (!m->interface || !streq(m->interface, interface)))
1028 if (member && (!m->member || !streq(m->member, member)))
1034 int sd_bus_message_is_method_call(sd_bus_message *m, const char *interface, const char *member) {
1038 if (m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_CALL)
1041 if (interface && (!m->interface || !streq(m->interface, interface)))
1044 if (member && (!m->member || !streq(m->member, member)))
1050 int sd_bus_message_is_method_error(sd_bus_message *m, const char *name) {
1054 if (m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_ERROR)
1057 if (name && (!m->error.name || !streq(m->error.name, name)))
1063 int sd_bus_message_set_no_reply(sd_bus_message *m, int b) {
1068 if (m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_CALL)
1072 m->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
1074 m->header->flags &= ~SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
1079 static struct bus_container *message_get_container(sd_bus_message *m) {
1082 if (m->n_containers == 0)
1083 return &m->root_container;
1085 assert(m->containers);
1086 return m->containers + m->n_containers - 1;
1089 struct bus_body_part *message_append_part(sd_bus_message *m) {
1090 struct bus_body_part *part;
1097 if (m->n_body_parts <= 0) {
1101 assert(m->body_end);
1103 part = new0(struct bus_body_part, 1);
1109 m->body_end->next = part;
1119 static void part_zero(struct bus_body_part *part, size_t sz) {
1124 /* All other fields can be left in their defaults */
1125 assert(!part->data);
1126 assert(part->memfd < 0);
1129 part->is_zero = true;
1130 part->sealed = true;
1133 static int part_make_space(
1134 struct sd_bus_message *m,
1135 struct bus_body_part *part,
1144 assert(!part->sealed);
1149 if (!part->data && part->memfd < 0)
1150 part->memfd = bus_kernel_pop_memfd(m->bus, &part->data, &part->mapped);
1152 if (part->memfd >= 0) {
1155 r = ioctl(part->memfd, KDBUS_CMD_MEMFD_SIZE_SET, &u);
1161 if (!part->data || sz > part->mapped) {
1162 size_t psz = PAGE_ALIGN(sz > 0 ? sz : 1);
1164 if (part->mapped <= 0)
1165 n = mmap(NULL, psz, PROT_READ|PROT_WRITE, MAP_SHARED, part->memfd, 0);
1167 n = mremap(part->data, part->mapped, psz, MREMAP_MAYMOVE);
1169 if (n == MAP_FAILED) {
1176 part->munmap_this = true;
1179 n = realloc(part->data, sz);
1186 part->free_this = true;
1190 *q = part->data ? (uint8_t*) part->data + part->size : NULL;
1196 static void message_extend_containers(sd_bus_message *m, size_t expand) {
1197 struct bus_container *c;
1204 /* Update counters */
1205 for (c = m->containers; c < m->containers + m->n_containers; c++)
1207 *c->array_size += expand;
1211 static void *message_extend_body(sd_bus_message *m, size_t align, size_t sz) {
1212 struct bus_body_part *part = NULL;
1213 size_t start_body, end_body, padding, start_part, end_part, added;
1225 start_body = ALIGN_TO((size_t) m->header->body_size, align);
1226 end_body = start_body + sz;
1228 padding = start_body - m->header->body_size;
1229 added = padding + sz;
1231 /* Check for 32bit overflows */
1232 if (end_body > (size_t) ((uint32_t) -1)) {
1238 m->n_body_parts <= 0 ||
1239 m->body_end->sealed ||
1240 padding != ALIGN_TO(m->body_end->size, align) - m->body_end->size;
1244 part = message_append_part(m);
1248 part_zero(part, padding);
1251 part = message_append_part(m);
1255 r = part_make_space(m, part, sz, &p);
1259 struct bus_container *c;
1267 start_part = ALIGN_TO(part->size, align);
1268 end_part = start_part + sz;
1270 r = part_make_space(m, part, end_part, &p);
1275 memset(p, 0, padding);
1276 p = (uint8_t*) p + padding;
1279 /* Readjust pointers */
1280 for (c = m->containers; c < m->containers + m->n_containers; c++)
1281 c->array_size = adjust_pointer(c->array_size, op, os, part->data);
1283 m->error.message = (const char*) adjust_pointer(m->error.message, op, os, part->data);
1286 m->header->body_size = end_body;
1287 message_extend_containers(m, added);
1292 int message_append_basic(sd_bus_message *m, char type, const void *p, const void **stored) {
1293 struct bus_container *c;
1308 if (!bus_type_is_basic(type))
1313 c = message_get_container(m);
1315 if (c->signature && c->signature[c->index]) {
1316 /* Container signature is already set */
1318 if (c->signature[c->index] != type)
1321 /* Maybe we can append to the signature? But only if this is the top-level container*/
1322 if (c->enclosing != 0)
1325 e = strextend(&c->signature, CHAR_TO_STR(type), NULL);
1334 case SD_BUS_TYPE_STRING:
1335 case SD_BUS_TYPE_OBJECT_PATH:
1338 sz = 4 + strlen(p) + 1;
1341 case SD_BUS_TYPE_SIGNATURE:
1344 sz = 1 + strlen(p) + 1;
1347 case SD_BUS_TYPE_BOOLEAN:
1350 assert_cc(sizeof(int) == sizeof(uint32_t));
1356 case SD_BUS_TYPE_UNIX_FD: {
1359 if (!m->allow_fds) {
1372 fd = fcntl(z, F_DUPFD_CLOEXEC, 3);
1378 f = realloc(m->fds, sizeof(int) * (m->n_fds + 1));
1393 align = bus_type_get_alignment(type);
1394 sz = bus_type_get_size(type);
1401 a = message_extend_body(m, align, sz);
1407 if (type == SD_BUS_TYPE_STRING || type == SD_BUS_TYPE_OBJECT_PATH) {
1408 *(uint32_t*) a = sz - 5;
1409 memcpy((uint8_t*) a + 4, p, sz - 4);
1412 *stored = (const uint8_t*) a + 4;
1414 } else if (type == SD_BUS_TYPE_SIGNATURE) {
1415 *(uint8_t*) a = sz - 1;
1416 memcpy((uint8_t*) a + 1, p, sz - 1);
1419 *stored = (const uint8_t*) a + 1;
1420 } else if (type == SD_BUS_TYPE_UNIX_FD) {
1421 *(uint32_t*) a = fdi;
1435 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1442 close_nointr_nofail(fd);
1447 int sd_bus_message_append_basic(sd_bus_message *m, char type, const void *p) {
1448 return message_append_basic(m, type, p, NULL);
1451 int sd_bus_message_append_string_space(sd_bus_message *m, size_t size, char **s) {
1452 struct bus_container *c;
1465 c = message_get_container(m);
1467 if (c->signature && c->signature[c->index]) {
1468 /* Container signature is already set */
1470 if (c->signature[c->index] != SD_BUS_TYPE_STRING)
1473 /* Maybe we can append to the signature? But only if this is the top-level container*/
1474 if (c->enclosing != 0)
1477 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRING), NULL);
1485 a = message_extend_body(m, 4, 4 + size + 1);
1489 *(uint32_t*) a = size;
1494 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1500 static int bus_message_open_array(
1502 struct bus_container *c,
1503 const char *contents,
1504 uint32_t **array_size) {
1511 struct bus_body_part *o;
1518 if (!signature_is_single(contents))
1521 alignment = bus_type_get_alignment(contents[0]);
1525 if (c->signature && c->signature[c->index]) {
1527 /* Verify the existing signature */
1529 if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
1532 if (!startswith(c->signature + c->index + 1, contents))
1535 nindex = c->index + 1 + strlen(contents);
1537 if (c->enclosing != 0)
1540 /* Extend the existing signature */
1542 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_ARRAY), contents, NULL);
1548 nindex = e - c->signature;
1551 a = message_extend_body(m, 4, 4);
1556 op = m->body_end->data;
1557 os = m->body_end->size;
1559 /* Add alignment between size and first element */
1560 if (!message_extend_body(m, alignment, 0))
1563 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1566 /* location of array size might have changed so let's readjust a */
1567 if (o == m->body_end)
1568 a = adjust_pointer(a, op, os, m->body_end->data);
1575 static int bus_message_open_variant(
1577 struct bus_container *c,
1578 const char *contents) {
1588 if (!signature_is_single(contents))
1591 if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
1594 if (c->signature && c->signature[c->index]) {
1596 if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
1600 if (c->enclosing != 0)
1603 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_VARIANT), NULL);
1610 l = strlen(contents);
1611 a = message_extend_body(m, 1, 1 + l + 1);
1616 memcpy((uint8_t*) a + 1, contents, l + 1);
1618 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1624 static int bus_message_open_struct(
1626 struct bus_container *c,
1627 const char *contents) {
1636 if (!signature_is_valid(contents, false))
1639 if (c->signature && c->signature[c->index]) {
1642 l = strlen(contents);
1644 if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
1645 !startswith(c->signature + c->index + 1, contents) ||
1646 c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
1649 nindex = c->index + 1 + l + 1;
1651 if (c->enclosing != 0)
1654 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_BEGIN), contents, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_END), NULL);
1660 nindex = e - c->signature;
1663 /* Align contents to 8 byte boundary */
1664 if (!message_extend_body(m, 8, 0))
1667 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1673 static int bus_message_open_dict_entry(
1675 struct bus_container *c,
1676 const char *contents) {
1684 if (!signature_is_pair(contents))
1687 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1690 if (c->signature && c->signature[c->index]) {
1693 l = strlen(contents);
1695 if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
1696 !startswith(c->signature + c->index + 1, contents) ||
1697 c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
1700 nindex = c->index + 1 + l + 1;
1704 /* Align contents to 8 byte boundary */
1705 if (!message_extend_body(m, 8, 0))
1708 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1714 int sd_bus_message_open_container(
1717 const char *contents) {
1719 struct bus_container *c, *w;
1720 uint32_t *array_size = NULL;
1734 /* Make sure we have space for one more container */
1735 w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
1743 c = message_get_container(m);
1745 signature = strdup(contents);
1751 /* Save old index in the parent container, in case we have to
1752 * abort this container */
1753 c->saved_index = c->index;
1754 before = m->header->body_size;
1756 if (type == SD_BUS_TYPE_ARRAY)
1757 r = bus_message_open_array(m, c, contents, &array_size);
1758 else if (type == SD_BUS_TYPE_VARIANT)
1759 r = bus_message_open_variant(m, c, contents);
1760 else if (type == SD_BUS_TYPE_STRUCT)
1761 r = bus_message_open_struct(m, c, contents);
1762 else if (type == SD_BUS_TYPE_DICT_ENTRY)
1763 r = bus_message_open_dict_entry(m, c, contents);
1772 /* OK, let's fill it in */
1773 w += m->n_containers++;
1774 w->enclosing = type;
1775 w->signature = signature;
1777 w->array_size = array_size;
1779 w->begin = m->rindex;
1784 int sd_bus_message_close_container(sd_bus_message *m) {
1785 struct bus_container *c;
1791 if (m->n_containers <= 0)
1796 c = message_get_container(m);
1797 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1798 if (c->signature && c->signature[c->index] != 0)
1813 static int type_stack_push(TypeStack *stack, unsigned max, unsigned *i, const char *types, unsigned n_struct, unsigned n_array) {
1820 stack[*i].types = types;
1821 stack[*i].n_struct = n_struct;
1822 stack[*i].n_array = n_array;
1828 static int type_stack_pop(TypeStack *stack, unsigned max, unsigned *i, const char **types, unsigned *n_struct, unsigned *n_array) {
1839 *types = stack[*i].types;
1840 *n_struct = stack[*i].n_struct;
1841 *n_array = stack[*i].n_array;
1846 int bus_message_append_ap(
1851 unsigned n_array, n_struct;
1852 TypeStack stack[BUS_CONTAINER_DEPTH];
1853 unsigned stack_ptr = 0;
1861 n_array = (unsigned) -1;
1862 n_struct = strlen(types);
1867 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
1868 r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
1874 r = sd_bus_message_close_container(m);
1882 if (n_array != (unsigned) -1)
1891 case SD_BUS_TYPE_BYTE: {
1894 x = (uint8_t) va_arg(ap, int);
1895 r = sd_bus_message_append_basic(m, *t, &x);
1899 case SD_BUS_TYPE_BOOLEAN:
1900 case SD_BUS_TYPE_INT32:
1901 case SD_BUS_TYPE_UINT32:
1902 case SD_BUS_TYPE_UNIX_FD: {
1905 /* We assume a boolean is the same as int32_t */
1906 assert_cc(sizeof(int32_t) == sizeof(int));
1908 x = va_arg(ap, uint32_t);
1909 r = sd_bus_message_append_basic(m, *t, &x);
1913 case SD_BUS_TYPE_INT16:
1914 case SD_BUS_TYPE_UINT16: {
1917 x = (uint16_t) va_arg(ap, int);
1918 r = sd_bus_message_append_basic(m, *t, &x);
1922 case SD_BUS_TYPE_INT64:
1923 case SD_BUS_TYPE_UINT64:
1924 case SD_BUS_TYPE_DOUBLE: {
1927 x = va_arg(ap, uint64_t);
1928 r = sd_bus_message_append_basic(m, *t, &x);
1932 case SD_BUS_TYPE_STRING:
1933 case SD_BUS_TYPE_OBJECT_PATH:
1934 case SD_BUS_TYPE_SIGNATURE: {
1937 x = va_arg(ap, const char*);
1938 r = sd_bus_message_append_basic(m, *t, x);
1942 case SD_BUS_TYPE_ARRAY: {
1945 r = signature_element_length(t + 1, &k);
1951 memcpy(s, t + 1, k);
1954 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, s);
1959 if (n_array == (unsigned) -1) {
1964 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
1970 n_array = va_arg(ap, unsigned);
1975 case SD_BUS_TYPE_VARIANT: {
1978 s = va_arg(ap, const char*);
1982 r = sd_bus_message_open_container(m, SD_BUS_TYPE_VARIANT, s);
1986 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
1991 n_struct = strlen(s);
1992 n_array = (unsigned) -1;
1997 case SD_BUS_TYPE_STRUCT_BEGIN:
1998 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
2001 r = signature_element_length(t, &k);
2008 memcpy(s, t + 1, k - 2);
2011 r = sd_bus_message_open_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
2016 if (n_array == (unsigned) -1) {
2021 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2027 n_array = (unsigned) -1;
2043 int sd_bus_message_append(sd_bus_message *m, const char *types, ...) {
2056 va_start(ap, types);
2057 r = bus_message_append_ap(m, types, ap);
2063 int sd_bus_message_append_array_space(sd_bus_message *m, char type, size_t size, void **ptr) {
2072 if (!bus_type_is_trivial(type))
2074 if (!ptr && size > 0)
2079 align = bus_type_get_alignment(type);
2080 sz = bus_type_get_size(type);
2082 assert_se(align > 0);
2088 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
2092 a = message_extend_body(m, align, size);
2096 r = sd_bus_message_close_container(m);
2104 int sd_bus_message_append_array(sd_bus_message *m, char type, const void *ptr, size_t size) {
2108 if (!ptr && size > 0)
2111 r = sd_bus_message_append_array_space(m, type, size, &p);
2116 memcpy(p, ptr, size);
2121 int sd_bus_message_append_array_memfd(sd_bus_message *m, char type, sd_memfd *memfd) {
2122 _cleanup_close_ int copy_fd = -1;
2123 struct bus_body_part *part;
2135 if (!bus_type_is_trivial(type))
2140 r = sd_memfd_set_sealed(memfd, true);
2144 copy_fd = sd_memfd_dup_fd(memfd);
2148 r = sd_memfd_get_size(memfd, &size);
2152 align = bus_type_get_alignment(type);
2153 sz = bus_type_get_size(type);
2155 assert_se(align > 0);
2161 if (size > (size_t) (uint32_t) -1)
2164 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
2168 a = message_extend_body(m, align, 0);
2172 part = message_append_part(m);
2176 part->memfd = copy_fd;
2177 part->sealed = true;
2181 message_extend_containers(m, size);
2182 m->header->body_size += size;
2184 return sd_bus_message_close_container(m);
2187 int bus_body_part_map(struct bus_body_part *part) {
2196 if (part->size <= 0)
2199 /* For smaller zero parts (as used for padding) we don't need to map anything... */
2200 if (part->memfd < 0 && part->is_zero && part->size < 8) {
2201 static const uint8_t zeroes[7] = { };
2202 part->data = (void*) zeroes;
2206 psz = PAGE_ALIGN(part->size);
2208 if (part->memfd >= 0)
2209 p = mmap(NULL, psz, PROT_READ, MAP_SHARED, part->memfd, 0);
2210 else if (part->is_zero)
2211 p = mmap(NULL, psz, PROT_READ, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
2215 if (p == MAP_FAILED)
2220 part->munmap_this = true;
2225 void bus_body_part_unmap(struct bus_body_part *part) {
2229 if (part->memfd < 0)
2235 if (!part->munmap_this)
2238 assert_se(munmap(part->data, part->mapped) == 0);
2242 part->munmap_this = false;
2247 static int buffer_peek(const void *p, uint32_t sz, size_t *rindex, size_t align, size_t nbytes, void **r) {
2248 size_t k, start, end;
2253 start = ALIGN_TO((size_t) *rindex, align);
2254 end = start + nbytes;
2259 /* Verify that padding is 0 */
2260 for (k = *rindex; k < start; k++)
2261 if (((const uint8_t*) p)[k] != 0)
2265 *r = (uint8_t*) p + start;
2272 static bool message_end_of_array(sd_bus_message *m, size_t index) {
2273 struct bus_container *c;
2277 c = message_get_container(m);
2281 return index >= c->begin + BUS_MESSAGE_BSWAP32(m, *c->array_size);
2284 static struct bus_body_part* find_part(sd_bus_message *m, size_t index, size_t sz, void **p) {
2285 struct bus_body_part *part;
2291 if (m->cached_rindex_part && index >= m->cached_rindex_part_begin) {
2292 part = m->cached_rindex_part;
2293 begin = m->cached_rindex_part_begin;
2303 if (index + sz <= begin + part->size) {
2305 r = bus_body_part_map(part);
2310 *p = (uint8_t*) part->data + index - begin;
2312 m->cached_rindex_part = part;
2313 m->cached_rindex_part_begin = begin;
2318 begin += part->size;
2325 static int message_peek_body(
2332 size_t k, start, end, padding;
2333 struct bus_body_part *part;
2340 if (message_end_of_array(m, *rindex))
2343 start = ALIGN_TO((size_t) *rindex, align);
2344 padding = start - *rindex;
2345 end = start + nbytes;
2347 if (end > BUS_MESSAGE_BODY_SIZE(m))
2350 part = find_part(m, *rindex, padding, (void**) &q);
2355 /* Verify padding */
2356 for (k = 0; k < padding; k++)
2361 part = find_part(m, start, nbytes, (void**) &q);
2373 static bool validate_nul(const char *s, size_t l) {
2375 /* Check for NUL chars in the string */
2376 if (memchr(s, 0, l))
2379 /* Check for NUL termination */
2386 static bool validate_string(const char *s, size_t l) {
2388 if (!validate_nul(s, l))
2391 /* Check if valid UTF8 */
2392 if (!utf8_is_valid(s))
2398 static bool validate_signature(const char *s, size_t l) {
2400 if (!validate_nul(s, l))
2403 /* Check if valid signature */
2404 if (!signature_is_valid(s, true))
2410 static bool validate_object_path(const char *s, size_t l) {
2412 if (!validate_nul(s, l))
2415 if (!object_path_is_valid(s))
2421 int sd_bus_message_read_basic(sd_bus_message *m, char type, void *p) {
2422 struct bus_container *c;
2430 if (!bus_type_is_basic(type))
2435 c = message_get_container(m);
2437 if (!c->signature || c->signature[c->index] == 0)
2440 if (c->signature[c->index] != type)
2445 case SD_BUS_TYPE_STRING:
2446 case SD_BUS_TYPE_OBJECT_PATH: {
2451 r = message_peek_body(m, &rindex, 4, 4, &q);
2455 l = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2456 r = message_peek_body(m, &rindex, 1, l+1, &q);
2462 if (type == SD_BUS_TYPE_OBJECT_PATH) {
2463 if (!validate_object_path(q, l))
2466 if (!validate_string(q, l))
2471 *(const char**) p = q;
2475 case SD_BUS_TYPE_SIGNATURE: {
2480 r = message_peek_body(m, &rindex, 1, 1, &q);
2485 r = message_peek_body(m, &rindex, 1, l+1, &q);
2491 if (!validate_signature(q, l))
2495 *(const char**) p = q;
2503 align = bus_type_get_alignment(type);
2504 sz = bus_type_get_size(type);
2505 assert(align > 0 && sz > 0);
2508 r = message_peek_body(m, &rindex, align, sz, &q);
2514 case SD_BUS_TYPE_BYTE:
2515 *(uint8_t*) p = *(uint8_t*) q;
2518 case SD_BUS_TYPE_BOOLEAN:
2519 *(int*) p = !!*(uint32_t*) q;
2522 case SD_BUS_TYPE_INT16:
2523 case SD_BUS_TYPE_UINT16:
2524 *(uint16_t*) p = BUS_MESSAGE_BSWAP16(m, *(uint16_t*) q);
2527 case SD_BUS_TYPE_INT32:
2528 case SD_BUS_TYPE_UINT32:
2529 *(uint32_t*) p = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2532 case SD_BUS_TYPE_INT64:
2533 case SD_BUS_TYPE_UINT64:
2534 case SD_BUS_TYPE_DOUBLE:
2535 *(uint64_t*) p = BUS_MESSAGE_BSWAP64(m, *(uint64_t*) q);
2538 case SD_BUS_TYPE_UNIX_FD: {
2541 j = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2545 *(int*) p = m->fds[j];
2550 assert_not_reached("Unknown basic type...");
2559 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2565 static int bus_message_enter_array(
2567 struct bus_container *c,
2568 const char *contents,
2569 uint32_t **array_size) {
2580 if (!signature_is_single(contents))
2583 alignment = bus_type_get_alignment(contents[0]);
2587 if (!c->signature || c->signature[c->index] == 0)
2590 if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
2593 if (!startswith(c->signature + c->index + 1, contents))
2597 r = message_peek_body(m, &rindex, 4, 4, &q);
2601 if (BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q) > BUS_ARRAY_MAX_SIZE)
2604 r = message_peek_body(m, &rindex, alignment, 0, NULL);
2610 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2611 c->index += 1 + strlen(contents);
2615 *array_size = (uint32_t*) q;
2620 static int bus_message_enter_variant(
2622 struct bus_container *c,
2623 const char *contents) {
2634 if (!signature_is_single(contents))
2637 if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
2640 if (!c->signature || c->signature[c->index] == 0)
2643 if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
2647 r = message_peek_body(m, &rindex, 1, 1, &q);
2652 r = message_peek_body(m, &rindex, 1, l+1, &q);
2658 if (!validate_signature(q, l))
2661 if (!streq(q, contents))
2664 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2672 static int bus_message_enter_struct(
2674 struct bus_container *c,
2675 const char *contents) {
2684 if (!signature_is_valid(contents, false))
2687 if (!c->signature || c->signature[c->index] == 0)
2690 l = strlen(contents);
2692 if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
2693 !startswith(c->signature + c->index + 1, contents) ||
2694 c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
2697 r = message_peek_body(m, &m->rindex, 8, 0, NULL);
2701 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2702 c->index += 1 + l + 1;
2707 static int bus_message_enter_dict_entry(
2709 struct bus_container *c,
2710 const char *contents) {
2719 if (!signature_is_pair(contents))
2722 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2725 if (!c->signature || c->signature[c->index] == 0)
2728 l = strlen(contents);
2730 if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
2731 !startswith(c->signature + c->index + 1, contents) ||
2732 c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
2735 r = message_peek_body(m, &m->rindex, 8, 0, NULL);
2739 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2740 c->index += 1 + l + 1;
2745 int sd_bus_message_enter_container(sd_bus_message *m, char type, const char *contents) {
2746 struct bus_container *c, *w;
2747 uint32_t *array_size = NULL;
2760 * We enforce a global limit on container depth, that is much
2761 * higher than the 32 structs and 32 arrays the specification
2762 * mandates. This is simpler to implement for us, and we need
2763 * this only to ensure our container array doesn't grow
2764 * without bounds. We are happy to return any data from a
2765 * message as long as the data itself is valid, even if the
2766 * overall message might be not.
2768 * Note that the message signature is validated when
2769 * parsing the headers, and that validation does check the
2772 * Note that the specification defines no limits on the depth
2773 * of stacked variants, but we do.
2775 if (m->n_containers >= BUS_CONTAINER_DEPTH)
2778 w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
2783 c = message_get_container(m);
2785 if (!c->signature || c->signature[c->index] == 0)
2788 signature = strdup(contents);
2792 c->saved_index = c->index;
2795 if (type == SD_BUS_TYPE_ARRAY)
2796 r = bus_message_enter_array(m, c, contents, &array_size);
2797 else if (type == SD_BUS_TYPE_VARIANT)
2798 r = bus_message_enter_variant(m, c, contents);
2799 else if (type == SD_BUS_TYPE_STRUCT)
2800 r = bus_message_enter_struct(m, c, contents);
2801 else if (type == SD_BUS_TYPE_DICT_ENTRY)
2802 r = bus_message_enter_dict_entry(m, c, contents);
2811 /* OK, let's fill it in */
2812 w += m->n_containers++;
2813 w->enclosing = type;
2814 w->signature = signature;
2816 w->array_size = array_size;
2818 w->begin = m->rindex;
2823 int sd_bus_message_exit_container(sd_bus_message *m) {
2824 struct bus_container *c;
2830 if (m->n_containers <= 0)
2833 c = message_get_container(m);
2834 if (c->enclosing == SD_BUS_TYPE_ARRAY) {
2837 l = BUS_MESSAGE_BSWAP32(m, *c->array_size);
2838 if (c->begin + l != m->rindex)
2842 if (c->signature && c->signature[c->index] != 0)
2852 static void message_quit_container(sd_bus_message *m) {
2853 struct bus_container *c;
2857 assert(m->n_containers > 0);
2859 c = message_get_container(m);
2862 assert(m->rindex >= c->before);
2863 m->rindex = c->before;
2865 /* Free container */
2869 /* Correct index of new top-level container */
2870 c = message_get_container(m);
2871 c->index = c->saved_index;
2874 int sd_bus_message_peek_type(sd_bus_message *m, char *type, const char **contents) {
2875 struct bus_container *c;
2883 c = message_get_container(m);
2885 if (!c->signature || c->signature[c->index] == 0)
2888 if (message_end_of_array(m, m->rindex))
2891 if (bus_type_is_basic(c->signature[c->index])) {
2895 *type = c->signature[c->index];
2899 if (c->signature[c->index] == SD_BUS_TYPE_ARRAY) {
2905 r = signature_element_length(c->signature+c->index+1, &l);
2911 sig = strndup(c->signature + c->index + 1, l);
2915 free(m->peeked_signature);
2916 m->peeked_signature = sig;
2922 *type = SD_BUS_TYPE_ARRAY;
2927 if (c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ||
2928 c->signature[c->index] == SD_BUS_TYPE_DICT_ENTRY_BEGIN) {
2934 r = signature_element_length(c->signature+c->index, &l);
2939 sig = strndup(c->signature + c->index + 1, l - 2);
2943 free(m->peeked_signature);
2944 m->peeked_signature = sig;
2950 *type = c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY;
2955 if (c->signature[c->index] == SD_BUS_TYPE_VARIANT) {
2961 r = message_peek_body(m, &rindex, 1, 1, &q);
2968 r = message_peek_body(m, &rindex, 1, l+1, &q);
2974 if (!validate_signature(q, l))
2981 *type = SD_BUS_TYPE_VARIANT;
2990 *type = c->enclosing;
2996 int sd_bus_message_rewind(sd_bus_message *m, int complete) {
2997 struct bus_container *c;
3005 message_reset_containers(m);
3007 m->root_container.index = 0;
3009 c = message_get_container(m);
3011 c = message_get_container(m);
3014 m->rindex = c->begin;
3017 return !isempty(c->signature);
3019 static int message_read_ap(
3024 unsigned n_array, n_struct;
3025 TypeStack stack[BUS_CONTAINER_DEPTH];
3026 unsigned stack_ptr = 0;
3034 /* Ideally, we'd just call ourselves recursively on every
3035 * complex type. However, the state of a va_list that is
3036 * passed to a function is undefined after that function
3037 * returns. This means we need to docode the va_list linearly
3038 * in a single stackframe. We hence implement our own
3039 * home-grown stack in an array. */
3041 n_array = (unsigned) -1;
3042 n_struct = strlen(types);
3047 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
3048 r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
3054 r = sd_bus_message_exit_container(m);
3062 if (n_array != (unsigned) -1)
3071 case SD_BUS_TYPE_BYTE:
3072 case SD_BUS_TYPE_BOOLEAN:
3073 case SD_BUS_TYPE_INT16:
3074 case SD_BUS_TYPE_UINT16:
3075 case SD_BUS_TYPE_INT32:
3076 case SD_BUS_TYPE_UINT32:
3077 case SD_BUS_TYPE_INT64:
3078 case SD_BUS_TYPE_UINT64:
3079 case SD_BUS_TYPE_DOUBLE:
3080 case SD_BUS_TYPE_STRING:
3081 case SD_BUS_TYPE_OBJECT_PATH:
3082 case SD_BUS_TYPE_SIGNATURE:
3083 case SD_BUS_TYPE_UNIX_FD: {
3086 p = va_arg(ap, void*);
3087 r = sd_bus_message_read_basic(m, *t, p);
3096 case SD_BUS_TYPE_ARRAY: {
3099 r = signature_element_length(t + 1, &k);
3105 memcpy(s, t + 1, k);
3108 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, s);
3115 if (n_array == (unsigned) -1) {
3120 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
3126 n_array = va_arg(ap, unsigned);
3131 case SD_BUS_TYPE_VARIANT: {
3134 s = va_arg(ap, const char *);
3138 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, s);
3144 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
3149 n_struct = strlen(s);
3150 n_array = (unsigned) -1;
3155 case SD_BUS_TYPE_STRUCT_BEGIN:
3156 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
3159 r = signature_element_length(t, &k);
3165 memcpy(s, t + 1, k - 2);
3168 r = sd_bus_message_enter_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
3175 if (n_array == (unsigned) -1) {
3180 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
3186 n_array = (unsigned) -1;
3199 int sd_bus_message_read(sd_bus_message *m, const char *types, ...) {
3210 va_start(ap, types);
3211 r = message_read_ap(m, types, ap);
3217 int sd_bus_message_read_array(sd_bus_message *m, char type, const void **ptr, size_t *size) {
3218 struct bus_container *c;
3228 if (!bus_type_is_trivial(type))
3234 if (BUS_MESSAGE_NEED_BSWAP(m))
3237 align = bus_type_get_alignment(type);
3241 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
3245 c = message_get_container(m);
3246 sz = BUS_MESSAGE_BSWAP32(m, *c->array_size);
3248 r = message_peek_body(m, &m->rindex, align, sz, &p);
3256 r = sd_bus_message_exit_container(m);
3260 *ptr = (const void*) p;
3266 message_quit_container(m);
3270 static int message_peek_fields(
3281 return buffer_peek(BUS_MESSAGE_FIELDS(m), BUS_MESSAGE_FIELDS_SIZE(m), rindex, align, nbytes, ret);
3284 static int message_peek_field_uint32(
3295 r = message_peek_fields(m, ri, 4, 4, &q);
3300 *ret = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
3305 static int message_peek_field_string(
3307 bool (*validate)(const char *p),
3318 r = message_peek_field_uint32(m, ri, &l);
3322 r = message_peek_fields(m, ri, 1, l+1, &q);
3327 if (!validate_nul(q, l))
3333 if (!validate_string(q, l))
3343 static int message_peek_field_signature(
3355 r = message_peek_fields(m, ri, 1, 1, &q);
3360 r = message_peek_fields(m, ri, 1, l+1, &q);
3364 if (!validate_signature(q, l))
3373 static int message_skip_fields(
3376 uint32_t array_size,
3377 const char **signature) {
3379 size_t original_index;
3386 original_index = *ri;
3392 if (array_size != (uint32_t) -1 &&
3393 array_size <= *ri - original_index)
3400 if (t == SD_BUS_TYPE_STRING) {
3402 r = message_peek_field_string(m, NULL, ri, NULL);
3408 } else if (t == SD_BUS_TYPE_OBJECT_PATH) {
3410 r = message_peek_field_string(m, object_path_is_valid, ri, NULL);
3416 } else if (t == SD_BUS_TYPE_SIGNATURE) {
3418 r = message_peek_field_signature(m, ri, NULL);
3424 } else if (bus_type_is_basic(t)) {
3427 align = bus_type_get_alignment(t);
3428 k = bus_type_get_size(t);
3429 assert(align > 0 && k > 0);
3431 r = message_peek_fields(m, ri, align, k, NULL);
3437 } else if (t == SD_BUS_TYPE_ARRAY) {
3439 r = signature_element_length(*signature+1, &l);
3449 strncpy(sig, *signature + 1, l-1);
3452 alignment = bus_type_get_alignment(sig[0]);
3456 r = message_peek_field_uint32(m, ri, &nas);
3459 if (nas > BUS_ARRAY_MAX_SIZE)
3462 r = message_peek_fields(m, ri, alignment, 0, NULL);
3466 r = message_skip_fields(m, ri, nas, (const char**) &s);
3471 (*signature) += 1 + l;
3473 } else if (t == SD_BUS_TYPE_VARIANT) {
3476 r = message_peek_field_signature(m, ri, &s);
3480 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
3486 } else if (t == SD_BUS_TYPE_STRUCT ||
3487 t == SD_BUS_TYPE_DICT_ENTRY) {
3489 r = signature_element_length(*signature, &l);
3496 strncpy(sig, *signature + 1, l-1);
3499 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
3510 int bus_message_parse_fields(sd_bus_message *m) {
3513 uint32_t unix_fds = 0;
3517 for (ri = 0; ri < BUS_MESSAGE_FIELDS_SIZE(m); ) {
3518 const char *signature;
3521 r = message_peek_fields(m, &ri, 8, 1, (void**) &header);
3525 r = message_peek_field_signature(m, &ri, &signature);
3530 case _SD_BUS_MESSAGE_HEADER_INVALID:
3533 case SD_BUS_MESSAGE_HEADER_PATH:
3538 if (!streq(signature, "o"))
3541 r = message_peek_field_string(m, object_path_is_valid, &ri, &m->path);
3544 case SD_BUS_MESSAGE_HEADER_INTERFACE:
3549 if (!streq(signature, "s"))
3552 r = message_peek_field_string(m, interface_name_is_valid, &ri, &m->interface);
3555 case SD_BUS_MESSAGE_HEADER_MEMBER:
3560 if (!streq(signature, "s"))
3563 r = message_peek_field_string(m, member_name_is_valid, &ri, &m->member);
3566 case SD_BUS_MESSAGE_HEADER_ERROR_NAME:
3571 if (!streq(signature, "s"))
3574 r = message_peek_field_string(m, error_name_is_valid, &ri, &m->error.name);
3577 case SD_BUS_MESSAGE_HEADER_DESTINATION:
3582 if (!streq(signature, "s"))
3585 r = message_peek_field_string(m, service_name_is_valid, &ri, &m->destination);
3588 case SD_BUS_MESSAGE_HEADER_SENDER:
3593 if (!streq(signature, "s"))
3596 r = message_peek_field_string(m, service_name_is_valid, &ri, &m->sender);
3600 case SD_BUS_MESSAGE_HEADER_SIGNATURE: {
3604 if (m->root_container.signature)
3607 if (!streq(signature, "g"))
3610 r = message_peek_field_signature(m, &ri, &s);
3618 free(m->root_container.signature);
3619 m->root_container.signature = c;
3623 case SD_BUS_MESSAGE_HEADER_REPLY_SERIAL:
3624 if (m->reply_serial != 0)
3627 if (!streq(signature, "u"))
3630 r = message_peek_field_uint32(m, &ri, &m->reply_serial);
3634 if (m->reply_serial == 0)
3639 case SD_BUS_MESSAGE_HEADER_UNIX_FDS:
3643 if (!streq(signature, "u"))
3646 r = message_peek_field_uint32(m, &ri, &unix_fds);
3656 r = message_skip_fields(m, &ri, (uint32_t) -1, (const char **) &signature);
3663 if (m->n_fds != unix_fds)
3666 if (isempty(m->root_container.signature) != (BUS_MESSAGE_BODY_SIZE(m) == 0))
3669 switch (m->header->type) {
3671 case SD_BUS_MESSAGE_TYPE_SIGNAL:
3672 if (!m->path || !m->interface || !m->member)
3676 case SD_BUS_MESSAGE_TYPE_METHOD_CALL:
3678 if (!m->path || !m->member)
3683 case SD_BUS_MESSAGE_TYPE_METHOD_RETURN:
3685 if (m->reply_serial == 0)
3689 case SD_BUS_MESSAGE_TYPE_METHOD_ERROR:
3691 if (m->reply_serial == 0 || !m->error.name)
3696 /* Try to read the error message, but if we can't it's a non-issue */
3697 if (m->header->type == SD_BUS_MESSAGE_TYPE_METHOD_ERROR)
3698 sd_bus_message_read(m, "s", &m->error.message);
3703 int bus_message_seal(sd_bus_message *m, uint64_t serial) {
3704 struct bus_body_part *part;
3714 if (m->n_containers > 0)
3720 /* If there's a non-trivial signature set, then add it in here */
3721 if (!isempty(m->root_container.signature)) {
3722 r = message_append_field_signature(m, SD_BUS_MESSAGE_HEADER_SIGNATURE, m->root_container.signature, NULL);
3728 r = message_append_field_uint32(m, SD_BUS_MESSAGE_HEADER_UNIX_FDS, m->n_fds);
3733 /* Add padding at the end, since we know the body
3734 * needs to start at an 8 byte alignment. */
3736 l = BUS_MESSAGE_FIELDS_SIZE(m);
3739 memset((uint8_t*) BUS_MESSAGE_FIELDS(m) + l, 0, a);
3741 MESSAGE_FOREACH_PART(part, i, m)
3742 if (part->memfd >= 0 && !part->sealed) {
3743 bus_body_part_unmap(part);
3745 if (ioctl(part->memfd, KDBUS_CMD_MEMFD_SEAL_SET, 1) >= 0)
3746 part->sealed = true;
3749 m->header->serial = serial;
3755 int sd_bus_message_set_destination(sd_bus_message *m, const char *destination) {
3765 return message_append_field_string(m, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &m->destination);
3768 int bus_message_dump(sd_bus_message *m) {
3769 const char *u = NULL, *uu = NULL, *s = NULL;
3770 char **cmdline = NULL;
3773 uid_t owner, audit_loginuid;
3774 uint32_t audit_sessionid;
3778 printf("Message %p\n"
3785 "\tfields_size=%u\n"
3790 "\tdestination=%s\n"
3793 "\treply_serial=%u\n"
3795 "\terror.message=%s\n"
3797 "\tn_body_parts=%u\n",
3804 BUS_MESSAGE_SERIAL(m),
3805 BUS_MESSAGE_FIELDS_SIZE(m),
3806 BUS_MESSAGE_BODY_SIZE(m),
3808 strna(m->interface),
3810 strna(m->destination),
3812 strna(m->root_container.signature),
3814 strna(m->error.name),
3815 strna(m->error.message),
3820 printf("\tpid=%lu\n", (unsigned long) m->pid);
3822 printf("\ttid=%lu\n", (unsigned long) m->tid);
3824 printf("\tuid=%lu\n", (unsigned long) m->uid);
3826 printf("\tgid=%lu\n", (unsigned long) m->gid);
3827 if (m->pid_starttime != 0)
3828 printf("\tpid_starttime=%llu\n", (unsigned long long) m->pid_starttime);
3829 if (m->monotonic != 0)
3830 printf("\tmonotonic=%llu\n", (unsigned long long) m->monotonic);
3831 if (m->realtime != 0)
3832 printf("\trealtime=%llu\n", (unsigned long long) m->realtime);
3834 printf("\texe=[%s]\n", m->exe);
3836 printf("\tcomm=[%s]\n", m->comm);
3838 printf("\ttid_comm=[%s]\n", m->tid_comm);
3840 printf("\tlabel=[%s]\n", m->label);
3842 printf("\tcgroup=[%s]\n", m->cgroup);
3844 sd_bus_message_get_unit(m, &u);
3846 printf("\tunit=[%s]\n", u);
3847 sd_bus_message_get_user_unit(m, &uu);
3849 printf("\tuser_unit=[%s]\n", uu);
3850 sd_bus_message_get_session(m, &s);
3852 printf("\tsession=[%s]\n", s);
3853 if (sd_bus_message_get_owner_uid(m, &owner) >= 0)
3854 printf("\towner_uid=%lu\n", (unsigned long) owner);
3855 if (sd_bus_message_get_audit_loginuid(m, &audit_loginuid) >= 0)
3856 printf("\taudit_loginuid=%lu\n", (unsigned long) audit_loginuid);
3857 if (sd_bus_message_get_audit_sessionid(m, &audit_sessionid) >= 0)
3858 printf("\taudit_sessionid=%lu\n", (unsigned long) audit_sessionid);
3860 printf("\tCAP_KILL=%i\n", sd_bus_message_has_effective_cap(m, 5));
3862 if (sd_bus_message_get_cmdline(m, &cmdline) >= 0) {
3865 fputs("\tcmdline=[", stdout);
3866 STRV_FOREACH(c, cmdline) {
3873 fputs("]\n", stdout);
3876 r = sd_bus_message_rewind(m, true);
3878 log_error("Failed to rewind: %s", strerror(-r));
3882 printf("BEGIN_MESSAGE \"%s\" {\n", strempty(m->root_container.signature));
3885 _cleanup_free_ char *prefix = NULL;
3886 const char *contents = NULL;
3901 r = sd_bus_message_peek_type(m, &type, &contents);
3903 log_error("Failed to peek type: %s", strerror(-r));
3910 r = sd_bus_message_exit_container(m);
3912 log_error("Failed to exit container: %s", strerror(-r));
3918 prefix = strrep("\t", level);
3922 if (type == SD_BUS_TYPE_ARRAY)
3923 printf("%s} END_ARRAY \n", prefix);
3924 else if (type == SD_BUS_TYPE_VARIANT)
3925 printf("%s} END_VARIANT\n", prefix);
3926 else if (type == SD_BUS_TYPE_STRUCT)
3927 printf("%s} END_STRUCT\n", prefix);
3928 else if (type == SD_BUS_TYPE_DICT_ENTRY)
3929 printf("%s} END_DICT_ENTRY\n", prefix);
3934 prefix = strrep("\t", level);
3938 if (bus_type_is_container(type) > 0) {
3939 r = sd_bus_message_enter_container(m, type, contents);
3941 log_error("Failed to enter container: %s", strerror(-r));
3945 if (type == SD_BUS_TYPE_ARRAY)
3946 printf("%sBEGIN_ARRAY \"%s\" {\n", prefix, contents);
3947 else if (type == SD_BUS_TYPE_VARIANT)
3948 printf("%sBEGIN_VARIANT \"%s\" {\n", prefix, contents);
3949 else if (type == SD_BUS_TYPE_STRUCT)
3950 printf("%sBEGIN_STRUCT \"%s\" {\n", prefix, contents);
3951 else if (type == SD_BUS_TYPE_DICT_ENTRY)
3952 printf("%sBEGIN_DICT_ENTRY \"%s\" {\n", prefix, contents);
3959 r = sd_bus_message_read_basic(m, type, &basic);
3961 log_error("Failed to get basic: %s", strerror(-r));
3967 case SD_BUS_TYPE_BYTE:
3968 printf("%sBYTE: %u\n", prefix, basic.u8);
3971 case SD_BUS_TYPE_BOOLEAN:
3972 printf("%sBOOLEAN: %s\n", prefix, yes_no(basic.i));
3975 case SD_BUS_TYPE_INT16:
3976 printf("%sINT16: %i\n", prefix, basic.s16);
3979 case SD_BUS_TYPE_UINT16:
3980 printf("%sUINT16: %u\n", prefix, basic.u16);
3983 case SD_BUS_TYPE_INT32:
3984 printf("%sINT32: %i\n", prefix, basic.s32);
3987 case SD_BUS_TYPE_UINT32:
3988 printf("%sUINT32: %u\n", prefix, basic.u32);
3991 case SD_BUS_TYPE_INT64:
3992 printf("%sINT64: %lli\n", prefix, (long long) basic.s64);
3995 case SD_BUS_TYPE_UINT64:
3996 printf("%sUINT64: %llu\n", prefix, (unsigned long long) basic.u64);
3999 case SD_BUS_TYPE_DOUBLE:
4000 printf("%sDOUBLE: %g\n", prefix, basic.d64);
4003 case SD_BUS_TYPE_STRING:
4004 printf("%sSTRING: \"%s\"\n", prefix, basic.string);
4007 case SD_BUS_TYPE_OBJECT_PATH:
4008 printf("%sOBJECT_PATH: \"%s\"\n", prefix, basic.string);
4011 case SD_BUS_TYPE_SIGNATURE:
4012 printf("%sSIGNATURE: \"%s\"\n", prefix, basic.string);
4015 case SD_BUS_TYPE_UNIX_FD:
4016 printf("%sUNIX_FD: %i\n", prefix, basic.i);
4020 assert_not_reached("Unknown basic type.");
4024 printf("} END_MESSAGE\n");
4028 int bus_message_get_blob(sd_bus_message *m, void **buffer, size_t *sz) {
4032 struct bus_body_part *part;
4038 total = BUS_MESSAGE_SIZE(m);
4044 e = mempcpy(p, m->header, BUS_MESSAGE_BODY_BEGIN(m));
4045 MESSAGE_FOREACH_PART(part, i, m)
4046 e = mempcpy(e, part->data, part->size);
4048 assert(total == (size_t) ((uint8_t*) e - (uint8_t*) p));
4056 int bus_message_read_strv_extend(sd_bus_message *m, char ***l) {
4062 r = sd_bus_message_enter_container(m, 'a', "s");
4069 r = sd_bus_message_read_basic(m, 's', &s);
4075 r = strv_extend(l, s);
4080 r = sd_bus_message_exit_container(m);
4087 const char* bus_message_get_arg(sd_bus_message *m, unsigned i) {
4089 const char *t = NULL;
4094 r = sd_bus_message_rewind(m, true);
4098 for (j = 0; j <= i; j++) {
4101 r = sd_bus_message_peek_type(m, &type, NULL);
4105 if (type != SD_BUS_TYPE_STRING &&
4106 type != SD_BUS_TYPE_OBJECT_PATH &&
4107 type != SD_BUS_TYPE_SIGNATURE)
4110 r = sd_bus_message_read_basic(m, type, &t);
4118 bool bus_header_is_complete(struct bus_header *h, size_t size) {
4124 if (size < sizeof(struct bus_header))
4127 full = sizeof(struct bus_header) +
4128 (h->endian == SD_BUS_NATIVE_ENDIAN ? h->fields_size : bswap_32(h->fields_size));
4130 return size >= full;
4133 int bus_header_message_size(struct bus_header *h, size_t *sum) {
4139 if (h->endian == SD_BUS_NATIVE_ENDIAN) {
4140 fs = h->fields_size;
4142 } else if (h->endian == SD_BUS_REVERSE_ENDIAN) {
4143 fs = bswap_32(h->fields_size);
4144 bs = bswap_32(h->body_size);
4148 *sum = sizeof(struct bus_header) + ALIGN8(fs) + bs;