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->free_this)
79 static void message_reset_parts(sd_bus_message *m) {
80 struct bus_body_part *part;
85 while (m->n_body_parts > 0) {
86 struct bus_body_part *next = part->next;
87 message_free_part(m, part);
94 m->cached_rindex_part = NULL;
95 m->cached_rindex_part_begin = 0;
98 static void message_reset_containers(sd_bus_message *m) {
103 for (i = 0; i < m->n_containers; i++)
104 free(m->containers[i].signature);
107 m->containers = NULL;
110 m->root_container.index = 0;
113 static void message_free(sd_bus_message *m) {
122 message_reset_parts(m);
127 if (m->release_kdbus)
128 ioctl(m->bus->input_fd, KDBUS_CMD_MSG_RELEASE, m->kdbus);
131 close_many(m->fds, m->n_fds);
136 sd_bus_unref(m->bus);
138 if (m->iovec != m->iovec_fixed)
141 free(m->cmdline_array);
143 message_reset_containers(m);
144 free(m->root_container.signature);
146 free(m->peeked_signature);
154 static void* buffer_extend(void **p, uint32_t *sz, size_t align, size_t extend) {
162 start = ALIGN_TO((size_t) *sz, align);
163 end = start + extend;
166 return (uint8_t*) *p + start;
168 if (end > (size_t) ((uint32_t) -1))
171 k = realloc(*p, end);
175 /* Zero out padding */
177 memset((uint8_t*) k + *sz, 0, start - *sz);
182 return (uint8_t*) k + start;
185 static void *message_extend_fields(sd_bus_message *m, size_t align, size_t sz) {
195 os = m->header->fields_size;
197 p = buffer_extend(&m->fields, &m->header->fields_size, align, sz);
203 /* Adjust quick access pointers */
204 m->path = adjust_pointer(m->path, op, os, m->fields);
205 m->interface = adjust_pointer(m->interface, op, os, m->fields);
206 m->member = adjust_pointer(m->member, op, os, m->fields);
207 m->destination = adjust_pointer(m->destination, op, os, m->fields);
208 m->sender = adjust_pointer(m->sender, op, os, m->fields);
209 m->error.name = adjust_pointer(m->error.name, op, os, m->fields);
211 m->free_fields = true;
216 static int message_append_field_string(
229 if (l > (size_t) (uint32_t) -1)
232 /* field id byte + signature length + signature 's' + NUL + string length + string + NUL */
233 p = message_extend_fields(m, 8, 4 + 4 + l + 1);
242 ((uint32_t*) p)[1] = l;
243 memcpy(p + 8, s, l + 1);
246 *ret = (char*) p + 8;
251 static int message_append_field_signature(
266 /* field id byte + signature length + signature 'g' + NUL + string length + string + NUL */
267 p = message_extend_fields(m, 8, 4 + 1 + l + 1);
273 p[2] = SD_BUS_TYPE_SIGNATURE;
276 memcpy(p + 5, s, l + 1);
279 *ret = (const char*) p + 5;
284 static int message_append_field_uint32(sd_bus_message *m, uint8_t h, uint32_t x) {
289 /* field id byte + signature length + signature 'u' + NUL + value */
290 p = message_extend_fields(m, 8, 4 + 4);
296 p[2] = SD_BUS_TYPE_UINT32;
299 ((uint32_t*) p)[1] = x;
304 int bus_message_from_header(
309 const struct ucred *ucred,
312 sd_bus_message **ret) {
315 struct bus_header *h;
318 assert(buffer || length <= 0);
319 assert(fds || n_fds <= 0);
322 if (length < sizeof(struct bus_header))
332 if (h->type == _SD_BUS_MESSAGE_TYPE_INVALID)
335 if (h->endian != SD_BUS_LITTLE_ENDIAN &&
336 h->endian != SD_BUS_BIG_ENDIAN)
339 a = ALIGN(sizeof(sd_bus_message)) + ALIGN(extra);
342 label_sz = strlen(label);
360 m->uid_valid = m->gid_valid = true;
364 m->label = (char*) m + ALIGN(sizeof(sd_bus_message)) + ALIGN(extra);
365 memcpy(m->label, label, label_sz + 1);
372 int bus_message_from_malloc(
377 const struct ucred *ucred,
379 sd_bus_message **ret) {
384 r = bus_message_from_header(buffer, length, fds, n_fds, ucred, label, 0, &m);
388 if (length != BUS_MESSAGE_SIZE(m)) {
393 m->fields = (uint8_t*) buffer + sizeof(struct bus_header);
396 m->body.data = (uint8_t*) buffer + sizeof(struct bus_header) + ALIGN8(BUS_MESSAGE_FIELDS_SIZE(m));
397 m->body.size = length - sizeof(struct bus_header) - ALIGN8(BUS_MESSAGE_FIELDS_SIZE(m));
398 m->body.sealed = true;
402 m->iovec = m->iovec_fixed;
403 m->iovec[0].iov_base = buffer;
404 m->iovec[0].iov_len = length;
406 r = bus_message_parse_fields(m);
410 /* We take possession of the memory and fds now */
411 m->free_header = true;
422 static sd_bus_message *message_new(sd_bus *bus, uint8_t type) {
425 m = malloc0(ALIGN(sizeof(sd_bus_message)) + sizeof(struct bus_header));
430 m->header = (struct bus_header*) ((uint8_t*) m + ALIGN(sizeof(struct sd_bus_message)));
431 m->header->endian = SD_BUS_NATIVE_ENDIAN;
432 m->header->type = type;
433 m->header->version = bus ? bus->message_version : 1;
434 m->allow_fds = !bus || bus->can_fds || (bus->state != BUS_HELLO && bus->state != BUS_RUNNING);
437 m->bus = sd_bus_ref(bus);
442 int sd_bus_message_new_signal(
445 const char *interface,
447 sd_bus_message **m) {
460 if (bus && bus->state == BUS_UNSET)
463 t = message_new(bus, SD_BUS_MESSAGE_TYPE_SIGNAL);
467 t->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
469 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_PATH, SD_BUS_TYPE_OBJECT_PATH, path, &t->path);
472 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_INTERFACE, SD_BUS_TYPE_STRING, interface, &t->interface);
475 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_MEMBER, SD_BUS_TYPE_STRING, member, &t->member);
483 sd_bus_message_unref(t);
487 int sd_bus_message_new_method_call(
489 const char *destination,
491 const char *interface,
493 sd_bus_message **m) {
504 if (bus && bus->state == BUS_UNSET)
507 t = message_new(bus, SD_BUS_MESSAGE_TYPE_METHOD_CALL);
511 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_PATH, SD_BUS_TYPE_OBJECT_PATH, path, &t->path);
514 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_MEMBER, SD_BUS_TYPE_STRING, member, &t->member);
519 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_INTERFACE, SD_BUS_TYPE_STRING, interface, &t->interface);
525 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &t->destination);
538 static int message_new_reply(
540 sd_bus_message *call,
542 sd_bus_message **m) {
551 if (call->header->type != SD_BUS_MESSAGE_TYPE_METHOD_CALL)
555 if (bus && bus->state == BUS_UNSET)
558 t = message_new(bus, type);
562 t->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
563 t->reply_serial = BUS_MESSAGE_SERIAL(call);
565 r = message_append_field_uint32(t, SD_BUS_MESSAGE_HEADER_REPLY_SERIAL, t->reply_serial);
570 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, call->sender, &t->sender);
575 t->dont_send = !!(call->header->flags & SD_BUS_MESSAGE_NO_REPLY_EXPECTED);
585 int sd_bus_message_new_method_return(
587 sd_bus_message *call,
588 sd_bus_message **m) {
590 return message_new_reply(bus, call, SD_BUS_MESSAGE_TYPE_METHOD_RETURN, m);
593 int sd_bus_message_new_method_error(
595 sd_bus_message *call,
596 const sd_bus_error *e,
597 sd_bus_message **m) {
602 if (!sd_bus_error_is_set(e))
607 r = message_new_reply(bus, call, SD_BUS_MESSAGE_TYPE_METHOD_ERROR, &t);
611 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_ERROR_NAME, SD_BUS_TYPE_STRING, e->name, &t->error.name);
616 r = message_append_basic(t, SD_BUS_TYPE_STRING, e->message, (const void**) &t->error.message);
629 sd_bus_message* sd_bus_message_ref(sd_bus_message *m) {
633 assert(m->n_ref > 0);
639 sd_bus_message* sd_bus_message_unref(sd_bus_message *m) {
643 assert(m->n_ref > 0);
652 int sd_bus_message_get_type(sd_bus_message *m, uint8_t *type) {
658 *type = m->header->type;
662 int sd_bus_message_get_serial(sd_bus_message *m, uint64_t *serial) {
667 if (m->header->serial == 0)
670 *serial = BUS_MESSAGE_SERIAL(m);
674 int sd_bus_message_get_reply_serial(sd_bus_message *m, uint64_t *serial) {
679 if (m->reply_serial == 0)
682 *serial = m->reply_serial;
686 int sd_bus_message_get_no_reply(sd_bus_message *m) {
690 return m->header->type == SD_BUS_MESSAGE_TYPE_METHOD_CALL ? !!(m->header->flags & SD_BUS_MESSAGE_NO_REPLY_EXPECTED) : 0;
693 const char *sd_bus_message_get_path(sd_bus_message *m) {
700 const char *sd_bus_message_get_interface(sd_bus_message *m) {
707 const char *sd_bus_message_get_member(sd_bus_message *m) {
713 const char *sd_bus_message_get_destination(sd_bus_message *m) {
717 return m->destination;
720 const char *sd_bus_message_get_sender(sd_bus_message *m) {
727 const sd_bus_error *sd_bus_message_get_error(sd_bus_message *m) {
731 if (!sd_bus_error_is_set(&m->error))
737 int sd_bus_message_get_uid(sd_bus_message *m, uid_t *uid) {
749 int sd_bus_message_get_gid(sd_bus_message *m, gid_t *gid) {
761 int sd_bus_message_get_pid(sd_bus_message *m, pid_t *pid) {
773 int sd_bus_message_get_tid(sd_bus_message *m, pid_t *tid) {
785 int sd_bus_message_get_pid_starttime(sd_bus_message *m, uint64_t *usec) {
790 if (m->pid_starttime <= 0)
793 *usec = m->pid_starttime;
797 int sd_bus_message_get_selinux_context(sd_bus_message *m, const char **ret) {
807 int sd_bus_message_get_monotonic_timestamp(sd_bus_message *m, uint64_t *usec) {
812 if (m->monotonic <= 0)
815 *usec = m->monotonic;
819 int sd_bus_message_get_realtime_timestamp(sd_bus_message *m, uint64_t *usec) {
824 if (m->realtime <= 0)
831 int sd_bus_message_get_comm(sd_bus_message *m, const char **ret) {
843 int sd_bus_message_get_tid_comm(sd_bus_message *m, const char **ret) {
855 int sd_bus_message_get_exe(sd_bus_message *m, const char **ret) {
867 int sd_bus_message_get_cgroup(sd_bus_message *m, const char **ret) {
879 int sd_bus_message_get_unit(sd_bus_message *m, const char **ret) {
890 r = cg_path_get_unit(m->cgroup, &m->unit);
899 int sd_bus_message_get_user_unit(sd_bus_message *m, const char **ret) {
910 r = cg_path_get_user_unit(m->cgroup, &m->user_unit);
919 int sd_bus_message_get_session(sd_bus_message *m, const char **ret) {
930 r = cg_path_get_session(m->cgroup, &m->session);
939 int sd_bus_message_get_owner_uid(sd_bus_message *m, uid_t *uid) {
947 return cg_path_get_owner_uid(m->cgroup, uid);
950 int sd_bus_message_get_cmdline(sd_bus_message *m, char ***cmdline) {
961 for (p = m->cmdline, n = 0; p < m->cmdline + m->cmdline_length; p++)
965 m->cmdline_array = new(char*, n + 1);
966 if (!m->cmdline_array)
969 for (p = m->cmdline, i = 0, first = true; p < m->cmdline + m->cmdline_length; p++) {
971 m->cmdline_array[i++] = (char*) p;
976 m->cmdline_array[i] = NULL;
977 *cmdline = m->cmdline_array;
982 int sd_bus_message_get_audit_sessionid(sd_bus_message *m, uint32_t *sessionid) {
990 *sessionid = m->audit->sessionid;
994 int sd_bus_message_get_audit_loginuid(sd_bus_message *m, uid_t *uid) {
1002 *uid = m->audit->loginuid;
1006 int sd_bus_message_has_effective_cap(sd_bus_message *m, int capability) {
1016 sz = m->capability_size / 4;
1017 if ((unsigned) capability >= sz*8)
1020 return !!(m->capability[2 * sz + (capability / 8)] & (1 << (capability % 8)));
1023 int sd_bus_message_is_signal(sd_bus_message *m, const char *interface, const char *member) {
1027 if (m->header->type != SD_BUS_MESSAGE_TYPE_SIGNAL)
1030 if (interface && (!m->interface || !streq(m->interface, interface)))
1033 if (member && (!m->member || !streq(m->member, member)))
1039 int sd_bus_message_is_method_call(sd_bus_message *m, const char *interface, const char *member) {
1043 if (m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_CALL)
1046 if (interface && (!m->interface || !streq(m->interface, interface)))
1049 if (member && (!m->member || !streq(m->member, member)))
1055 int sd_bus_message_is_method_error(sd_bus_message *m, const char *name) {
1059 if (m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_ERROR)
1062 if (name && (!m->error.name || !streq(m->error.name, name)))
1068 int sd_bus_message_set_no_reply(sd_bus_message *m, int b) {
1073 if (m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_CALL)
1077 m->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
1079 m->header->flags &= ~SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
1084 static struct bus_container *message_get_container(sd_bus_message *m) {
1087 if (m->n_containers == 0)
1088 return &m->root_container;
1090 assert(m->containers);
1091 return m->containers + m->n_containers - 1;
1094 struct bus_body_part *message_append_part(sd_bus_message *m) {
1095 struct bus_body_part *part;
1102 if (m->n_body_parts <= 0) {
1106 assert(m->body_end);
1108 part = new0(struct bus_body_part, 1);
1114 m->body_end->next = part;
1124 static void part_zero(struct bus_body_part *part, size_t sz) {
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 (sz > part->mapped) {
1162 size_t psz = PAGE_ALIGN(sz);
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) {
1178 n = realloc(part->data, sz);
1185 part->free_this = true;
1189 *q = part->data ? (uint8_t*) part->data + part->size : NULL;
1195 static void *message_extend_body(sd_bus_message *m, size_t align, size_t sz) {
1196 struct bus_container *c;
1197 struct bus_body_part *part = NULL;
1198 size_t start_body, end_body, padding, start_part, end_part, added;
1210 start_body = ALIGN_TO((size_t) m->header->body_size, align);
1211 end_body = start_body + sz;
1213 padding = start_body - m->header->body_size;
1214 added = padding + sz;
1216 /* Check for 32bit overflows */
1217 if (end_body > (size_t) ((uint32_t) -1)) {
1223 m->n_body_parts <= 0 ||
1224 m->body_end->sealed ||
1225 padding != ALIGN_TO(m->body_end->size, align) - m->body_end->size;
1229 part = message_append_part(m);
1233 part_zero(part, padding);
1236 part = message_append_part(m);
1240 r = part_make_space(m, part, sz, &p);
1251 start_part = ALIGN_TO(part->size, align);
1252 end_part = start_part + sz;
1254 r = part_make_space(m, part, end_part, &p);
1259 memset(p, 0, padding);
1260 p = (uint8_t*) p + padding;
1263 /* Readjust pointers */
1264 for (c = m->containers; c < m->containers + m->n_containers; c++)
1265 c->array_size = adjust_pointer(c->array_size, op, os, part->data);
1267 m->error.message = (const char*) adjust_pointer(m->error.message, op, os, part->data);
1270 /* Update counters */
1271 for (c = m->containers; c < m->containers + m->n_containers; c++)
1273 *c->array_size += added;
1275 m->header->body_size = end_body;
1280 int message_append_basic(sd_bus_message *m, char type, const void *p, const void **stored) {
1281 struct bus_container *c;
1296 if (!bus_type_is_basic(type))
1301 c = message_get_container(m);
1303 if (c->signature && c->signature[c->index]) {
1304 /* Container signature is already set */
1306 if (c->signature[c->index] != type)
1309 /* Maybe we can append to the signature? But only if this is the top-level container*/
1310 if (c->enclosing != 0)
1313 e = strextend(&c->signature, CHAR_TO_STR(type), NULL);
1322 case SD_BUS_TYPE_STRING:
1323 case SD_BUS_TYPE_OBJECT_PATH:
1326 sz = 4 + strlen(p) + 1;
1329 case SD_BUS_TYPE_SIGNATURE:
1332 sz = 1 + strlen(p) + 1;
1335 case SD_BUS_TYPE_BOOLEAN:
1338 assert_cc(sizeof(int) == sizeof(uint32_t));
1344 case SD_BUS_TYPE_UNIX_FD: {
1347 if (!m->allow_fds) {
1360 fd = fcntl(z, F_DUPFD_CLOEXEC, 3);
1366 f = realloc(m->fds, sizeof(int) * (m->n_fds + 1));
1381 align = bus_type_get_alignment(type);
1382 sz = bus_type_get_size(type);
1389 a = message_extend_body(m, align, sz);
1395 if (type == SD_BUS_TYPE_STRING || type == SD_BUS_TYPE_OBJECT_PATH) {
1396 *(uint32_t*) a = sz - 5;
1397 memcpy((uint8_t*) a + 4, p, sz - 4);
1400 *stored = (const uint8_t*) a + 4;
1402 } else if (type == SD_BUS_TYPE_SIGNATURE) {
1403 *(uint8_t*) a = sz - 1;
1404 memcpy((uint8_t*) a + 1, p, sz - 1);
1407 *stored = (const uint8_t*) a + 1;
1408 } else if (type == SD_BUS_TYPE_UNIX_FD) {
1409 *(uint32_t*) a = fdi;
1423 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1430 close_nointr_nofail(fd);
1435 int sd_bus_message_append_basic(sd_bus_message *m, char type, const void *p) {
1436 return message_append_basic(m, type, p, NULL);
1439 int sd_bus_message_append_string_space(sd_bus_message *m, size_t size, char **s) {
1440 struct bus_container *c;
1453 c = message_get_container(m);
1455 if (c->signature && c->signature[c->index]) {
1456 /* Container signature is already set */
1458 if (c->signature[c->index] != SD_BUS_TYPE_STRING)
1461 /* Maybe we can append to the signature? But only if this is the top-level container*/
1462 if (c->enclosing != 0)
1465 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRING), NULL);
1473 a = message_extend_body(m, 4, 4 + size + 1);
1477 *(uint32_t*) a = size;
1482 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1488 static int bus_message_open_array(
1490 struct bus_container *c,
1491 const char *contents,
1492 uint32_t **array_size) {
1499 struct bus_body_part *o;
1506 if (!signature_is_single(contents))
1509 alignment = bus_type_get_alignment(contents[0]);
1513 if (c->signature && c->signature[c->index]) {
1515 /* Verify the existing signature */
1517 if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
1520 if (!startswith(c->signature + c->index + 1, contents))
1523 nindex = c->index + 1 + strlen(contents);
1525 if (c->enclosing != 0)
1528 /* Extend the existing signature */
1530 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_ARRAY), contents, NULL);
1536 nindex = e - c->signature;
1539 a = message_extend_body(m, 4, 4);
1544 op = m->body_end->data;
1545 os = m->body_end->size;
1547 /* Add alignment between size and first element */
1548 if (!message_extend_body(m, alignment, 0))
1551 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1554 /* location of array size might have changed so let's readjust a */
1555 if (o == m->body_end)
1556 a = adjust_pointer(a, op, os, m->body_end->data);
1563 static int bus_message_open_variant(
1565 struct bus_container *c,
1566 const char *contents) {
1576 if (!signature_is_single(contents))
1579 if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
1582 if (c->signature && c->signature[c->index]) {
1584 if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
1588 if (c->enclosing != 0)
1591 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_VARIANT), NULL);
1598 l = strlen(contents);
1599 a = message_extend_body(m, 1, 1 + l + 1);
1604 memcpy((uint8_t*) a + 1, contents, l + 1);
1606 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1612 static int bus_message_open_struct(
1614 struct bus_container *c,
1615 const char *contents) {
1624 if (!signature_is_valid(contents, false))
1627 if (c->signature && c->signature[c->index]) {
1630 l = strlen(contents);
1632 if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
1633 !startswith(c->signature + c->index + 1, contents) ||
1634 c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
1637 nindex = c->index + 1 + l + 1;
1639 if (c->enclosing != 0)
1642 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_BEGIN), contents, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_END), NULL);
1648 nindex = e - c->signature;
1651 /* Align contents to 8 byte boundary */
1652 if (!message_extend_body(m, 8, 0))
1655 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1661 static int bus_message_open_dict_entry(
1663 struct bus_container *c,
1664 const char *contents) {
1672 if (!signature_is_pair(contents))
1675 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1678 if (c->signature && c->signature[c->index]) {
1681 l = strlen(contents);
1683 if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
1684 !startswith(c->signature + c->index + 1, contents) ||
1685 c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
1688 nindex = c->index + 1 + l + 1;
1692 /* Align contents to 8 byte boundary */
1693 if (!message_extend_body(m, 8, 0))
1696 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1702 int sd_bus_message_open_container(
1705 const char *contents) {
1707 struct bus_container *c, *w;
1708 uint32_t *array_size = NULL;
1722 /* Make sure we have space for one more container */
1723 w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
1731 c = message_get_container(m);
1733 signature = strdup(contents);
1739 /* Save old index in the parent container, in case we have to
1740 * abort this container */
1741 c->saved_index = c->index;
1742 before = m->header->body_size;
1744 if (type == SD_BUS_TYPE_ARRAY)
1745 r = bus_message_open_array(m, c, contents, &array_size);
1746 else if (type == SD_BUS_TYPE_VARIANT)
1747 r = bus_message_open_variant(m, c, contents);
1748 else if (type == SD_BUS_TYPE_STRUCT)
1749 r = bus_message_open_struct(m, c, contents);
1750 else if (type == SD_BUS_TYPE_DICT_ENTRY)
1751 r = bus_message_open_dict_entry(m, c, contents);
1760 /* OK, let's fill it in */
1761 w += m->n_containers++;
1762 w->enclosing = type;
1763 w->signature = signature;
1765 w->array_size = array_size;
1767 w->begin = m->rindex;
1772 int sd_bus_message_close_container(sd_bus_message *m) {
1773 struct bus_container *c;
1779 if (m->n_containers <= 0)
1784 c = message_get_container(m);
1785 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1786 if (c->signature && c->signature[c->index] != 0)
1801 static int type_stack_push(TypeStack *stack, unsigned max, unsigned *i, const char *types, unsigned n_struct, unsigned n_array) {
1808 stack[*i].types = types;
1809 stack[*i].n_struct = n_struct;
1810 stack[*i].n_array = n_array;
1816 static int type_stack_pop(TypeStack *stack, unsigned max, unsigned *i, const char **types, unsigned *n_struct, unsigned *n_array) {
1827 *types = stack[*i].types;
1828 *n_struct = stack[*i].n_struct;
1829 *n_array = stack[*i].n_array;
1834 int bus_message_append_ap(
1839 unsigned n_array, n_struct;
1840 TypeStack stack[BUS_CONTAINER_DEPTH];
1841 unsigned stack_ptr = 0;
1849 n_array = (unsigned) -1;
1850 n_struct = strlen(types);
1855 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
1856 r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
1862 r = sd_bus_message_close_container(m);
1870 if (n_array != (unsigned) -1)
1879 case SD_BUS_TYPE_BYTE: {
1882 x = (uint8_t) va_arg(ap, int);
1883 r = sd_bus_message_append_basic(m, *t, &x);
1887 case SD_BUS_TYPE_BOOLEAN:
1888 case SD_BUS_TYPE_INT32:
1889 case SD_BUS_TYPE_UINT32:
1890 case SD_BUS_TYPE_UNIX_FD: {
1893 /* We assume a boolean is the same as int32_t */
1894 assert_cc(sizeof(int32_t) == sizeof(int));
1896 x = va_arg(ap, uint32_t);
1897 r = sd_bus_message_append_basic(m, *t, &x);
1901 case SD_BUS_TYPE_INT16:
1902 case SD_BUS_TYPE_UINT16: {
1905 x = (uint16_t) va_arg(ap, int);
1906 r = sd_bus_message_append_basic(m, *t, &x);
1910 case SD_BUS_TYPE_INT64:
1911 case SD_BUS_TYPE_UINT64:
1912 case SD_BUS_TYPE_DOUBLE: {
1915 x = va_arg(ap, uint64_t);
1916 r = sd_bus_message_append_basic(m, *t, &x);
1920 case SD_BUS_TYPE_STRING:
1921 case SD_BUS_TYPE_OBJECT_PATH:
1922 case SD_BUS_TYPE_SIGNATURE: {
1925 x = va_arg(ap, const char*);
1926 r = sd_bus_message_append_basic(m, *t, x);
1930 case SD_BUS_TYPE_ARRAY: {
1933 r = signature_element_length(t + 1, &k);
1939 memcpy(s, t + 1, k);
1942 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, s);
1947 if (n_array == (unsigned) -1) {
1952 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
1958 n_array = va_arg(ap, unsigned);
1963 case SD_BUS_TYPE_VARIANT: {
1966 s = va_arg(ap, const char*);
1970 r = sd_bus_message_open_container(m, SD_BUS_TYPE_VARIANT, s);
1974 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
1979 n_struct = strlen(s);
1980 n_array = (unsigned) -1;
1985 case SD_BUS_TYPE_STRUCT_BEGIN:
1986 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
1989 r = signature_element_length(t, &k);
1996 memcpy(s, t + 1, k - 2);
1999 r = sd_bus_message_open_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
2004 if (n_array == (unsigned) -1) {
2009 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2015 n_array = (unsigned) -1;
2031 int sd_bus_message_append(sd_bus_message *m, const char *types, ...) {
2044 va_start(ap, types);
2045 r = bus_message_append_ap(m, types, ap);
2051 int sd_bus_message_append_array_space(sd_bus_message *m, char type, size_t size, void **ptr) {
2060 if (!bus_type_is_trivial(type))
2062 if (!ptr && size > 0)
2067 align = bus_type_get_alignment(type);
2068 sz = bus_type_get_size(type);
2070 assert_se(align > 0);
2076 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
2080 a = message_extend_body(m, align, size);
2084 r = sd_bus_message_close_container(m);
2092 int sd_bus_message_append_array(sd_bus_message *m, char type, const void *ptr, size_t size) {
2096 if (!ptr && size > 0)
2099 r = sd_bus_message_append_array_space(m, type, size, &p);
2104 memcpy(p, ptr, size);
2109 static int buffer_peek(const void *p, uint32_t sz, size_t *rindex, size_t align, size_t nbytes, void **r) {
2110 size_t k, start, end;
2115 start = ALIGN_TO((size_t) *rindex, align);
2116 end = start + nbytes;
2121 /* Verify that padding is 0 */
2122 for (k = *rindex; k < start; k++)
2123 if (((const uint8_t*) p)[k] != 0)
2127 *r = (uint8_t*) p + start;
2134 static bool message_end_of_array(sd_bus_message *m, size_t index) {
2135 struct bus_container *c;
2139 c = message_get_container(m);
2143 return index >= c->begin + BUS_MESSAGE_BSWAP32(m, *c->array_size);
2146 static struct bus_body_part* find_part(sd_bus_message *m, size_t index, size_t sz, void **p) {
2147 struct bus_body_part *part;
2151 if (m->cached_rindex_part && index >= m->cached_rindex_part_begin) {
2152 part = m->cached_rindex_part;
2153 begin = m->cached_rindex_part_begin;
2163 if (index + sz <= begin + part->size) {
2165 *p = part->data ? (uint8_t*) part->data + index - begin : NULL;
2167 m->cached_rindex_part = part;
2168 m->cached_rindex_part_begin = begin;
2179 static int message_peek_body(
2186 size_t k, start, end, padding;
2187 struct bus_body_part *part;
2194 if (message_end_of_array(m, *rindex))
2197 start = ALIGN_TO((size_t) *rindex, align);
2198 padding = start - *rindex;
2199 end = start + nbytes;
2201 if (end > BUS_MESSAGE_BODY_SIZE(m))
2204 part = find_part(m, *rindex, padding, (void**) &q);
2209 /* Verify padding */
2210 for (k = 0; k < padding; k++)
2215 part = find_part(m, start, nbytes, (void**) &q);
2227 static bool validate_nul(const char *s, size_t l) {
2229 /* Check for NUL chars in the string */
2230 if (memchr(s, 0, l))
2233 /* Check for NUL termination */
2240 static bool validate_string(const char *s, size_t l) {
2242 if (!validate_nul(s, l))
2245 /* Check if valid UTF8 */
2246 if (!utf8_is_valid(s))
2252 static bool validate_signature(const char *s, size_t l) {
2254 if (!validate_nul(s, l))
2257 /* Check if valid signature */
2258 if (!signature_is_valid(s, true))
2264 static bool validate_object_path(const char *s, size_t l) {
2266 if (!validate_nul(s, l))
2269 if (!object_path_is_valid(s))
2275 int sd_bus_message_read_basic(sd_bus_message *m, char type, void *p) {
2276 struct bus_container *c;
2284 if (!bus_type_is_basic(type))
2289 c = message_get_container(m);
2291 if (!c->signature || c->signature[c->index] == 0)
2294 if (c->signature[c->index] != type)
2299 case SD_BUS_TYPE_STRING:
2300 case SD_BUS_TYPE_OBJECT_PATH: {
2305 r = message_peek_body(m, &rindex, 4, 4, &q);
2309 l = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2310 r = message_peek_body(m, &rindex, 1, l+1, &q);
2316 if (type == SD_BUS_TYPE_OBJECT_PATH) {
2317 if (!validate_object_path(q, l))
2320 if (!validate_string(q, l))
2325 *(const char**) p = q;
2329 case SD_BUS_TYPE_SIGNATURE: {
2334 r = message_peek_body(m, &rindex, 1, 1, &q);
2339 r = message_peek_body(m, &rindex, 1, l+1, &q);
2345 if (!validate_signature(q, l))
2349 *(const char**) p = q;
2357 align = bus_type_get_alignment(type);
2358 sz = bus_type_get_size(type);
2359 assert(align > 0 && sz > 0);
2362 r = message_peek_body(m, &rindex, align, sz, &q);
2368 case SD_BUS_TYPE_BYTE:
2369 *(uint8_t*) p = *(uint8_t*) q;
2372 case SD_BUS_TYPE_BOOLEAN:
2373 *(int*) p = !!*(uint32_t*) q;
2376 case SD_BUS_TYPE_INT16:
2377 case SD_BUS_TYPE_UINT16:
2378 *(uint16_t*) p = BUS_MESSAGE_BSWAP16(m, *(uint16_t*) q);
2381 case SD_BUS_TYPE_INT32:
2382 case SD_BUS_TYPE_UINT32:
2383 *(uint32_t*) p = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2386 case SD_BUS_TYPE_INT64:
2387 case SD_BUS_TYPE_UINT64:
2388 case SD_BUS_TYPE_DOUBLE:
2389 *(uint64_t*) p = BUS_MESSAGE_BSWAP64(m, *(uint64_t*) q);
2392 case SD_BUS_TYPE_UNIX_FD: {
2395 j = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2399 *(int*) p = m->fds[j];
2404 assert_not_reached("Unknown basic type...");
2413 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2419 static int bus_message_enter_array(
2421 struct bus_container *c,
2422 const char *contents,
2423 uint32_t **array_size) {
2434 if (!signature_is_single(contents))
2437 alignment = bus_type_get_alignment(contents[0]);
2441 if (!c->signature || c->signature[c->index] == 0)
2444 if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
2447 if (!startswith(c->signature + c->index + 1, contents))
2451 r = message_peek_body(m, &rindex, 4, 4, &q);
2455 if (BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q) > BUS_ARRAY_MAX_SIZE)
2458 r = message_peek_body(m, &rindex, alignment, 0, NULL);
2464 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2465 c->index += 1 + strlen(contents);
2469 *array_size = (uint32_t*) q;
2474 static int bus_message_enter_variant(
2476 struct bus_container *c,
2477 const char *contents) {
2488 if (!signature_is_single(contents))
2491 if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
2494 if (!c->signature || c->signature[c->index] == 0)
2497 if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
2501 r = message_peek_body(m, &rindex, 1, 1, &q);
2506 r = message_peek_body(m, &rindex, 1, l+1, &q);
2512 if (!validate_signature(q, l))
2515 if (!streq(q, contents))
2518 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2526 static int bus_message_enter_struct(
2528 struct bus_container *c,
2529 const char *contents) {
2538 if (!signature_is_valid(contents, false))
2541 if (!c->signature || c->signature[c->index] == 0)
2544 l = strlen(contents);
2546 if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
2547 !startswith(c->signature + c->index + 1, contents) ||
2548 c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
2551 r = message_peek_body(m, &m->rindex, 8, 0, NULL);
2555 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2556 c->index += 1 + l + 1;
2561 static int bus_message_enter_dict_entry(
2563 struct bus_container *c,
2564 const char *contents) {
2573 if (!signature_is_pair(contents))
2576 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2579 if (!c->signature || c->signature[c->index] == 0)
2582 l = strlen(contents);
2584 if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
2585 !startswith(c->signature + c->index + 1, contents) ||
2586 c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
2589 r = message_peek_body(m, &m->rindex, 8, 0, NULL);
2593 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2594 c->index += 1 + l + 1;
2599 int sd_bus_message_enter_container(sd_bus_message *m, char type, const char *contents) {
2600 struct bus_container *c, *w;
2601 uint32_t *array_size = NULL;
2614 * We enforce a global limit on container depth, that is much
2615 * higher than the 32 structs and 32 arrays the specification
2616 * mandates. This is simpler to implement for us, and we need
2617 * this only to ensure our container array doesn't grow
2618 * without bounds. We are happy to return any data from a
2619 * message as long as the data itself is valid, even if the
2620 * overall message might be not.
2622 * Note that the message signature is validated when
2623 * parsing the headers, and that validation does check the
2626 * Note that the specification defines no limits on the depth
2627 * of stacked variants, but we do.
2629 if (m->n_containers >= BUS_CONTAINER_DEPTH)
2632 w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
2637 c = message_get_container(m);
2639 if (!c->signature || c->signature[c->index] == 0)
2642 signature = strdup(contents);
2646 c->saved_index = c->index;
2649 if (type == SD_BUS_TYPE_ARRAY)
2650 r = bus_message_enter_array(m, c, contents, &array_size);
2651 else if (type == SD_BUS_TYPE_VARIANT)
2652 r = bus_message_enter_variant(m, c, contents);
2653 else if (type == SD_BUS_TYPE_STRUCT)
2654 r = bus_message_enter_struct(m, c, contents);
2655 else if (type == SD_BUS_TYPE_DICT_ENTRY)
2656 r = bus_message_enter_dict_entry(m, c, contents);
2665 /* OK, let's fill it in */
2666 w += m->n_containers++;
2667 w->enclosing = type;
2668 w->signature = signature;
2670 w->array_size = array_size;
2672 w->begin = m->rindex;
2677 int sd_bus_message_exit_container(sd_bus_message *m) {
2678 struct bus_container *c;
2684 if (m->n_containers <= 0)
2687 c = message_get_container(m);
2688 if (c->enclosing == SD_BUS_TYPE_ARRAY) {
2691 l = BUS_MESSAGE_BSWAP32(m, *c->array_size);
2692 if (c->begin + l != m->rindex)
2696 if (c->signature && c->signature[c->index] != 0)
2706 static void message_quit_container(sd_bus_message *m) {
2707 struct bus_container *c;
2711 assert(m->n_containers > 0);
2713 c = message_get_container(m);
2716 assert(m->rindex >= c->before);
2717 m->rindex = c->before;
2719 /* Free container */
2723 /* Correct index of new top-level container */
2724 c = message_get_container(m);
2725 c->index = c->saved_index;
2728 int sd_bus_message_peek_type(sd_bus_message *m, char *type, const char **contents) {
2729 struct bus_container *c;
2737 c = message_get_container(m);
2739 if (!c->signature || c->signature[c->index] == 0)
2742 if (message_end_of_array(m, m->rindex))
2745 if (bus_type_is_basic(c->signature[c->index])) {
2749 *type = c->signature[c->index];
2753 if (c->signature[c->index] == SD_BUS_TYPE_ARRAY) {
2759 r = signature_element_length(c->signature+c->index+1, &l);
2765 sig = strndup(c->signature + c->index + 1, l);
2769 free(m->peeked_signature);
2770 m->peeked_signature = sig;
2776 *type = SD_BUS_TYPE_ARRAY;
2781 if (c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ||
2782 c->signature[c->index] == SD_BUS_TYPE_DICT_ENTRY_BEGIN) {
2788 r = signature_element_length(c->signature+c->index, &l);
2793 sig = strndup(c->signature + c->index + 1, l - 2);
2797 free(m->peeked_signature);
2798 m->peeked_signature = sig;
2804 *type = c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY;
2809 if (c->signature[c->index] == SD_BUS_TYPE_VARIANT) {
2815 r = message_peek_body(m, &rindex, 1, 1, &q);
2822 r = message_peek_body(m, &rindex, 1, l+1, &q);
2828 if (!validate_signature(q, l))
2835 *type = SD_BUS_TYPE_VARIANT;
2844 *type = c->enclosing;
2850 int sd_bus_message_rewind(sd_bus_message *m, int complete) {
2851 struct bus_container *c;
2859 message_reset_containers(m);
2861 m->root_container.index = 0;
2863 c = message_get_container(m);
2865 c = message_get_container(m);
2868 m->rindex = c->begin;
2871 return !isempty(c->signature);
2873 static int message_read_ap(
2878 unsigned n_array, n_struct;
2879 TypeStack stack[BUS_CONTAINER_DEPTH];
2880 unsigned stack_ptr = 0;
2888 /* Ideally, we'd just call ourselves recursively on every
2889 * complex type. However, the state of a va_list that is
2890 * passed to a function is undefined after that function
2891 * returns. This means we need to docode the va_list linearly
2892 * in a single stackframe. We hence implement our own
2893 * home-grown stack in an array. */
2895 n_array = (unsigned) -1;
2896 n_struct = strlen(types);
2901 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
2902 r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
2908 r = sd_bus_message_exit_container(m);
2916 if (n_array != (unsigned) -1)
2925 case SD_BUS_TYPE_BYTE:
2926 case SD_BUS_TYPE_BOOLEAN:
2927 case SD_BUS_TYPE_INT16:
2928 case SD_BUS_TYPE_UINT16:
2929 case SD_BUS_TYPE_INT32:
2930 case SD_BUS_TYPE_UINT32:
2931 case SD_BUS_TYPE_INT64:
2932 case SD_BUS_TYPE_UINT64:
2933 case SD_BUS_TYPE_DOUBLE:
2934 case SD_BUS_TYPE_STRING:
2935 case SD_BUS_TYPE_OBJECT_PATH:
2936 case SD_BUS_TYPE_SIGNATURE:
2937 case SD_BUS_TYPE_UNIX_FD: {
2940 p = va_arg(ap, void*);
2941 r = sd_bus_message_read_basic(m, *t, p);
2950 case SD_BUS_TYPE_ARRAY: {
2953 r = signature_element_length(t + 1, &k);
2959 memcpy(s, t + 1, k);
2962 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, s);
2969 if (n_array == (unsigned) -1) {
2974 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2980 n_array = va_arg(ap, unsigned);
2985 case SD_BUS_TYPE_VARIANT: {
2988 s = va_arg(ap, const char *);
2992 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, s);
2998 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
3003 n_struct = strlen(s);
3004 n_array = (unsigned) -1;
3009 case SD_BUS_TYPE_STRUCT_BEGIN:
3010 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
3013 r = signature_element_length(t, &k);
3019 memcpy(s, t + 1, k - 2);
3022 r = sd_bus_message_enter_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
3029 if (n_array == (unsigned) -1) {
3034 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
3040 n_array = (unsigned) -1;
3053 int sd_bus_message_read(sd_bus_message *m, const char *types, ...) {
3064 va_start(ap, types);
3065 r = message_read_ap(m, types, ap);
3071 int sd_bus_message_read_array(sd_bus_message *m, char type, const void **ptr, size_t *size) {
3072 struct bus_container *c;
3082 if (!bus_type_is_trivial(type))
3088 if (BUS_MESSAGE_NEED_BSWAP(m))
3091 align = bus_type_get_alignment(type);
3095 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
3099 c = message_get_container(m);
3100 sz = BUS_MESSAGE_BSWAP32(m, *c->array_size);
3102 r = message_peek_body(m, &m->rindex, align, sz, &p);
3110 r = sd_bus_message_exit_container(m);
3114 *ptr = (const void*) p;
3120 message_quit_container(m);
3124 static int message_peek_fields(
3135 return buffer_peek(m->fields, BUS_MESSAGE_FIELDS_SIZE(m), rindex, align, nbytes, ret);
3138 static int message_peek_field_uint32(
3149 r = message_peek_fields(m, ri, 4, 4, &q);
3154 *ret = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
3159 static int message_peek_field_string(
3161 bool (*validate)(const char *p),
3172 r = message_peek_field_uint32(m, ri, &l);
3176 r = message_peek_fields(m, ri, 1, l+1, &q);
3181 if (!validate_nul(q, l))
3187 if (!validate_string(q, l))
3197 static int message_peek_field_signature(
3209 r = message_peek_fields(m, ri, 1, 1, &q);
3214 r = message_peek_fields(m, ri, 1, l+1, &q);
3218 if (!validate_signature(q, l))
3227 static int message_skip_fields(
3230 uint32_t array_size,
3231 const char **signature) {
3233 size_t original_index;
3240 original_index = *ri;
3246 if (array_size != (uint32_t) -1 &&
3247 array_size <= *ri - original_index)
3254 if (t == SD_BUS_TYPE_STRING) {
3256 r = message_peek_field_string(m, NULL, ri, NULL);
3262 } else if (t == SD_BUS_TYPE_OBJECT_PATH) {
3264 r = message_peek_field_string(m, object_path_is_valid, ri, NULL);
3270 } else if (t == SD_BUS_TYPE_SIGNATURE) {
3272 r = message_peek_field_signature(m, ri, NULL);
3278 } else if (bus_type_is_basic(t)) {
3281 align = bus_type_get_alignment(t);
3282 k = bus_type_get_size(t);
3283 assert(align > 0 && k > 0);
3285 r = message_peek_fields(m, ri, align, k, NULL);
3291 } else if (t == SD_BUS_TYPE_ARRAY) {
3293 r = signature_element_length(*signature+1, &l);
3303 strncpy(sig, *signature + 1, l-1);
3306 alignment = bus_type_get_alignment(sig[0]);
3310 r = message_peek_field_uint32(m, ri, &nas);
3313 if (nas > BUS_ARRAY_MAX_SIZE)
3316 r = message_peek_fields(m, ri, alignment, 0, NULL);
3320 r = message_skip_fields(m, ri, nas, (const char**) &s);
3325 (*signature) += 1 + l;
3327 } else if (t == SD_BUS_TYPE_VARIANT) {
3330 r = message_peek_field_signature(m, ri, &s);
3334 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
3340 } else if (t == SD_BUS_TYPE_STRUCT ||
3341 t == SD_BUS_TYPE_DICT_ENTRY) {
3343 r = signature_element_length(*signature, &l);
3350 strncpy(sig, *signature + 1, l-1);
3353 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
3364 int bus_message_parse_fields(sd_bus_message *m) {
3367 uint32_t unix_fds = 0;
3371 for (ri = 0; ri < BUS_MESSAGE_FIELDS_SIZE(m); ) {
3372 const char *signature;
3375 r = message_peek_fields(m, &ri, 8, 1, (void**) &header);
3379 r = message_peek_field_signature(m, &ri, &signature);
3384 case _SD_BUS_MESSAGE_HEADER_INVALID:
3387 case SD_BUS_MESSAGE_HEADER_PATH:
3392 if (!streq(signature, "o"))
3395 r = message_peek_field_string(m, object_path_is_valid, &ri, &m->path);
3398 case SD_BUS_MESSAGE_HEADER_INTERFACE:
3403 if (!streq(signature, "s"))
3406 r = message_peek_field_string(m, interface_name_is_valid, &ri, &m->interface);
3409 case SD_BUS_MESSAGE_HEADER_MEMBER:
3414 if (!streq(signature, "s"))
3417 r = message_peek_field_string(m, member_name_is_valid, &ri, &m->member);
3420 case SD_BUS_MESSAGE_HEADER_ERROR_NAME:
3425 if (!streq(signature, "s"))
3428 r = message_peek_field_string(m, error_name_is_valid, &ri, &m->error.name);
3431 case SD_BUS_MESSAGE_HEADER_DESTINATION:
3436 if (!streq(signature, "s"))
3439 r = message_peek_field_string(m, service_name_is_valid, &ri, &m->destination);
3442 case SD_BUS_MESSAGE_HEADER_SENDER:
3447 if (!streq(signature, "s"))
3450 r = message_peek_field_string(m, service_name_is_valid, &ri, &m->sender);
3454 case SD_BUS_MESSAGE_HEADER_SIGNATURE: {
3458 if (m->root_container.signature)
3461 if (!streq(signature, "g"))
3464 r = message_peek_field_signature(m, &ri, &s);
3472 free(m->root_container.signature);
3473 m->root_container.signature = c;
3477 case SD_BUS_MESSAGE_HEADER_REPLY_SERIAL:
3478 if (m->reply_serial != 0)
3481 if (!streq(signature, "u"))
3484 r = message_peek_field_uint32(m, &ri, &m->reply_serial);
3488 if (m->reply_serial == 0)
3493 case SD_BUS_MESSAGE_HEADER_UNIX_FDS:
3497 if (!streq(signature, "u"))
3500 r = message_peek_field_uint32(m, &ri, &unix_fds);
3510 r = message_skip_fields(m, &ri, (uint32_t) -1, (const char **) &signature);
3517 if (m->n_fds != unix_fds)
3520 if (isempty(m->root_container.signature) != (BUS_MESSAGE_BODY_SIZE(m) == 0))
3523 switch (m->header->type) {
3525 case SD_BUS_MESSAGE_TYPE_SIGNAL:
3526 if (!m->path || !m->interface || !m->member)
3530 case SD_BUS_MESSAGE_TYPE_METHOD_CALL:
3532 if (!m->path || !m->member)
3537 case SD_BUS_MESSAGE_TYPE_METHOD_RETURN:
3539 if (m->reply_serial == 0)
3543 case SD_BUS_MESSAGE_TYPE_METHOD_ERROR:
3545 if (m->reply_serial == 0 || !m->error.name)
3550 /* Try to read the error message, but if we can't it's a non-issue */
3551 if (m->header->type == SD_BUS_MESSAGE_TYPE_METHOD_ERROR)
3552 sd_bus_message_read(m, "s", &m->error.message);
3557 int bus_message_seal(sd_bus_message *m, uint64_t serial) {
3558 struct bus_body_part *part;
3568 if (m->n_containers > 0)
3574 /* If there's a non-trivial signature set, then add it in here */
3575 if (!isempty(m->root_container.signature)) {
3576 r = message_append_field_signature(m, SD_BUS_MESSAGE_HEADER_SIGNATURE, m->root_container.signature, NULL);
3582 r = message_append_field_uint32(m, SD_BUS_MESSAGE_HEADER_UNIX_FDS, m->n_fds);
3587 l = BUS_MESSAGE_FIELDS_SIZE(m);
3591 /* Add padding at the end, since we know the body
3592 * needs to start at an 8 byte alignment. */
3595 p = message_extend_fields(m, 1, a);
3600 m->header->fields_size -= a;
3603 for (i = 0, part = &m->body; i < m->n_body_parts; i++, part = part->next)
3604 if (part->memfd >= 0 && part->sealed)
3605 ioctl(part->memfd, KDBUS_CMD_MEMFD_SEAL_SET, 1);
3607 m->header->serial = serial;
3613 int sd_bus_message_set_destination(sd_bus_message *m, const char *destination) {
3623 return message_append_field_string(m, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &m->destination);
3626 int bus_message_dump(sd_bus_message *m) {
3627 const char *u = NULL, *uu = NULL, *s = NULL;
3628 char **cmdline = NULL;
3631 uid_t owner, audit_loginuid;
3632 uint32_t audit_sessionid;
3636 printf("Message %p\n"
3643 "\tfields_size=%u\n"
3648 "\tdestination=%s\n"
3651 "\treply_serial=%u\n"
3653 "\terror.message=%s\n"
3661 BUS_MESSAGE_SERIAL(m),
3662 BUS_MESSAGE_FIELDS_SIZE(m),
3663 BUS_MESSAGE_BODY_SIZE(m),
3665 strna(m->interface),
3667 strna(m->destination),
3669 strna(m->root_container.signature),
3671 strna(m->error.name),
3672 strna(m->error.message),
3676 printf("\tpid=%lu\n", (unsigned long) m->pid);
3678 printf("\ttid=%lu\n", (unsigned long) m->tid);
3680 printf("\tuid=%lu\n", (unsigned long) m->uid);
3682 printf("\tgid=%lu\n", (unsigned long) m->gid);
3683 if (m->pid_starttime != 0)
3684 printf("\tpid_starttime=%llu\n", (unsigned long long) m->pid_starttime);
3685 if (m->monotonic != 0)
3686 printf("\tmonotonic=%llu\n", (unsigned long long) m->monotonic);
3687 if (m->realtime != 0)
3688 printf("\trealtime=%llu\n", (unsigned long long) m->realtime);
3690 printf("\texe=[%s]\n", m->exe);
3692 printf("\tcomm=[%s]\n", m->comm);
3694 printf("\ttid_comm=[%s]\n", m->tid_comm);
3696 printf("\tlabel=[%s]\n", m->label);
3698 printf("\tcgroup=[%s]\n", m->cgroup);
3700 sd_bus_message_get_unit(m, &u);
3702 printf("\tunit=[%s]\n", u);
3703 sd_bus_message_get_user_unit(m, &uu);
3705 printf("\tuser_unit=[%s]\n", uu);
3706 sd_bus_message_get_session(m, &s);
3708 printf("\tsession=[%s]\n", s);
3709 if (sd_bus_message_get_owner_uid(m, &owner) >= 0)
3710 printf("\towner_uid=%lu\n", (unsigned long) owner);
3711 if (sd_bus_message_get_audit_loginuid(m, &audit_loginuid) >= 0)
3712 printf("\taudit_loginuid=%lu\n", (unsigned long) audit_loginuid);
3713 if (sd_bus_message_get_audit_sessionid(m, &audit_sessionid) >= 0)
3714 printf("\taudit_sessionid=%lu\n", (unsigned long) audit_sessionid);
3716 printf("\tCAP_KILL=%i\n", sd_bus_message_has_effective_cap(m, 5));
3718 if (sd_bus_message_get_cmdline(m, &cmdline) >= 0) {
3721 fputs("\tcmdline=[", stdout);
3722 STRV_FOREACH(c, cmdline) {
3729 fputs("]\n", stdout);
3732 r = sd_bus_message_rewind(m, true);
3734 log_error("Failed to rewind: %s", strerror(-r));
3738 printf("BEGIN_MESSAGE \"%s\" {\n", strempty(m->root_container.signature));
3741 _cleanup_free_ char *prefix = NULL;
3742 const char *contents = NULL;
3757 r = sd_bus_message_peek_type(m, &type, &contents);
3759 log_error("Failed to peek type: %s", strerror(-r));
3766 r = sd_bus_message_exit_container(m);
3768 log_error("Failed to exit container: %s", strerror(-r));
3774 prefix = strrep("\t", level);
3778 if (type == SD_BUS_TYPE_ARRAY)
3779 printf("%s} END_ARRAY \n", prefix);
3780 else if (type == SD_BUS_TYPE_VARIANT)
3781 printf("%s} END_VARIANT\n", prefix);
3782 else if (type == SD_BUS_TYPE_STRUCT)
3783 printf("%s} END_STRUCT\n", prefix);
3784 else if (type == SD_BUS_TYPE_DICT_ENTRY)
3785 printf("%s} END_DICT_ENTRY\n", prefix);
3790 prefix = strrep("\t", level);
3794 if (bus_type_is_container(type) > 0) {
3795 r = sd_bus_message_enter_container(m, type, contents);
3797 log_error("Failed to enter container: %s", strerror(-r));
3801 if (type == SD_BUS_TYPE_ARRAY)
3802 printf("%sBEGIN_ARRAY \"%s\" {\n", prefix, contents);
3803 else if (type == SD_BUS_TYPE_VARIANT)
3804 printf("%sBEGIN_VARIANT \"%s\" {\n", prefix, contents);
3805 else if (type == SD_BUS_TYPE_STRUCT)
3806 printf("%sBEGIN_STRUCT \"%s\" {\n", prefix, contents);
3807 else if (type == SD_BUS_TYPE_DICT_ENTRY)
3808 printf("%sBEGIN_DICT_ENTRY \"%s\" {\n", prefix, contents);
3815 r = sd_bus_message_read_basic(m, type, &basic);
3817 log_error("Failed to get basic: %s", strerror(-r));
3823 case SD_BUS_TYPE_BYTE:
3824 printf("%sBYTE: %u\n", prefix, basic.u8);
3827 case SD_BUS_TYPE_BOOLEAN:
3828 printf("%sBOOLEAN: %s\n", prefix, yes_no(basic.i));
3831 case SD_BUS_TYPE_INT16:
3832 printf("%sINT16: %i\n", prefix, basic.s16);
3835 case SD_BUS_TYPE_UINT16:
3836 printf("%sUINT16: %u\n", prefix, basic.u16);
3839 case SD_BUS_TYPE_INT32:
3840 printf("%sINT32: %i\n", prefix, basic.s32);
3843 case SD_BUS_TYPE_UINT32:
3844 printf("%sUINT32: %u\n", prefix, basic.u32);
3847 case SD_BUS_TYPE_INT64:
3848 printf("%sINT64: %lli\n", prefix, (long long) basic.s64);
3851 case SD_BUS_TYPE_UINT64:
3852 printf("%sUINT64: %llu\n", prefix, (unsigned long long) basic.u64);
3855 case SD_BUS_TYPE_DOUBLE:
3856 printf("%sDOUBLE: %g\n", prefix, basic.d64);
3859 case SD_BUS_TYPE_STRING:
3860 printf("%sSTRING: \"%s\"\n", prefix, basic.string);
3863 case SD_BUS_TYPE_OBJECT_PATH:
3864 printf("%sOBJECT_PATH: \"%s\"\n", prefix, basic.string);
3867 case SD_BUS_TYPE_SIGNATURE:
3868 printf("%sSIGNATURE: \"%s\"\n", prefix, basic.string);
3871 case SD_BUS_TYPE_UNIX_FD:
3872 printf("%sUNIX_FD: %i\n", prefix, basic.i);
3876 assert_not_reached("Unknown basic type.");
3880 printf("} END_MESSAGE\n");
3884 int bus_message_get_blob(sd_bus_message *m, void **buffer, size_t *sz) {
3888 struct bus_body_part *part;
3894 total = BUS_MESSAGE_SIZE(m);
3900 e = mempcpy(p, m->header, sizeof(*m->header));
3903 e = mempcpy(e, m->fields, m->header->fields_size);
3905 if (m->header->fields_size % 8 != 0)
3906 e = mempset(e, 0, 8 - (m->header->fields_size % 8));
3909 for (i = 0, part = &m->body; i < m->n_body_parts; i++, part = part->next)
3910 e = mempcpy(e, part->data, part->size);
3912 assert(total == (size_t) ((uint8_t*) e - (uint8_t*) p));
3920 int bus_message_read_strv_extend(sd_bus_message *m, char ***l) {
3926 r = sd_bus_message_enter_container(m, 'a', "s");
3933 r = sd_bus_message_read_basic(m, 's', &s);
3939 r = strv_extend(l, s);
3944 r = sd_bus_message_exit_container(m);
3951 const char* bus_message_get_arg(sd_bus_message *m, unsigned i) {
3953 const char *t = NULL;
3958 r = sd_bus_message_rewind(m, true);
3962 for (j = 0; j <= i; j++) {
3965 r = sd_bus_message_peek_type(m, &type, NULL);
3969 if (type != SD_BUS_TYPE_STRING &&
3970 type != SD_BUS_TYPE_OBJECT_PATH &&
3971 type != SD_BUS_TYPE_SIGNATURE)
3974 r = sd_bus_message_read_basic(m, type, &t);
3982 int bus_header_size(struct bus_header *h, size_t *sum) {
3988 if (h->endian == SD_BUS_NATIVE_ENDIAN) {
3989 fs = h->fields_size;
3991 } else if (h->endian == SD_BUS_REVERSE_ENDIAN) {
3992 fs = bswap_32(h->fields_size);
3993 bs = bswap_32(h->body_size);
3997 *sum = sizeof(struct bus_header) + ALIGN8(fs) + bs;