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);
439 int sd_bus_message_new_signal(
442 const char *interface,
444 sd_bus_message **m) {
457 if (bus && bus->state == BUS_UNSET)
460 t = message_new(bus, SD_BUS_MESSAGE_TYPE_SIGNAL);
464 t->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
466 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_PATH, SD_BUS_TYPE_OBJECT_PATH, path, &t->path);
469 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_INTERFACE, SD_BUS_TYPE_STRING, interface, &t->interface);
472 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_MEMBER, SD_BUS_TYPE_STRING, member, &t->member);
480 sd_bus_message_unref(t);
484 int sd_bus_message_new_method_call(
486 const char *destination,
488 const char *interface,
490 sd_bus_message **m) {
501 if (bus && bus->state == BUS_UNSET)
504 t = message_new(bus, SD_BUS_MESSAGE_TYPE_METHOD_CALL);
508 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_PATH, SD_BUS_TYPE_OBJECT_PATH, path, &t->path);
511 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_MEMBER, SD_BUS_TYPE_STRING, member, &t->member);
516 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_INTERFACE, SD_BUS_TYPE_STRING, interface, &t->interface);
522 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &t->destination);
535 static int message_new_reply(
537 sd_bus_message *call,
539 sd_bus_message **m) {
548 if (call->header->type != SD_BUS_MESSAGE_TYPE_METHOD_CALL)
552 if (bus && bus->state == BUS_UNSET)
555 t = message_new(bus, type);
559 t->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
560 t->reply_serial = BUS_MESSAGE_SERIAL(call);
562 r = message_append_field_uint32(t, SD_BUS_MESSAGE_HEADER_REPLY_SERIAL, t->reply_serial);
567 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, call->sender, &t->sender);
572 t->dont_send = !!(call->header->flags & SD_BUS_MESSAGE_NO_REPLY_EXPECTED);
582 int sd_bus_message_new_method_return(
584 sd_bus_message *call,
585 sd_bus_message **m) {
587 return message_new_reply(bus, call, SD_BUS_MESSAGE_TYPE_METHOD_RETURN, m);
590 int sd_bus_message_new_method_error(
592 sd_bus_message *call,
593 const sd_bus_error *e,
594 sd_bus_message **m) {
599 if (!sd_bus_error_is_set(e))
604 r = message_new_reply(bus, call, SD_BUS_MESSAGE_TYPE_METHOD_ERROR, &t);
608 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_ERROR_NAME, SD_BUS_TYPE_STRING, e->name, &t->error.name);
613 r = message_append_basic(t, SD_BUS_TYPE_STRING, e->message, (const void**) &t->error.message);
626 sd_bus_message* sd_bus_message_ref(sd_bus_message *m) {
630 assert(m->n_ref > 0);
636 sd_bus_message* sd_bus_message_unref(sd_bus_message *m) {
640 assert(m->n_ref > 0);
649 int sd_bus_message_get_type(sd_bus_message *m, uint8_t *type) {
655 *type = m->header->type;
659 int sd_bus_message_get_serial(sd_bus_message *m, uint64_t *serial) {
664 if (m->header->serial == 0)
667 *serial = BUS_MESSAGE_SERIAL(m);
671 int sd_bus_message_get_reply_serial(sd_bus_message *m, uint64_t *serial) {
676 if (m->reply_serial == 0)
679 *serial = m->reply_serial;
683 int sd_bus_message_get_no_reply(sd_bus_message *m) {
687 return m->header->type == SD_BUS_MESSAGE_TYPE_METHOD_CALL ? !!(m->header->flags & SD_BUS_MESSAGE_NO_REPLY_EXPECTED) : 0;
690 const char *sd_bus_message_get_path(sd_bus_message *m) {
697 const char *sd_bus_message_get_interface(sd_bus_message *m) {
704 const char *sd_bus_message_get_member(sd_bus_message *m) {
710 const char *sd_bus_message_get_destination(sd_bus_message *m) {
714 return m->destination;
717 const char *sd_bus_message_get_sender(sd_bus_message *m) {
724 const sd_bus_error *sd_bus_message_get_error(sd_bus_message *m) {
728 if (!sd_bus_error_is_set(&m->error))
734 int sd_bus_message_get_uid(sd_bus_message *m, uid_t *uid) {
746 int sd_bus_message_get_gid(sd_bus_message *m, gid_t *gid) {
758 int sd_bus_message_get_pid(sd_bus_message *m, pid_t *pid) {
770 int sd_bus_message_get_tid(sd_bus_message *m, pid_t *tid) {
782 int sd_bus_message_get_pid_starttime(sd_bus_message *m, uint64_t *usec) {
787 if (m->pid_starttime <= 0)
790 *usec = m->pid_starttime;
794 int sd_bus_message_get_selinux_context(sd_bus_message *m, const char **ret) {
804 int sd_bus_message_get_monotonic_timestamp(sd_bus_message *m, uint64_t *usec) {
809 if (m->monotonic <= 0)
812 *usec = m->monotonic;
816 int sd_bus_message_get_realtime_timestamp(sd_bus_message *m, uint64_t *usec) {
821 if (m->realtime <= 0)
828 int sd_bus_message_get_comm(sd_bus_message *m, const char **ret) {
840 int sd_bus_message_get_tid_comm(sd_bus_message *m, const char **ret) {
852 int sd_bus_message_get_exe(sd_bus_message *m, const char **ret) {
864 int sd_bus_message_get_cgroup(sd_bus_message *m, const char **ret) {
876 int sd_bus_message_get_unit(sd_bus_message *m, const char **ret) {
887 r = cg_path_get_unit(m->cgroup, &m->unit);
896 int sd_bus_message_get_user_unit(sd_bus_message *m, const char **ret) {
907 r = cg_path_get_user_unit(m->cgroup, &m->user_unit);
916 int sd_bus_message_get_session(sd_bus_message *m, const char **ret) {
927 r = cg_path_get_session(m->cgroup, &m->session);
936 int sd_bus_message_get_owner_uid(sd_bus_message *m, uid_t *uid) {
944 return cg_path_get_owner_uid(m->cgroup, uid);
947 int sd_bus_message_get_cmdline(sd_bus_message *m, char ***cmdline) {
958 for (p = m->cmdline, n = 0; p < m->cmdline + m->cmdline_length; p++)
962 m->cmdline_array = new(char*, n + 1);
963 if (!m->cmdline_array)
966 for (p = m->cmdline, i = 0, first = true; p < m->cmdline + m->cmdline_length; p++) {
968 m->cmdline_array[i++] = (char*) p;
973 m->cmdline_array[i] = NULL;
974 *cmdline = m->cmdline_array;
979 int sd_bus_message_get_audit_sessionid(sd_bus_message *m, uint32_t *sessionid) {
987 *sessionid = m->audit->sessionid;
991 int sd_bus_message_get_audit_loginuid(sd_bus_message *m, uid_t *uid) {
999 *uid = m->audit->loginuid;
1003 int sd_bus_message_has_effective_cap(sd_bus_message *m, int capability) {
1013 sz = m->capability_size / 4;
1014 if ((unsigned) capability >= sz*8)
1017 return !!(m->capability[2 * sz + (capability / 8)] & (1 << (capability % 8)));
1020 int sd_bus_message_is_signal(sd_bus_message *m, const char *interface, const char *member) {
1024 if (m->header->type != SD_BUS_MESSAGE_TYPE_SIGNAL)
1027 if (interface && (!m->interface || !streq(m->interface, interface)))
1030 if (member && (!m->member || !streq(m->member, member)))
1036 int sd_bus_message_is_method_call(sd_bus_message *m, const char *interface, const char *member) {
1040 if (m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_CALL)
1043 if (interface && (!m->interface || !streq(m->interface, interface)))
1046 if (member && (!m->member || !streq(m->member, member)))
1052 int sd_bus_message_is_method_error(sd_bus_message *m, const char *name) {
1056 if (m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_ERROR)
1059 if (name && (!m->error.name || !streq(m->error.name, name)))
1065 int sd_bus_message_set_no_reply(sd_bus_message *m, int b) {
1070 if (m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_CALL)
1074 m->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
1076 m->header->flags &= ~SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
1081 static struct bus_container *message_get_container(sd_bus_message *m) {
1084 if (m->n_containers == 0)
1085 return &m->root_container;
1087 assert(m->containers);
1088 return m->containers + m->n_containers - 1;
1091 struct bus_body_part *message_append_part(sd_bus_message *m) {
1092 struct bus_body_part *part;
1099 if (m->n_body_parts <= 0) {
1103 assert(m->body_end);
1105 part = new0(struct bus_body_part, 1);
1111 m->body_end->next = part;
1121 static void part_zero(struct bus_body_part *part, size_t sz) {
1130 static int part_make_space(
1131 struct sd_bus_message *m,
1132 struct bus_body_part *part,
1141 assert(!part->sealed);
1146 if (!part->data && part->memfd < 0)
1147 part->memfd = bus_kernel_pop_memfd(m->bus, &part->data, &part->mapped);
1149 if (part->memfd >= 0) {
1152 r = ioctl(part->memfd, KDBUS_CMD_MEMFD_SIZE_SET, &u);
1158 if (sz > part->mapped) {
1159 size_t psz = PAGE_ALIGN(sz);
1161 if (part->mapped <= 0)
1162 n = mmap(NULL, psz, PROT_READ|PROT_WRITE, MAP_SHARED, part->memfd, 0);
1164 n = mremap(part->data, part->mapped, psz, MREMAP_MAYMOVE);
1166 if (n == MAP_FAILED) {
1175 n = realloc(part->data, sz);
1182 part->free_this = true;
1186 *q = part->data ? (uint8_t*) part->data + part->size : NULL;
1192 static void *message_extend_body(sd_bus_message *m, size_t align, size_t sz) {
1193 struct bus_container *c;
1194 struct bus_body_part *part = NULL;
1195 size_t start_body, end_body, padding, start_part, end_part, added;
1207 start_body = ALIGN_TO((size_t) m->header->body_size, align);
1208 end_body = start_body + sz;
1210 padding = start_body - m->header->body_size;
1211 added = padding + sz;
1213 /* Check for 32bit overflows */
1214 if (end_body > (size_t) ((uint32_t) -1)) {
1220 m->n_body_parts <= 0 ||
1221 m->body_end->sealed ||
1222 padding != ALIGN_TO(m->body_end->size, align) - m->body_end->size;
1226 part = message_append_part(m);
1230 part_zero(part, padding);
1233 part = message_append_part(m);
1237 r = part_make_space(m, part, sz, &p);
1248 start_part = ALIGN_TO(part->size, align);
1249 end_part = start_part + sz;
1251 r = part_make_space(m, part, end_part, &p);
1256 memset(p, 0, padding);
1257 p = (uint8_t*) p + padding;
1260 /* Readjust pointers */
1261 for (c = m->containers; c < m->containers + m->n_containers; c++)
1262 c->array_size = adjust_pointer(c->array_size, op, os, part->data);
1264 m->error.message = (const char*) adjust_pointer(m->error.message, op, os, part->data);
1267 /* Update counters */
1268 for (c = m->containers; c < m->containers + m->n_containers; c++)
1270 *c->array_size += added;
1272 m->header->body_size = end_body;
1277 int message_append_basic(sd_bus_message *m, char type, const void *p, const void **stored) {
1278 struct bus_container *c;
1293 if (!bus_type_is_basic(type))
1298 c = message_get_container(m);
1300 if (c->signature && c->signature[c->index]) {
1301 /* Container signature is already set */
1303 if (c->signature[c->index] != type)
1306 /* Maybe we can append to the signature? But only if this is the top-level container*/
1307 if (c->enclosing != 0)
1310 e = strextend(&c->signature, CHAR_TO_STR(type), NULL);
1319 case SD_BUS_TYPE_STRING:
1320 case SD_BUS_TYPE_OBJECT_PATH:
1323 sz = 4 + strlen(p) + 1;
1326 case SD_BUS_TYPE_SIGNATURE:
1329 sz = 1 + strlen(p) + 1;
1332 case SD_BUS_TYPE_BOOLEAN:
1335 assert_cc(sizeof(int) == sizeof(uint32_t));
1341 case SD_BUS_TYPE_UNIX_FD: {
1344 if (!m->allow_fds) {
1357 fd = fcntl(z, F_DUPFD_CLOEXEC, 3);
1363 f = realloc(m->fds, sizeof(int) * (m->n_fds + 1));
1378 align = bus_type_get_alignment(type);
1379 sz = bus_type_get_size(type);
1386 a = message_extend_body(m, align, sz);
1392 if (type == SD_BUS_TYPE_STRING || type == SD_BUS_TYPE_OBJECT_PATH) {
1393 *(uint32_t*) a = sz - 5;
1394 memcpy((uint8_t*) a + 4, p, sz - 4);
1397 *stored = (const uint8_t*) a + 4;
1399 } else if (type == SD_BUS_TYPE_SIGNATURE) {
1400 *(uint8_t*) a = sz - 1;
1401 memcpy((uint8_t*) a + 1, p, sz - 1);
1404 *stored = (const uint8_t*) a + 1;
1405 } else if (type == SD_BUS_TYPE_UNIX_FD) {
1406 *(uint32_t*) a = fdi;
1420 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1427 close_nointr_nofail(fd);
1432 int sd_bus_message_append_basic(sd_bus_message *m, char type, const void *p) {
1433 return message_append_basic(m, type, p, NULL);
1436 int sd_bus_message_append_string_space(sd_bus_message *m, size_t size, char **s) {
1437 struct bus_container *c;
1450 c = message_get_container(m);
1452 if (c->signature && c->signature[c->index]) {
1453 /* Container signature is already set */
1455 if (c->signature[c->index] != SD_BUS_TYPE_STRING)
1458 /* Maybe we can append to the signature? But only if this is the top-level container*/
1459 if (c->enclosing != 0)
1462 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRING), NULL);
1470 a = message_extend_body(m, 4, 4 + size + 1);
1474 *(uint32_t*) a = size;
1479 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1485 static int bus_message_open_array(
1487 struct bus_container *c,
1488 const char *contents,
1489 uint32_t **array_size) {
1496 struct bus_body_part *o;
1503 if (!signature_is_single(contents))
1506 alignment = bus_type_get_alignment(contents[0]);
1510 if (c->signature && c->signature[c->index]) {
1512 /* Verify the existing signature */
1514 if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
1517 if (!startswith(c->signature + c->index + 1, contents))
1520 nindex = c->index + 1 + strlen(contents);
1522 if (c->enclosing != 0)
1525 /* Extend the existing signature */
1527 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_ARRAY), contents, NULL);
1533 nindex = e - c->signature;
1536 a = message_extend_body(m, 4, 4);
1541 op = m->body_end->data;
1542 os = m->body_end->size;
1544 /* Add alignment between size and first element */
1545 if (!message_extend_body(m, alignment, 0))
1548 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1551 /* location of array size might have changed so let's readjust a */
1552 if (o == m->body_end)
1553 a = adjust_pointer(a, op, os, m->body_end->data);
1560 static int bus_message_open_variant(
1562 struct bus_container *c,
1563 const char *contents) {
1573 if (!signature_is_single(contents))
1576 if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
1579 if (c->signature && c->signature[c->index]) {
1581 if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
1585 if (c->enclosing != 0)
1588 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_VARIANT), NULL);
1595 l = strlen(contents);
1596 a = message_extend_body(m, 1, 1 + l + 1);
1601 memcpy((uint8_t*) a + 1, contents, l + 1);
1603 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1609 static int bus_message_open_struct(
1611 struct bus_container *c,
1612 const char *contents) {
1621 if (!signature_is_valid(contents, false))
1624 if (c->signature && c->signature[c->index]) {
1627 l = strlen(contents);
1629 if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
1630 !startswith(c->signature + c->index + 1, contents) ||
1631 c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
1634 nindex = c->index + 1 + l + 1;
1636 if (c->enclosing != 0)
1639 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_BEGIN), contents, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_END), NULL);
1645 nindex = e - c->signature;
1648 /* Align contents to 8 byte boundary */
1649 if (!message_extend_body(m, 8, 0))
1652 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1658 static int bus_message_open_dict_entry(
1660 struct bus_container *c,
1661 const char *contents) {
1669 if (!signature_is_pair(contents))
1672 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1675 if (c->signature && c->signature[c->index]) {
1678 l = strlen(contents);
1680 if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
1681 !startswith(c->signature + c->index + 1, contents) ||
1682 c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
1685 nindex = c->index + 1 + l + 1;
1689 /* Align contents to 8 byte boundary */
1690 if (!message_extend_body(m, 8, 0))
1693 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1699 int sd_bus_message_open_container(
1702 const char *contents) {
1704 struct bus_container *c, *w;
1705 uint32_t *array_size = NULL;
1719 /* Make sure we have space for one more container */
1720 w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
1728 c = message_get_container(m);
1730 signature = strdup(contents);
1736 /* Save old index in the parent container, in case we have to
1737 * abort this container */
1738 c->saved_index = c->index;
1739 before = m->header->body_size;
1741 if (type == SD_BUS_TYPE_ARRAY)
1742 r = bus_message_open_array(m, c, contents, &array_size);
1743 else if (type == SD_BUS_TYPE_VARIANT)
1744 r = bus_message_open_variant(m, c, contents);
1745 else if (type == SD_BUS_TYPE_STRUCT)
1746 r = bus_message_open_struct(m, c, contents);
1747 else if (type == SD_BUS_TYPE_DICT_ENTRY)
1748 r = bus_message_open_dict_entry(m, c, contents);
1757 /* OK, let's fill it in */
1758 w += m->n_containers++;
1759 w->enclosing = type;
1760 w->signature = signature;
1762 w->array_size = array_size;
1764 w->begin = m->rindex;
1769 int sd_bus_message_close_container(sd_bus_message *m) {
1770 struct bus_container *c;
1776 if (m->n_containers <= 0)
1781 c = message_get_container(m);
1782 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1783 if (c->signature && c->signature[c->index] != 0)
1798 static int type_stack_push(TypeStack *stack, unsigned max, unsigned *i, const char *types, unsigned n_struct, unsigned n_array) {
1805 stack[*i].types = types;
1806 stack[*i].n_struct = n_struct;
1807 stack[*i].n_array = n_array;
1813 static int type_stack_pop(TypeStack *stack, unsigned max, unsigned *i, const char **types, unsigned *n_struct, unsigned *n_array) {
1824 *types = stack[*i].types;
1825 *n_struct = stack[*i].n_struct;
1826 *n_array = stack[*i].n_array;
1831 int bus_message_append_ap(
1836 unsigned n_array, n_struct;
1837 TypeStack stack[BUS_CONTAINER_DEPTH];
1838 unsigned stack_ptr = 0;
1846 n_array = (unsigned) -1;
1847 n_struct = strlen(types);
1852 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
1853 r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
1859 r = sd_bus_message_close_container(m);
1867 if (n_array != (unsigned) -1)
1876 case SD_BUS_TYPE_BYTE: {
1879 x = (uint8_t) va_arg(ap, int);
1880 r = sd_bus_message_append_basic(m, *t, &x);
1884 case SD_BUS_TYPE_BOOLEAN:
1885 case SD_BUS_TYPE_INT32:
1886 case SD_BUS_TYPE_UINT32:
1887 case SD_BUS_TYPE_UNIX_FD: {
1890 /* We assume a boolean is the same as int32_t */
1891 assert_cc(sizeof(int32_t) == sizeof(int));
1893 x = va_arg(ap, uint32_t);
1894 r = sd_bus_message_append_basic(m, *t, &x);
1898 case SD_BUS_TYPE_INT16:
1899 case SD_BUS_TYPE_UINT16: {
1902 x = (uint16_t) va_arg(ap, int);
1903 r = sd_bus_message_append_basic(m, *t, &x);
1907 case SD_BUS_TYPE_INT64:
1908 case SD_BUS_TYPE_UINT64:
1909 case SD_BUS_TYPE_DOUBLE: {
1912 x = va_arg(ap, uint64_t);
1913 r = sd_bus_message_append_basic(m, *t, &x);
1917 case SD_BUS_TYPE_STRING:
1918 case SD_BUS_TYPE_OBJECT_PATH:
1919 case SD_BUS_TYPE_SIGNATURE: {
1922 x = va_arg(ap, const char*);
1923 r = sd_bus_message_append_basic(m, *t, x);
1927 case SD_BUS_TYPE_ARRAY: {
1930 r = signature_element_length(t + 1, &k);
1936 memcpy(s, t + 1, k);
1939 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, s);
1944 if (n_array == (unsigned) -1) {
1949 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
1955 n_array = va_arg(ap, unsigned);
1960 case SD_BUS_TYPE_VARIANT: {
1963 s = va_arg(ap, const char*);
1967 r = sd_bus_message_open_container(m, SD_BUS_TYPE_VARIANT, s);
1971 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
1976 n_struct = strlen(s);
1977 n_array = (unsigned) -1;
1982 case SD_BUS_TYPE_STRUCT_BEGIN:
1983 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
1986 r = signature_element_length(t, &k);
1993 memcpy(s, t + 1, k - 2);
1996 r = sd_bus_message_open_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
2001 if (n_array == (unsigned) -1) {
2006 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2012 n_array = (unsigned) -1;
2028 int sd_bus_message_append(sd_bus_message *m, const char *types, ...) {
2041 va_start(ap, types);
2042 r = bus_message_append_ap(m, types, ap);
2048 int sd_bus_message_append_array_space(sd_bus_message *m, char type, size_t size, void **ptr) {
2057 if (!bus_type_is_trivial(type))
2059 if (!ptr && size > 0)
2064 align = bus_type_get_alignment(type);
2065 sz = bus_type_get_size(type);
2067 assert_se(align > 0);
2073 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
2077 a = message_extend_body(m, align, size);
2081 r = sd_bus_message_close_container(m);
2089 int sd_bus_message_append_array(sd_bus_message *m, char type, const void *ptr, size_t size) {
2093 if (!ptr && size > 0)
2096 r = sd_bus_message_append_array_space(m, type, size, &p);
2101 memcpy(p, ptr, size);
2106 static int buffer_peek(const void *p, uint32_t sz, size_t *rindex, size_t align, size_t nbytes, void **r) {
2107 size_t k, start, end;
2112 start = ALIGN_TO((size_t) *rindex, align);
2113 end = start + nbytes;
2118 /* Verify that padding is 0 */
2119 for (k = *rindex; k < start; k++)
2120 if (((const uint8_t*) p)[k] != 0)
2124 *r = (uint8_t*) p + start;
2131 static bool message_end_of_array(sd_bus_message *m, size_t index) {
2132 struct bus_container *c;
2136 c = message_get_container(m);
2140 return index >= c->begin + BUS_MESSAGE_BSWAP32(m, *c->array_size);
2143 static struct bus_body_part* find_part(sd_bus_message *m, size_t index, size_t sz, void **p) {
2144 struct bus_body_part *part;
2148 if (m->cached_rindex_part && index >= m->cached_rindex_part_begin) {
2149 part = m->cached_rindex_part;
2150 begin = m->cached_rindex_part_begin;
2160 if (index + sz <= begin + part->size) {
2162 *p = part->data ? (uint8_t*) part->data + index - begin : NULL;
2164 m->cached_rindex_part = part;
2165 m->cached_rindex_part_begin = begin;
2176 static int message_peek_body(
2183 size_t k, start, end, padding;
2184 struct bus_body_part *part;
2191 if (message_end_of_array(m, *rindex))
2194 start = ALIGN_TO((size_t) *rindex, align);
2195 padding = start - *rindex;
2196 end = start + nbytes;
2198 if (end > BUS_MESSAGE_BODY_SIZE(m))
2201 part = find_part(m, *rindex, padding, (void**) &q);
2206 /* Verify padding */
2207 for (k = 0; k < padding; k++)
2212 part = find_part(m, start, nbytes, (void**) &q);
2224 static bool validate_nul(const char *s, size_t l) {
2226 /* Check for NUL chars in the string */
2227 if (memchr(s, 0, l))
2230 /* Check for NUL termination */
2237 static bool validate_string(const char *s, size_t l) {
2239 if (!validate_nul(s, l))
2242 /* Check if valid UTF8 */
2243 if (!utf8_is_valid(s))
2249 static bool validate_signature(const char *s, size_t l) {
2251 if (!validate_nul(s, l))
2254 /* Check if valid signature */
2255 if (!signature_is_valid(s, true))
2261 static bool validate_object_path(const char *s, size_t l) {
2263 if (!validate_nul(s, l))
2266 if (!object_path_is_valid(s))
2272 int sd_bus_message_read_basic(sd_bus_message *m, char type, void *p) {
2273 struct bus_container *c;
2281 if (!bus_type_is_basic(type))
2286 c = message_get_container(m);
2288 if (!c->signature || c->signature[c->index] == 0)
2291 if (c->signature[c->index] != type)
2296 case SD_BUS_TYPE_STRING:
2297 case SD_BUS_TYPE_OBJECT_PATH: {
2302 r = message_peek_body(m, &rindex, 4, 4, &q);
2306 l = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2307 r = message_peek_body(m, &rindex, 1, l+1, &q);
2313 if (type == SD_BUS_TYPE_OBJECT_PATH) {
2314 if (!validate_object_path(q, l))
2317 if (!validate_string(q, l))
2322 *(const char**) p = q;
2326 case SD_BUS_TYPE_SIGNATURE: {
2331 r = message_peek_body(m, &rindex, 1, 1, &q);
2336 r = message_peek_body(m, &rindex, 1, l+1, &q);
2342 if (!validate_signature(q, l))
2346 *(const char**) p = q;
2354 align = bus_type_get_alignment(type);
2355 sz = bus_type_get_size(type);
2356 assert(align > 0 && sz > 0);
2359 r = message_peek_body(m, &rindex, align, sz, &q);
2365 case SD_BUS_TYPE_BYTE:
2366 *(uint8_t*) p = *(uint8_t*) q;
2369 case SD_BUS_TYPE_BOOLEAN:
2370 *(int*) p = !!*(uint32_t*) q;
2373 case SD_BUS_TYPE_INT16:
2374 case SD_BUS_TYPE_UINT16:
2375 *(uint16_t*) p = BUS_MESSAGE_BSWAP16(m, *(uint16_t*) q);
2378 case SD_BUS_TYPE_INT32:
2379 case SD_BUS_TYPE_UINT32:
2380 *(uint32_t*) p = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2383 case SD_BUS_TYPE_INT64:
2384 case SD_BUS_TYPE_UINT64:
2385 case SD_BUS_TYPE_DOUBLE:
2386 *(uint64_t*) p = BUS_MESSAGE_BSWAP64(m, *(uint64_t*) q);
2389 case SD_BUS_TYPE_UNIX_FD: {
2392 j = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2396 *(int*) p = m->fds[j];
2401 assert_not_reached("Unknown basic type...");
2410 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2416 static int bus_message_enter_array(
2418 struct bus_container *c,
2419 const char *contents,
2420 uint32_t **array_size) {
2431 if (!signature_is_single(contents))
2434 alignment = bus_type_get_alignment(contents[0]);
2438 if (!c->signature || c->signature[c->index] == 0)
2441 if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
2444 if (!startswith(c->signature + c->index + 1, contents))
2448 r = message_peek_body(m, &rindex, 4, 4, &q);
2452 if (BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q) > BUS_ARRAY_MAX_SIZE)
2455 r = message_peek_body(m, &rindex, alignment, 0, NULL);
2461 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2462 c->index += 1 + strlen(contents);
2466 *array_size = (uint32_t*) q;
2471 static int bus_message_enter_variant(
2473 struct bus_container *c,
2474 const char *contents) {
2485 if (!signature_is_single(contents))
2488 if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
2491 if (!c->signature || c->signature[c->index] == 0)
2494 if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
2498 r = message_peek_body(m, &rindex, 1, 1, &q);
2503 r = message_peek_body(m, &rindex, 1, l+1, &q);
2509 if (!validate_signature(q, l))
2512 if (!streq(q, contents))
2515 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2523 static int bus_message_enter_struct(
2525 struct bus_container *c,
2526 const char *contents) {
2535 if (!signature_is_valid(contents, false))
2538 if (!c->signature || c->signature[c->index] == 0)
2541 l = strlen(contents);
2543 if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
2544 !startswith(c->signature + c->index + 1, contents) ||
2545 c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
2548 r = message_peek_body(m, &m->rindex, 8, 0, NULL);
2552 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2553 c->index += 1 + l + 1;
2558 static int bus_message_enter_dict_entry(
2560 struct bus_container *c,
2561 const char *contents) {
2570 if (!signature_is_pair(contents))
2573 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2576 if (!c->signature || c->signature[c->index] == 0)
2579 l = strlen(contents);
2581 if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
2582 !startswith(c->signature + c->index + 1, contents) ||
2583 c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
2586 r = message_peek_body(m, &m->rindex, 8, 0, NULL);
2590 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2591 c->index += 1 + l + 1;
2596 int sd_bus_message_enter_container(sd_bus_message *m, char type, const char *contents) {
2597 struct bus_container *c, *w;
2598 uint32_t *array_size = NULL;
2611 * We enforce a global limit on container depth, that is much
2612 * higher than the 32 structs and 32 arrays the specification
2613 * mandates. This is simpler to implement for us, and we need
2614 * this only to ensure our container array doesn't grow
2615 * without bounds. We are happy to return any data from a
2616 * message as long as the data itself is valid, even if the
2617 * overall message might be not.
2619 * Note that the message signature is validated when
2620 * parsing the headers, and that validation does check the
2623 * Note that the specification defines no limits on the depth
2624 * of stacked variants, but we do.
2626 if (m->n_containers >= BUS_CONTAINER_DEPTH)
2629 w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
2634 c = message_get_container(m);
2636 if (!c->signature || c->signature[c->index] == 0)
2639 signature = strdup(contents);
2643 c->saved_index = c->index;
2646 if (type == SD_BUS_TYPE_ARRAY)
2647 r = bus_message_enter_array(m, c, contents, &array_size);
2648 else if (type == SD_BUS_TYPE_VARIANT)
2649 r = bus_message_enter_variant(m, c, contents);
2650 else if (type == SD_BUS_TYPE_STRUCT)
2651 r = bus_message_enter_struct(m, c, contents);
2652 else if (type == SD_BUS_TYPE_DICT_ENTRY)
2653 r = bus_message_enter_dict_entry(m, c, contents);
2662 /* OK, let's fill it in */
2663 w += m->n_containers++;
2664 w->enclosing = type;
2665 w->signature = signature;
2667 w->array_size = array_size;
2669 w->begin = m->rindex;
2674 int sd_bus_message_exit_container(sd_bus_message *m) {
2675 struct bus_container *c;
2681 if (m->n_containers <= 0)
2684 c = message_get_container(m);
2685 if (c->enclosing == SD_BUS_TYPE_ARRAY) {
2688 l = BUS_MESSAGE_BSWAP32(m, *c->array_size);
2689 if (c->begin + l != m->rindex)
2693 if (c->signature && c->signature[c->index] != 0)
2703 static void message_quit_container(sd_bus_message *m) {
2704 struct bus_container *c;
2708 assert(m->n_containers > 0);
2710 c = message_get_container(m);
2713 assert(m->rindex >= c->before);
2714 m->rindex = c->before;
2716 /* Free container */
2720 /* Correct index of new top-level container */
2721 c = message_get_container(m);
2722 c->index = c->saved_index;
2725 int sd_bus_message_peek_type(sd_bus_message *m, char *type, const char **contents) {
2726 struct bus_container *c;
2734 c = message_get_container(m);
2736 if (!c->signature || c->signature[c->index] == 0)
2739 if (message_end_of_array(m, m->rindex))
2742 if (bus_type_is_basic(c->signature[c->index])) {
2746 *type = c->signature[c->index];
2750 if (c->signature[c->index] == SD_BUS_TYPE_ARRAY) {
2756 r = signature_element_length(c->signature+c->index+1, &l);
2762 sig = strndup(c->signature + c->index + 1, l);
2766 free(m->peeked_signature);
2767 m->peeked_signature = sig;
2773 *type = SD_BUS_TYPE_ARRAY;
2778 if (c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ||
2779 c->signature[c->index] == SD_BUS_TYPE_DICT_ENTRY_BEGIN) {
2785 r = signature_element_length(c->signature+c->index, &l);
2790 sig = strndup(c->signature + c->index + 1, l - 2);
2794 free(m->peeked_signature);
2795 m->peeked_signature = sig;
2801 *type = c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY;
2806 if (c->signature[c->index] == SD_BUS_TYPE_VARIANT) {
2812 r = message_peek_body(m, &rindex, 1, 1, &q);
2819 r = message_peek_body(m, &rindex, 1, l+1, &q);
2825 if (!validate_signature(q, l))
2832 *type = SD_BUS_TYPE_VARIANT;
2841 *type = c->enclosing;
2847 int sd_bus_message_rewind(sd_bus_message *m, int complete) {
2848 struct bus_container *c;
2856 message_reset_containers(m);
2858 m->root_container.index = 0;
2860 c = message_get_container(m);
2862 c = message_get_container(m);
2865 m->rindex = c->begin;
2868 return !isempty(c->signature);
2870 static int message_read_ap(
2875 unsigned n_array, n_struct;
2876 TypeStack stack[BUS_CONTAINER_DEPTH];
2877 unsigned stack_ptr = 0;
2885 /* Ideally, we'd just call ourselves recursively on every
2886 * complex type. However, the state of a va_list that is
2887 * passed to a function is undefined after that function
2888 * returns. This means we need to docode the va_list linearly
2889 * in a single stackframe. We hence implement our own
2890 * home-grown stack in an array. */
2892 n_array = (unsigned) -1;
2893 n_struct = strlen(types);
2898 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
2899 r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
2905 r = sd_bus_message_exit_container(m);
2913 if (n_array != (unsigned) -1)
2922 case SD_BUS_TYPE_BYTE:
2923 case SD_BUS_TYPE_BOOLEAN:
2924 case SD_BUS_TYPE_INT16:
2925 case SD_BUS_TYPE_UINT16:
2926 case SD_BUS_TYPE_INT32:
2927 case SD_BUS_TYPE_UINT32:
2928 case SD_BUS_TYPE_INT64:
2929 case SD_BUS_TYPE_UINT64:
2930 case SD_BUS_TYPE_DOUBLE:
2931 case SD_BUS_TYPE_STRING:
2932 case SD_BUS_TYPE_OBJECT_PATH:
2933 case SD_BUS_TYPE_SIGNATURE:
2934 case SD_BUS_TYPE_UNIX_FD: {
2937 p = va_arg(ap, void*);
2938 r = sd_bus_message_read_basic(m, *t, p);
2947 case SD_BUS_TYPE_ARRAY: {
2950 r = signature_element_length(t + 1, &k);
2956 memcpy(s, t + 1, k);
2959 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, s);
2966 if (n_array == (unsigned) -1) {
2971 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2977 n_array = va_arg(ap, unsigned);
2982 case SD_BUS_TYPE_VARIANT: {
2985 s = va_arg(ap, const char *);
2989 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, s);
2995 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
3000 n_struct = strlen(s);
3001 n_array = (unsigned) -1;
3006 case SD_BUS_TYPE_STRUCT_BEGIN:
3007 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
3010 r = signature_element_length(t, &k);
3016 memcpy(s, t + 1, k - 2);
3019 r = sd_bus_message_enter_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
3026 if (n_array == (unsigned) -1) {
3031 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
3037 n_array = (unsigned) -1;
3050 int sd_bus_message_read(sd_bus_message *m, const char *types, ...) {
3061 va_start(ap, types);
3062 r = message_read_ap(m, types, ap);
3068 int sd_bus_message_read_array(sd_bus_message *m, char type, const void **ptr, size_t *size) {
3069 struct bus_container *c;
3079 if (!bus_type_is_trivial(type))
3085 if (BUS_MESSAGE_NEED_BSWAP(m))
3088 align = bus_type_get_alignment(type);
3092 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
3096 c = message_get_container(m);
3097 sz = BUS_MESSAGE_BSWAP32(m, *c->array_size);
3099 r = message_peek_body(m, &m->rindex, align, sz, &p);
3107 r = sd_bus_message_exit_container(m);
3111 *ptr = (const void*) p;
3117 message_quit_container(m);
3121 static int message_peek_fields(
3132 return buffer_peek(m->fields, BUS_MESSAGE_FIELDS_SIZE(m), rindex, align, nbytes, ret);
3135 static int message_peek_field_uint32(
3146 r = message_peek_fields(m, ri, 4, 4, &q);
3151 *ret = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
3156 static int message_peek_field_string(
3158 bool (*validate)(const char *p),
3169 r = message_peek_field_uint32(m, ri, &l);
3173 r = message_peek_fields(m, ri, 1, l+1, &q);
3178 if (!validate_nul(q, l))
3184 if (!validate_string(q, l))
3194 static int message_peek_field_signature(
3206 r = message_peek_fields(m, ri, 1, 1, &q);
3211 r = message_peek_fields(m, ri, 1, l+1, &q);
3215 if (!validate_signature(q, l))
3224 static int message_skip_fields(
3227 uint32_t array_size,
3228 const char **signature) {
3230 size_t original_index;
3237 original_index = *ri;
3243 if (array_size != (uint32_t) -1 &&
3244 array_size <= *ri - original_index)
3251 if (t == SD_BUS_TYPE_STRING) {
3253 r = message_peek_field_string(m, NULL, ri, NULL);
3259 } else if (t == SD_BUS_TYPE_OBJECT_PATH) {
3261 r = message_peek_field_string(m, object_path_is_valid, ri, NULL);
3267 } else if (t == SD_BUS_TYPE_SIGNATURE) {
3269 r = message_peek_field_signature(m, ri, NULL);
3275 } else if (bus_type_is_basic(t)) {
3278 align = bus_type_get_alignment(t);
3279 k = bus_type_get_size(t);
3280 assert(align > 0 && k > 0);
3282 r = message_peek_fields(m, ri, align, k, NULL);
3288 } else if (t == SD_BUS_TYPE_ARRAY) {
3290 r = signature_element_length(*signature+1, &l);
3300 strncpy(sig, *signature + 1, l-1);
3303 alignment = bus_type_get_alignment(sig[0]);
3307 r = message_peek_field_uint32(m, ri, &nas);
3310 if (nas > BUS_ARRAY_MAX_SIZE)
3313 r = message_peek_fields(m, ri, alignment, 0, NULL);
3317 r = message_skip_fields(m, ri, nas, (const char**) &s);
3322 (*signature) += 1 + l;
3324 } else if (t == SD_BUS_TYPE_VARIANT) {
3327 r = message_peek_field_signature(m, ri, &s);
3331 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
3337 } else if (t == SD_BUS_TYPE_STRUCT ||
3338 t == SD_BUS_TYPE_DICT_ENTRY) {
3340 r = signature_element_length(*signature, &l);
3347 strncpy(sig, *signature + 1, l-1);
3350 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
3361 int bus_message_parse_fields(sd_bus_message *m) {
3364 uint32_t unix_fds = 0;
3368 for (ri = 0; ri < BUS_MESSAGE_FIELDS_SIZE(m); ) {
3369 const char *signature;
3372 r = message_peek_fields(m, &ri, 8, 1, (void**) &header);
3376 r = message_peek_field_signature(m, &ri, &signature);
3381 case _SD_BUS_MESSAGE_HEADER_INVALID:
3384 case SD_BUS_MESSAGE_HEADER_PATH:
3389 if (!streq(signature, "o"))
3392 r = message_peek_field_string(m, object_path_is_valid, &ri, &m->path);
3395 case SD_BUS_MESSAGE_HEADER_INTERFACE:
3400 if (!streq(signature, "s"))
3403 r = message_peek_field_string(m, interface_name_is_valid, &ri, &m->interface);
3406 case SD_BUS_MESSAGE_HEADER_MEMBER:
3411 if (!streq(signature, "s"))
3414 r = message_peek_field_string(m, member_name_is_valid, &ri, &m->member);
3417 case SD_BUS_MESSAGE_HEADER_ERROR_NAME:
3422 if (!streq(signature, "s"))
3425 r = message_peek_field_string(m, error_name_is_valid, &ri, &m->error.name);
3428 case SD_BUS_MESSAGE_HEADER_DESTINATION:
3433 if (!streq(signature, "s"))
3436 r = message_peek_field_string(m, service_name_is_valid, &ri, &m->destination);
3439 case SD_BUS_MESSAGE_HEADER_SENDER:
3444 if (!streq(signature, "s"))
3447 r = message_peek_field_string(m, service_name_is_valid, &ri, &m->sender);
3451 case SD_BUS_MESSAGE_HEADER_SIGNATURE: {
3455 if (m->root_container.signature)
3458 if (!streq(signature, "g"))
3461 r = message_peek_field_signature(m, &ri, &s);
3469 free(m->root_container.signature);
3470 m->root_container.signature = c;
3474 case SD_BUS_MESSAGE_HEADER_REPLY_SERIAL:
3475 if (m->reply_serial != 0)
3478 if (!streq(signature, "u"))
3481 r = message_peek_field_uint32(m, &ri, &m->reply_serial);
3485 if (m->reply_serial == 0)
3490 case SD_BUS_MESSAGE_HEADER_UNIX_FDS:
3494 if (!streq(signature, "u"))
3497 r = message_peek_field_uint32(m, &ri, &unix_fds);
3507 r = message_skip_fields(m, &ri, (uint32_t) -1, (const char **) &signature);
3514 if (m->n_fds != unix_fds)
3517 if (isempty(m->root_container.signature) != (BUS_MESSAGE_BODY_SIZE(m) == 0))
3520 switch (m->header->type) {
3522 case SD_BUS_MESSAGE_TYPE_SIGNAL:
3523 if (!m->path || !m->interface || !m->member)
3527 case SD_BUS_MESSAGE_TYPE_METHOD_CALL:
3529 if (!m->path || !m->member)
3534 case SD_BUS_MESSAGE_TYPE_METHOD_RETURN:
3536 if (m->reply_serial == 0)
3540 case SD_BUS_MESSAGE_TYPE_METHOD_ERROR:
3542 if (m->reply_serial == 0 || !m->error.name)
3547 /* Try to read the error message, but if we can't it's a non-issue */
3548 if (m->header->type == SD_BUS_MESSAGE_TYPE_METHOD_ERROR)
3549 sd_bus_message_read(m, "s", &m->error.message);
3554 int bus_message_seal(sd_bus_message *m, uint64_t serial) {
3563 if (m->n_containers > 0)
3566 /* If there's a non-trivial signature set, then add it in here */
3567 if (!isempty(m->root_container.signature)) {
3568 r = message_append_field_signature(m, SD_BUS_MESSAGE_HEADER_SIGNATURE, m->root_container.signature, NULL);
3574 r = message_append_field_uint32(m, SD_BUS_MESSAGE_HEADER_UNIX_FDS, m->n_fds);
3579 l = BUS_MESSAGE_FIELDS_SIZE(m);
3583 /* Add padding at the end, since we know the body
3584 * needs to start at an 8 byte alignment. */
3587 p = message_extend_fields(m, 1, a);
3592 m->header->fields_size -= a;
3595 m->header->serial = serial;
3601 int sd_bus_message_set_destination(sd_bus_message *m, const char *destination) {
3611 return message_append_field_string(m, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &m->destination);
3614 int bus_message_dump(sd_bus_message *m) {
3615 const char *u = NULL, *uu = NULL, *s = NULL;
3616 char **cmdline = NULL;
3619 uid_t owner, audit_loginuid;
3620 uint32_t audit_sessionid;
3624 printf("Message %p\n"
3631 "\tfields_size=%u\n"
3636 "\tdestination=%s\n"
3639 "\treply_serial=%u\n"
3641 "\terror.message=%s\n"
3649 BUS_MESSAGE_SERIAL(m),
3650 BUS_MESSAGE_FIELDS_SIZE(m),
3651 BUS_MESSAGE_BODY_SIZE(m),
3653 strna(m->interface),
3655 strna(m->destination),
3657 strna(m->root_container.signature),
3659 strna(m->error.name),
3660 strna(m->error.message),
3664 printf("\tpid=%lu\n", (unsigned long) m->pid);
3666 printf("\ttid=%lu\n", (unsigned long) m->tid);
3668 printf("\tuid=%lu\n", (unsigned long) m->uid);
3670 printf("\tgid=%lu\n", (unsigned long) m->gid);
3671 if (m->pid_starttime != 0)
3672 printf("\tpid_starttime=%llu\n", (unsigned long long) m->pid_starttime);
3673 if (m->monotonic != 0)
3674 printf("\tmonotonic=%llu\n", (unsigned long long) m->monotonic);
3675 if (m->realtime != 0)
3676 printf("\trealtime=%llu\n", (unsigned long long) m->realtime);
3678 printf("\texe=[%s]\n", m->exe);
3680 printf("\tcomm=[%s]\n", m->comm);
3682 printf("\ttid_comm=[%s]\n", m->tid_comm);
3684 printf("\tlabel=[%s]\n", m->label);
3686 printf("\tcgroup=[%s]\n", m->cgroup);
3688 sd_bus_message_get_unit(m, &u);
3690 printf("\tunit=[%s]\n", u);
3691 sd_bus_message_get_user_unit(m, &uu);
3693 printf("\tuser_unit=[%s]\n", uu);
3694 sd_bus_message_get_session(m, &s);
3696 printf("\tsession=[%s]\n", s);
3697 if (sd_bus_message_get_owner_uid(m, &owner) >= 0)
3698 printf("\towner_uid=%lu\n", (unsigned long) owner);
3699 if (sd_bus_message_get_audit_loginuid(m, &audit_loginuid) >= 0)
3700 printf("\taudit_loginuid=%lu\n", (unsigned long) audit_loginuid);
3701 if (sd_bus_message_get_audit_sessionid(m, &audit_sessionid) >= 0)
3702 printf("\taudit_sessionid=%lu\n", (unsigned long) audit_sessionid);
3704 printf("\tCAP_KILL=%i\n", sd_bus_message_has_effective_cap(m, 5));
3706 if (sd_bus_message_get_cmdline(m, &cmdline) >= 0) {
3709 fputs("\tcmdline=[", stdout);
3710 STRV_FOREACH(c, cmdline) {
3717 fputs("]\n", stdout);
3720 r = sd_bus_message_rewind(m, true);
3722 log_error("Failed to rewind: %s", strerror(-r));
3726 printf("BEGIN_MESSAGE \"%s\" {\n", strempty(m->root_container.signature));
3729 _cleanup_free_ char *prefix = NULL;
3730 const char *contents = NULL;
3745 r = sd_bus_message_peek_type(m, &type, &contents);
3747 log_error("Failed to peek type: %s", strerror(-r));
3754 r = sd_bus_message_exit_container(m);
3756 log_error("Failed to exit container: %s", strerror(-r));
3762 prefix = strrep("\t", level);
3766 if (type == SD_BUS_TYPE_ARRAY)
3767 printf("%s} END_ARRAY \n", prefix);
3768 else if (type == SD_BUS_TYPE_VARIANT)
3769 printf("%s} END_VARIANT\n", prefix);
3770 else if (type == SD_BUS_TYPE_STRUCT)
3771 printf("%s} END_STRUCT\n", prefix);
3772 else if (type == SD_BUS_TYPE_DICT_ENTRY)
3773 printf("%s} END_DICT_ENTRY\n", prefix);
3778 prefix = strrep("\t", level);
3782 if (bus_type_is_container(type) > 0) {
3783 r = sd_bus_message_enter_container(m, type, contents);
3785 log_error("Failed to enter container: %s", strerror(-r));
3789 if (type == SD_BUS_TYPE_ARRAY)
3790 printf("%sBEGIN_ARRAY \"%s\" {\n", prefix, contents);
3791 else if (type == SD_BUS_TYPE_VARIANT)
3792 printf("%sBEGIN_VARIANT \"%s\" {\n", prefix, contents);
3793 else if (type == SD_BUS_TYPE_STRUCT)
3794 printf("%sBEGIN_STRUCT \"%s\" {\n", prefix, contents);
3795 else if (type == SD_BUS_TYPE_DICT_ENTRY)
3796 printf("%sBEGIN_DICT_ENTRY \"%s\" {\n", prefix, contents);
3803 r = sd_bus_message_read_basic(m, type, &basic);
3805 log_error("Failed to get basic: %s", strerror(-r));
3811 case SD_BUS_TYPE_BYTE:
3812 printf("%sBYTE: %u\n", prefix, basic.u8);
3815 case SD_BUS_TYPE_BOOLEAN:
3816 printf("%sBOOLEAN: %s\n", prefix, yes_no(basic.i));
3819 case SD_BUS_TYPE_INT16:
3820 printf("%sINT16: %i\n", prefix, basic.s16);
3823 case SD_BUS_TYPE_UINT16:
3824 printf("%sUINT16: %u\n", prefix, basic.u16);
3827 case SD_BUS_TYPE_INT32:
3828 printf("%sINT32: %i\n", prefix, basic.s32);
3831 case SD_BUS_TYPE_UINT32:
3832 printf("%sUINT32: %u\n", prefix, basic.u32);
3835 case SD_BUS_TYPE_INT64:
3836 printf("%sINT64: %lli\n", prefix, (long long) basic.s64);
3839 case SD_BUS_TYPE_UINT64:
3840 printf("%sUINT64: %llu\n", prefix, (unsigned long long) basic.u64);
3843 case SD_BUS_TYPE_DOUBLE:
3844 printf("%sDOUBLE: %g\n", prefix, basic.d64);
3847 case SD_BUS_TYPE_STRING:
3848 printf("%sSTRING: \"%s\"\n", prefix, basic.string);
3851 case SD_BUS_TYPE_OBJECT_PATH:
3852 printf("%sOBJECT_PATH: \"%s\"\n", prefix, basic.string);
3855 case SD_BUS_TYPE_SIGNATURE:
3856 printf("%sSIGNATURE: \"%s\"\n", prefix, basic.string);
3859 case SD_BUS_TYPE_UNIX_FD:
3860 printf("%sUNIX_FD: %i\n", prefix, basic.i);
3864 assert_not_reached("Unknown basic type.");
3868 printf("} END_MESSAGE\n");
3872 int bus_message_get_blob(sd_bus_message *m, void **buffer, size_t *sz) {
3876 struct bus_body_part *part;
3882 total = BUS_MESSAGE_SIZE(m);
3888 e = mempcpy(p, m->header, sizeof(*m->header));
3891 e = mempcpy(e, m->fields, m->header->fields_size);
3893 if (m->header->fields_size % 8 != 0)
3894 e = mempset(e, 0, 8 - (m->header->fields_size % 8));
3897 for (i = 0, part = &m->body; i < m->n_body_parts; i++, part = part->next)
3898 e = mempcpy(e, part->data, part->size);
3900 assert(total == (size_t) ((uint8_t*) e - (uint8_t*) p));
3908 int bus_message_read_strv_extend(sd_bus_message *m, char ***l) {
3914 r = sd_bus_message_enter_container(m, 'a', "s");
3921 r = sd_bus_message_read_basic(m, 's', &s);
3927 r = strv_extend(l, s);
3932 r = sd_bus_message_exit_container(m);
3939 const char* bus_message_get_arg(sd_bus_message *m, unsigned i) {
3941 const char *t = NULL;
3946 r = sd_bus_message_rewind(m, true);
3950 for (j = 0; j <= i; j++) {
3953 r = sd_bus_message_peek_type(m, &type, NULL);
3957 if (type != SD_BUS_TYPE_STRING &&
3958 type != SD_BUS_TYPE_OBJECT_PATH &&
3959 type != SD_BUS_TYPE_SIGNATURE)
3962 r = sd_bus_message_read_basic(m, type, &t);
3970 int bus_header_size(struct bus_header *h, size_t *sum) {
3976 if (h->endian == SD_BUS_NATIVE_ENDIAN) {
3977 fs = h->fields_size;
3979 } else if (h->endian == SD_BUS_REVERSE_ENDIAN) {
3980 fs = bswap_32(h->fields_size);
3981 bs = bswap_32(h->body_size);
3985 *sum = sizeof(struct bus_header) + ALIGN8(fs) + bs;