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) {
119 message_reset_parts(m);
124 if (m->release_kdbus)
125 ioctl(m->bus->input_fd, KDBUS_CMD_MSG_RELEASE, m->kdbus);
128 close_many(m->fds, m->n_fds);
133 sd_bus_unref(m->bus);
135 if (m->iovec != m->iovec_fixed)
138 free(m->cmdline_array);
140 message_reset_containers(m);
141 free(m->root_container.signature);
143 free(m->peeked_signature);
151 static void *message_extend_fields(sd_bus_message *m, size_t align, size_t sz) {
153 size_t old_size, new_size, start;
160 old_size = sizeof(struct bus_header) + m->header->fields_size;
161 start = ALIGN_TO(old_size, align);
162 new_size = start + sz;
164 if (old_size == new_size)
165 return (uint8_t*) m->header + old_size;
167 if (new_size > (size_t) ((uint32_t) -1))
170 if (m->free_header) {
171 np = realloc(m->header, ALIGN8(new_size));
175 /* Initially, the header is allocated as part of of
176 * the sd_bus_message itself, let's replace it by
179 np = malloc(ALIGN8(new_size));
183 memcpy(np, m->header, sizeof(struct bus_header));
186 /* Zero out padding */
187 if (start > old_size)
188 memset((uint8_t*) np + old_size, 0, start - old_size);
192 m->header->fields_size = new_size - sizeof(struct bus_header);
194 /* Adjust quick access pointers */
195 m->path = adjust_pointer(m->path, op, old_size, m->header);
196 m->interface = adjust_pointer(m->interface, op, old_size, m->header);
197 m->member = adjust_pointer(m->member, op, old_size, m->header);
198 m->destination = adjust_pointer(m->destination, op, old_size, m->header);
199 m->sender = adjust_pointer(m->sender, op, old_size, m->header);
200 m->error.name = adjust_pointer(m->error.name, op, old_size, m->header);
202 m->free_header = true;
204 return (uint8_t*) np + start;
211 static int message_append_field_string(
224 if (l > (size_t) (uint32_t) -1)
227 /* field id byte + signature length + signature 's' + NUL + string length + string + NUL */
228 p = message_extend_fields(m, 8, 4 + 4 + l + 1);
237 ((uint32_t*) p)[1] = l;
238 memcpy(p + 8, s, l + 1);
241 *ret = (char*) p + 8;
246 static int message_append_field_signature(
261 /* field id byte + signature length + signature 'g' + NUL + string length + string + NUL */
262 p = message_extend_fields(m, 8, 4 + 1 + l + 1);
268 p[2] = SD_BUS_TYPE_SIGNATURE;
271 memcpy(p + 5, s, l + 1);
274 *ret = (const char*) p + 5;
279 static int message_append_field_uint32(sd_bus_message *m, uint8_t h, uint32_t x) {
284 /* field id byte + signature length + signature 'u' + NUL + value */
285 p = message_extend_fields(m, 8, 4 + 4);
291 p[2] = SD_BUS_TYPE_UINT32;
294 ((uint32_t*) p)[1] = x;
299 int bus_message_from_header(
304 const struct ucred *ucred,
307 sd_bus_message **ret) {
310 struct bus_header *h;
313 assert(buffer || length <= 0);
314 assert(fds || n_fds <= 0);
317 if (length < sizeof(struct bus_header))
327 if (h->type == _SD_BUS_MESSAGE_TYPE_INVALID)
330 if (h->endian != SD_BUS_LITTLE_ENDIAN &&
331 h->endian != SD_BUS_BIG_ENDIAN)
334 a = ALIGN(sizeof(sd_bus_message)) + ALIGN(extra);
337 label_sz = strlen(label);
355 m->uid_valid = m->gid_valid = true;
359 m->label = (char*) m + ALIGN(sizeof(sd_bus_message)) + ALIGN(extra);
360 memcpy(m->label, label, label_sz + 1);
367 int bus_message_from_malloc(
372 const struct ucred *ucred,
374 sd_bus_message **ret) {
379 r = bus_message_from_header(buffer, length, fds, n_fds, ucred, label, 0, &m);
383 if (length != BUS_MESSAGE_SIZE(m)) {
389 m->body.data = (uint8_t*) buffer + sizeof(struct bus_header) + ALIGN8(BUS_MESSAGE_FIELDS_SIZE(m));
390 m->body.size = length - sizeof(struct bus_header) - ALIGN8(BUS_MESSAGE_FIELDS_SIZE(m));
391 m->body.sealed = true;
395 m->iovec = m->iovec_fixed;
396 m->iovec[0].iov_base = buffer;
397 m->iovec[0].iov_len = length;
399 r = bus_message_parse_fields(m);
403 /* We take possession of the memory and fds now */
404 m->free_header = true;
415 static sd_bus_message *message_new(sd_bus *bus, uint8_t type) {
418 m = malloc0(ALIGN(sizeof(sd_bus_message)) + sizeof(struct bus_header));
423 m->header = (struct bus_header*) ((uint8_t*) m + ALIGN(sizeof(struct sd_bus_message)));
424 m->header->endian = SD_BUS_NATIVE_ENDIAN;
425 m->header->type = type;
426 m->header->version = bus ? bus->message_version : 1;
427 m->allow_fds = !bus || bus->can_fds || (bus->state != BUS_HELLO && bus->state != BUS_RUNNING);
430 m->bus = sd_bus_ref(bus);
435 int sd_bus_message_new_signal(
438 const char *interface,
440 sd_bus_message **m) {
453 if (bus && bus->state == BUS_UNSET)
456 t = message_new(bus, SD_BUS_MESSAGE_TYPE_SIGNAL);
460 t->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
462 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_PATH, SD_BUS_TYPE_OBJECT_PATH, path, &t->path);
465 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_INTERFACE, SD_BUS_TYPE_STRING, interface, &t->interface);
468 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_MEMBER, SD_BUS_TYPE_STRING, member, &t->member);
476 sd_bus_message_unref(t);
480 int sd_bus_message_new_method_call(
482 const char *destination,
484 const char *interface,
486 sd_bus_message **m) {
497 if (bus && bus->state == BUS_UNSET)
500 t = message_new(bus, SD_BUS_MESSAGE_TYPE_METHOD_CALL);
504 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_PATH, SD_BUS_TYPE_OBJECT_PATH, path, &t->path);
507 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_MEMBER, SD_BUS_TYPE_STRING, member, &t->member);
512 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_INTERFACE, SD_BUS_TYPE_STRING, interface, &t->interface);
518 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &t->destination);
531 static int message_new_reply(
533 sd_bus_message *call,
535 sd_bus_message **m) {
544 if (call->header->type != SD_BUS_MESSAGE_TYPE_METHOD_CALL)
548 if (bus && bus->state == BUS_UNSET)
551 t = message_new(bus, type);
555 t->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
556 t->reply_serial = BUS_MESSAGE_SERIAL(call);
558 r = message_append_field_uint32(t, SD_BUS_MESSAGE_HEADER_REPLY_SERIAL, t->reply_serial);
563 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, call->sender, &t->sender);
568 t->dont_send = !!(call->header->flags & SD_BUS_MESSAGE_NO_REPLY_EXPECTED);
578 int sd_bus_message_new_method_return(
580 sd_bus_message *call,
581 sd_bus_message **m) {
583 return message_new_reply(bus, call, SD_BUS_MESSAGE_TYPE_METHOD_RETURN, m);
586 int sd_bus_message_new_method_error(
588 sd_bus_message *call,
589 const sd_bus_error *e,
590 sd_bus_message **m) {
595 if (!sd_bus_error_is_set(e))
600 r = message_new_reply(bus, call, SD_BUS_MESSAGE_TYPE_METHOD_ERROR, &t);
604 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_ERROR_NAME, SD_BUS_TYPE_STRING, e->name, &t->error.name);
609 r = message_append_basic(t, SD_BUS_TYPE_STRING, e->message, (const void**) &t->error.message);
622 sd_bus_message* sd_bus_message_ref(sd_bus_message *m) {
626 assert(m->n_ref > 0);
632 sd_bus_message* sd_bus_message_unref(sd_bus_message *m) {
636 assert(m->n_ref > 0);
645 int sd_bus_message_get_type(sd_bus_message *m, uint8_t *type) {
651 *type = m->header->type;
655 int sd_bus_message_get_serial(sd_bus_message *m, uint64_t *serial) {
660 if (m->header->serial == 0)
663 *serial = BUS_MESSAGE_SERIAL(m);
667 int sd_bus_message_get_reply_serial(sd_bus_message *m, uint64_t *serial) {
672 if (m->reply_serial == 0)
675 *serial = m->reply_serial;
679 int sd_bus_message_get_no_reply(sd_bus_message *m) {
683 return m->header->type == SD_BUS_MESSAGE_TYPE_METHOD_CALL ? !!(m->header->flags & SD_BUS_MESSAGE_NO_REPLY_EXPECTED) : 0;
686 const char *sd_bus_message_get_path(sd_bus_message *m) {
693 const char *sd_bus_message_get_interface(sd_bus_message *m) {
700 const char *sd_bus_message_get_member(sd_bus_message *m) {
706 const char *sd_bus_message_get_destination(sd_bus_message *m) {
710 return m->destination;
713 const char *sd_bus_message_get_sender(sd_bus_message *m) {
720 const sd_bus_error *sd_bus_message_get_error(sd_bus_message *m) {
724 if (!sd_bus_error_is_set(&m->error))
730 int sd_bus_message_get_uid(sd_bus_message *m, uid_t *uid) {
742 int sd_bus_message_get_gid(sd_bus_message *m, gid_t *gid) {
754 int sd_bus_message_get_pid(sd_bus_message *m, pid_t *pid) {
766 int sd_bus_message_get_tid(sd_bus_message *m, pid_t *tid) {
778 int sd_bus_message_get_pid_starttime(sd_bus_message *m, uint64_t *usec) {
783 if (m->pid_starttime <= 0)
786 *usec = m->pid_starttime;
790 int sd_bus_message_get_selinux_context(sd_bus_message *m, const char **ret) {
800 int sd_bus_message_get_monotonic_timestamp(sd_bus_message *m, uint64_t *usec) {
805 if (m->monotonic <= 0)
808 *usec = m->monotonic;
812 int sd_bus_message_get_realtime_timestamp(sd_bus_message *m, uint64_t *usec) {
817 if (m->realtime <= 0)
824 int sd_bus_message_get_comm(sd_bus_message *m, const char **ret) {
836 int sd_bus_message_get_tid_comm(sd_bus_message *m, const char **ret) {
848 int sd_bus_message_get_exe(sd_bus_message *m, const char **ret) {
860 int sd_bus_message_get_cgroup(sd_bus_message *m, const char **ret) {
872 int sd_bus_message_get_unit(sd_bus_message *m, const char **ret) {
883 r = cg_path_get_unit(m->cgroup, &m->unit);
892 int sd_bus_message_get_user_unit(sd_bus_message *m, const char **ret) {
903 r = cg_path_get_user_unit(m->cgroup, &m->user_unit);
912 int sd_bus_message_get_session(sd_bus_message *m, const char **ret) {
923 r = cg_path_get_session(m->cgroup, &m->session);
932 int sd_bus_message_get_owner_uid(sd_bus_message *m, uid_t *uid) {
940 return cg_path_get_owner_uid(m->cgroup, uid);
943 int sd_bus_message_get_cmdline(sd_bus_message *m, char ***cmdline) {
954 for (p = m->cmdline, n = 0; p < m->cmdline + m->cmdline_length; p++)
958 m->cmdline_array = new(char*, n + 1);
959 if (!m->cmdline_array)
962 for (p = m->cmdline, i = 0, first = true; p < m->cmdline + m->cmdline_length; p++) {
964 m->cmdline_array[i++] = (char*) p;
969 m->cmdline_array[i] = NULL;
970 *cmdline = m->cmdline_array;
975 int sd_bus_message_get_audit_sessionid(sd_bus_message *m, uint32_t *sessionid) {
983 *sessionid = m->audit->sessionid;
987 int sd_bus_message_get_audit_loginuid(sd_bus_message *m, uid_t *uid) {
995 *uid = m->audit->loginuid;
999 int sd_bus_message_has_effective_cap(sd_bus_message *m, int capability) {
1009 sz = m->capability_size / 4;
1010 if ((unsigned) capability >= sz*8)
1013 return !!(m->capability[2 * sz + (capability / 8)] & (1 << (capability % 8)));
1016 int sd_bus_message_is_signal(sd_bus_message *m, const char *interface, const char *member) {
1020 if (m->header->type != SD_BUS_MESSAGE_TYPE_SIGNAL)
1023 if (interface && (!m->interface || !streq(m->interface, interface)))
1026 if (member && (!m->member || !streq(m->member, member)))
1032 int sd_bus_message_is_method_call(sd_bus_message *m, const char *interface, const char *member) {
1036 if (m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_CALL)
1039 if (interface && (!m->interface || !streq(m->interface, interface)))
1042 if (member && (!m->member || !streq(m->member, member)))
1048 int sd_bus_message_is_method_error(sd_bus_message *m, const char *name) {
1052 if (m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_ERROR)
1055 if (name && (!m->error.name || !streq(m->error.name, name)))
1061 int sd_bus_message_set_no_reply(sd_bus_message *m, int b) {
1066 if (m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_CALL)
1070 m->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
1072 m->header->flags &= ~SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
1077 static struct bus_container *message_get_container(sd_bus_message *m) {
1080 if (m->n_containers == 0)
1081 return &m->root_container;
1083 assert(m->containers);
1084 return m->containers + m->n_containers - 1;
1087 struct bus_body_part *message_append_part(sd_bus_message *m) {
1088 struct bus_body_part *part;
1095 if (m->n_body_parts <= 0) {
1099 assert(m->body_end);
1101 part = new0(struct bus_body_part, 1);
1107 m->body_end->next = part;
1117 static void part_zero(struct bus_body_part *part, size_t sz) {
1126 static int part_make_space(
1127 struct sd_bus_message *m,
1128 struct bus_body_part *part,
1137 assert(!part->sealed);
1142 if (!part->data && part->memfd < 0)
1143 part->memfd = bus_kernel_pop_memfd(m->bus, &part->data, &part->mapped);
1145 if (part->memfd >= 0) {
1148 r = ioctl(part->memfd, KDBUS_CMD_MEMFD_SIZE_SET, &u);
1154 if (sz > part->mapped) {
1155 size_t psz = PAGE_ALIGN(sz);
1157 if (part->mapped <= 0)
1158 n = mmap(NULL, psz, PROT_READ|PROT_WRITE, MAP_SHARED, part->memfd, 0);
1160 n = mremap(part->data, part->mapped, psz, MREMAP_MAYMOVE);
1162 if (n == MAP_FAILED) {
1171 n = realloc(part->data, sz);
1178 part->free_this = true;
1182 *q = part->data ? (uint8_t*) part->data + part->size : NULL;
1188 static void *message_extend_body(sd_bus_message *m, size_t align, size_t sz) {
1189 struct bus_container *c;
1190 struct bus_body_part *part = NULL;
1191 size_t start_body, end_body, padding, start_part, end_part, added;
1203 start_body = ALIGN_TO((size_t) m->header->body_size, align);
1204 end_body = start_body + sz;
1206 padding = start_body - m->header->body_size;
1207 added = padding + sz;
1209 /* Check for 32bit overflows */
1210 if (end_body > (size_t) ((uint32_t) -1)) {
1216 m->n_body_parts <= 0 ||
1217 m->body_end->sealed ||
1218 padding != ALIGN_TO(m->body_end->size, align) - m->body_end->size;
1222 part = message_append_part(m);
1226 part_zero(part, padding);
1229 part = message_append_part(m);
1233 r = part_make_space(m, part, sz, &p);
1244 start_part = ALIGN_TO(part->size, align);
1245 end_part = start_part + sz;
1247 r = part_make_space(m, part, end_part, &p);
1252 memset(p, 0, padding);
1253 p = (uint8_t*) p + padding;
1256 /* Readjust pointers */
1257 for (c = m->containers; c < m->containers + m->n_containers; c++)
1258 c->array_size = adjust_pointer(c->array_size, op, os, part->data);
1260 m->error.message = (const char*) adjust_pointer(m->error.message, op, os, part->data);
1263 /* Update counters */
1264 for (c = m->containers; c < m->containers + m->n_containers; c++)
1266 *c->array_size += added;
1268 m->header->body_size = end_body;
1273 int message_append_basic(sd_bus_message *m, char type, const void *p, const void **stored) {
1274 struct bus_container *c;
1289 if (!bus_type_is_basic(type))
1294 c = message_get_container(m);
1296 if (c->signature && c->signature[c->index]) {
1297 /* Container signature is already set */
1299 if (c->signature[c->index] != type)
1302 /* Maybe we can append to the signature? But only if this is the top-level container*/
1303 if (c->enclosing != 0)
1306 e = strextend(&c->signature, CHAR_TO_STR(type), NULL);
1315 case SD_BUS_TYPE_STRING:
1316 case SD_BUS_TYPE_OBJECT_PATH:
1319 sz = 4 + strlen(p) + 1;
1322 case SD_BUS_TYPE_SIGNATURE:
1325 sz = 1 + strlen(p) + 1;
1328 case SD_BUS_TYPE_BOOLEAN:
1331 assert_cc(sizeof(int) == sizeof(uint32_t));
1337 case SD_BUS_TYPE_UNIX_FD: {
1340 if (!m->allow_fds) {
1353 fd = fcntl(z, F_DUPFD_CLOEXEC, 3);
1359 f = realloc(m->fds, sizeof(int) * (m->n_fds + 1));
1374 align = bus_type_get_alignment(type);
1375 sz = bus_type_get_size(type);
1382 a = message_extend_body(m, align, sz);
1388 if (type == SD_BUS_TYPE_STRING || type == SD_BUS_TYPE_OBJECT_PATH) {
1389 *(uint32_t*) a = sz - 5;
1390 memcpy((uint8_t*) a + 4, p, sz - 4);
1393 *stored = (const uint8_t*) a + 4;
1395 } else if (type == SD_BUS_TYPE_SIGNATURE) {
1396 *(uint8_t*) a = sz - 1;
1397 memcpy((uint8_t*) a + 1, p, sz - 1);
1400 *stored = (const uint8_t*) a + 1;
1401 } else if (type == SD_BUS_TYPE_UNIX_FD) {
1402 *(uint32_t*) a = fdi;
1416 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1423 close_nointr_nofail(fd);
1428 int sd_bus_message_append_basic(sd_bus_message *m, char type, const void *p) {
1429 return message_append_basic(m, type, p, NULL);
1432 int sd_bus_message_append_string_space(sd_bus_message *m, size_t size, char **s) {
1433 struct bus_container *c;
1446 c = message_get_container(m);
1448 if (c->signature && c->signature[c->index]) {
1449 /* Container signature is already set */
1451 if (c->signature[c->index] != SD_BUS_TYPE_STRING)
1454 /* Maybe we can append to the signature? But only if this is the top-level container*/
1455 if (c->enclosing != 0)
1458 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRING), NULL);
1466 a = message_extend_body(m, 4, 4 + size + 1);
1470 *(uint32_t*) a = size;
1475 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1481 static int bus_message_open_array(
1483 struct bus_container *c,
1484 const char *contents,
1485 uint32_t **array_size) {
1492 struct bus_body_part *o;
1499 if (!signature_is_single(contents))
1502 alignment = bus_type_get_alignment(contents[0]);
1506 if (c->signature && c->signature[c->index]) {
1508 /* Verify the existing signature */
1510 if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
1513 if (!startswith(c->signature + c->index + 1, contents))
1516 nindex = c->index + 1 + strlen(contents);
1518 if (c->enclosing != 0)
1521 /* Extend the existing signature */
1523 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_ARRAY), contents, NULL);
1529 nindex = e - c->signature;
1532 a = message_extend_body(m, 4, 4);
1537 op = m->body_end->data;
1538 os = m->body_end->size;
1540 /* Add alignment between size and first element */
1541 if (!message_extend_body(m, alignment, 0))
1544 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1547 /* location of array size might have changed so let's readjust a */
1548 if (o == m->body_end)
1549 a = adjust_pointer(a, op, os, m->body_end->data);
1556 static int bus_message_open_variant(
1558 struct bus_container *c,
1559 const char *contents) {
1569 if (!signature_is_single(contents))
1572 if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
1575 if (c->signature && c->signature[c->index]) {
1577 if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
1581 if (c->enclosing != 0)
1584 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_VARIANT), NULL);
1591 l = strlen(contents);
1592 a = message_extend_body(m, 1, 1 + l + 1);
1597 memcpy((uint8_t*) a + 1, contents, l + 1);
1599 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1605 static int bus_message_open_struct(
1607 struct bus_container *c,
1608 const char *contents) {
1617 if (!signature_is_valid(contents, false))
1620 if (c->signature && c->signature[c->index]) {
1623 l = strlen(contents);
1625 if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
1626 !startswith(c->signature + c->index + 1, contents) ||
1627 c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
1630 nindex = c->index + 1 + l + 1;
1632 if (c->enclosing != 0)
1635 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_BEGIN), contents, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_END), NULL);
1641 nindex = e - c->signature;
1644 /* Align contents to 8 byte boundary */
1645 if (!message_extend_body(m, 8, 0))
1648 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1654 static int bus_message_open_dict_entry(
1656 struct bus_container *c,
1657 const char *contents) {
1665 if (!signature_is_pair(contents))
1668 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1671 if (c->signature && c->signature[c->index]) {
1674 l = strlen(contents);
1676 if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
1677 !startswith(c->signature + c->index + 1, contents) ||
1678 c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
1681 nindex = c->index + 1 + l + 1;
1685 /* Align contents to 8 byte boundary */
1686 if (!message_extend_body(m, 8, 0))
1689 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1695 int sd_bus_message_open_container(
1698 const char *contents) {
1700 struct bus_container *c, *w;
1701 uint32_t *array_size = NULL;
1715 /* Make sure we have space for one more container */
1716 w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
1724 c = message_get_container(m);
1726 signature = strdup(contents);
1732 /* Save old index in the parent container, in case we have to
1733 * abort this container */
1734 c->saved_index = c->index;
1735 before = m->header->body_size;
1737 if (type == SD_BUS_TYPE_ARRAY)
1738 r = bus_message_open_array(m, c, contents, &array_size);
1739 else if (type == SD_BUS_TYPE_VARIANT)
1740 r = bus_message_open_variant(m, c, contents);
1741 else if (type == SD_BUS_TYPE_STRUCT)
1742 r = bus_message_open_struct(m, c, contents);
1743 else if (type == SD_BUS_TYPE_DICT_ENTRY)
1744 r = bus_message_open_dict_entry(m, c, contents);
1753 /* OK, let's fill it in */
1754 w += m->n_containers++;
1755 w->enclosing = type;
1756 w->signature = signature;
1758 w->array_size = array_size;
1760 w->begin = m->rindex;
1765 int sd_bus_message_close_container(sd_bus_message *m) {
1766 struct bus_container *c;
1772 if (m->n_containers <= 0)
1777 c = message_get_container(m);
1778 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1779 if (c->signature && c->signature[c->index] != 0)
1794 static int type_stack_push(TypeStack *stack, unsigned max, unsigned *i, const char *types, unsigned n_struct, unsigned n_array) {
1801 stack[*i].types = types;
1802 stack[*i].n_struct = n_struct;
1803 stack[*i].n_array = n_array;
1809 static int type_stack_pop(TypeStack *stack, unsigned max, unsigned *i, const char **types, unsigned *n_struct, unsigned *n_array) {
1820 *types = stack[*i].types;
1821 *n_struct = stack[*i].n_struct;
1822 *n_array = stack[*i].n_array;
1827 int bus_message_append_ap(
1832 unsigned n_array, n_struct;
1833 TypeStack stack[BUS_CONTAINER_DEPTH];
1834 unsigned stack_ptr = 0;
1842 n_array = (unsigned) -1;
1843 n_struct = strlen(types);
1848 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
1849 r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
1855 r = sd_bus_message_close_container(m);
1863 if (n_array != (unsigned) -1)
1872 case SD_BUS_TYPE_BYTE: {
1875 x = (uint8_t) va_arg(ap, int);
1876 r = sd_bus_message_append_basic(m, *t, &x);
1880 case SD_BUS_TYPE_BOOLEAN:
1881 case SD_BUS_TYPE_INT32:
1882 case SD_BUS_TYPE_UINT32:
1883 case SD_BUS_TYPE_UNIX_FD: {
1886 /* We assume a boolean is the same as int32_t */
1887 assert_cc(sizeof(int32_t) == sizeof(int));
1889 x = va_arg(ap, uint32_t);
1890 r = sd_bus_message_append_basic(m, *t, &x);
1894 case SD_BUS_TYPE_INT16:
1895 case SD_BUS_TYPE_UINT16: {
1898 x = (uint16_t) va_arg(ap, int);
1899 r = sd_bus_message_append_basic(m, *t, &x);
1903 case SD_BUS_TYPE_INT64:
1904 case SD_BUS_TYPE_UINT64:
1905 case SD_BUS_TYPE_DOUBLE: {
1908 x = va_arg(ap, uint64_t);
1909 r = sd_bus_message_append_basic(m, *t, &x);
1913 case SD_BUS_TYPE_STRING:
1914 case SD_BUS_TYPE_OBJECT_PATH:
1915 case SD_BUS_TYPE_SIGNATURE: {
1918 x = va_arg(ap, const char*);
1919 r = sd_bus_message_append_basic(m, *t, x);
1923 case SD_BUS_TYPE_ARRAY: {
1926 r = signature_element_length(t + 1, &k);
1932 memcpy(s, t + 1, k);
1935 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, s);
1940 if (n_array == (unsigned) -1) {
1945 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
1951 n_array = va_arg(ap, unsigned);
1956 case SD_BUS_TYPE_VARIANT: {
1959 s = va_arg(ap, const char*);
1963 r = sd_bus_message_open_container(m, SD_BUS_TYPE_VARIANT, s);
1967 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
1972 n_struct = strlen(s);
1973 n_array = (unsigned) -1;
1978 case SD_BUS_TYPE_STRUCT_BEGIN:
1979 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
1982 r = signature_element_length(t, &k);
1989 memcpy(s, t + 1, k - 2);
1992 r = sd_bus_message_open_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
1997 if (n_array == (unsigned) -1) {
2002 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2008 n_array = (unsigned) -1;
2024 int sd_bus_message_append(sd_bus_message *m, const char *types, ...) {
2037 va_start(ap, types);
2038 r = bus_message_append_ap(m, types, ap);
2044 int sd_bus_message_append_array_space(sd_bus_message *m, char type, size_t size, void **ptr) {
2053 if (!bus_type_is_trivial(type))
2055 if (!ptr && size > 0)
2060 align = bus_type_get_alignment(type);
2061 sz = bus_type_get_size(type);
2063 assert_se(align > 0);
2069 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
2073 a = message_extend_body(m, align, size);
2077 r = sd_bus_message_close_container(m);
2085 int sd_bus_message_append_array(sd_bus_message *m, char type, const void *ptr, size_t size) {
2089 if (!ptr && size > 0)
2092 r = sd_bus_message_append_array_space(m, type, size, &p);
2097 memcpy(p, ptr, size);
2102 static int buffer_peek(const void *p, uint32_t sz, size_t *rindex, size_t align, size_t nbytes, void **r) {
2103 size_t k, start, end;
2108 start = ALIGN_TO((size_t) *rindex, align);
2109 end = start + nbytes;
2114 /* Verify that padding is 0 */
2115 for (k = *rindex; k < start; k++)
2116 if (((const uint8_t*) p)[k] != 0)
2120 *r = (uint8_t*) p + start;
2127 static bool message_end_of_array(sd_bus_message *m, size_t index) {
2128 struct bus_container *c;
2132 c = message_get_container(m);
2136 return index >= c->begin + BUS_MESSAGE_BSWAP32(m, *c->array_size);
2139 static struct bus_body_part* find_part(sd_bus_message *m, size_t index, size_t sz, void **p) {
2140 struct bus_body_part *part;
2144 if (m->cached_rindex_part && index >= m->cached_rindex_part_begin) {
2145 part = m->cached_rindex_part;
2146 begin = m->cached_rindex_part_begin;
2156 if (index + sz <= begin + part->size) {
2158 *p = part->data ? (uint8_t*) part->data + index - begin : NULL;
2160 m->cached_rindex_part = part;
2161 m->cached_rindex_part_begin = begin;
2172 static int message_peek_body(
2179 size_t k, start, end, padding;
2180 struct bus_body_part *part;
2187 if (message_end_of_array(m, *rindex))
2190 start = ALIGN_TO((size_t) *rindex, align);
2191 padding = start - *rindex;
2192 end = start + nbytes;
2194 if (end > BUS_MESSAGE_BODY_SIZE(m))
2197 part = find_part(m, *rindex, padding, (void**) &q);
2202 /* Verify padding */
2203 for (k = 0; k < padding; k++)
2208 part = find_part(m, start, nbytes, (void**) &q);
2220 static bool validate_nul(const char *s, size_t l) {
2222 /* Check for NUL chars in the string */
2223 if (memchr(s, 0, l))
2226 /* Check for NUL termination */
2233 static bool validate_string(const char *s, size_t l) {
2235 if (!validate_nul(s, l))
2238 /* Check if valid UTF8 */
2239 if (!utf8_is_valid(s))
2245 static bool validate_signature(const char *s, size_t l) {
2247 if (!validate_nul(s, l))
2250 /* Check if valid signature */
2251 if (!signature_is_valid(s, true))
2257 static bool validate_object_path(const char *s, size_t l) {
2259 if (!validate_nul(s, l))
2262 if (!object_path_is_valid(s))
2268 int sd_bus_message_read_basic(sd_bus_message *m, char type, void *p) {
2269 struct bus_container *c;
2277 if (!bus_type_is_basic(type))
2282 c = message_get_container(m);
2284 if (!c->signature || c->signature[c->index] == 0)
2287 if (c->signature[c->index] != type)
2292 case SD_BUS_TYPE_STRING:
2293 case SD_BUS_TYPE_OBJECT_PATH: {
2298 r = message_peek_body(m, &rindex, 4, 4, &q);
2302 l = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2303 r = message_peek_body(m, &rindex, 1, l+1, &q);
2309 if (type == SD_BUS_TYPE_OBJECT_PATH) {
2310 if (!validate_object_path(q, l))
2313 if (!validate_string(q, l))
2318 *(const char**) p = q;
2322 case SD_BUS_TYPE_SIGNATURE: {
2327 r = message_peek_body(m, &rindex, 1, 1, &q);
2332 r = message_peek_body(m, &rindex, 1, l+1, &q);
2338 if (!validate_signature(q, l))
2342 *(const char**) p = q;
2350 align = bus_type_get_alignment(type);
2351 sz = bus_type_get_size(type);
2352 assert(align > 0 && sz > 0);
2355 r = message_peek_body(m, &rindex, align, sz, &q);
2361 case SD_BUS_TYPE_BYTE:
2362 *(uint8_t*) p = *(uint8_t*) q;
2365 case SD_BUS_TYPE_BOOLEAN:
2366 *(int*) p = !!*(uint32_t*) q;
2369 case SD_BUS_TYPE_INT16:
2370 case SD_BUS_TYPE_UINT16:
2371 *(uint16_t*) p = BUS_MESSAGE_BSWAP16(m, *(uint16_t*) q);
2374 case SD_BUS_TYPE_INT32:
2375 case SD_BUS_TYPE_UINT32:
2376 *(uint32_t*) p = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2379 case SD_BUS_TYPE_INT64:
2380 case SD_BUS_TYPE_UINT64:
2381 case SD_BUS_TYPE_DOUBLE:
2382 *(uint64_t*) p = BUS_MESSAGE_BSWAP64(m, *(uint64_t*) q);
2385 case SD_BUS_TYPE_UNIX_FD: {
2388 j = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2392 *(int*) p = m->fds[j];
2397 assert_not_reached("Unknown basic type...");
2406 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2412 static int bus_message_enter_array(
2414 struct bus_container *c,
2415 const char *contents,
2416 uint32_t **array_size) {
2427 if (!signature_is_single(contents))
2430 alignment = bus_type_get_alignment(contents[0]);
2434 if (!c->signature || c->signature[c->index] == 0)
2437 if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
2440 if (!startswith(c->signature + c->index + 1, contents))
2444 r = message_peek_body(m, &rindex, 4, 4, &q);
2448 if (BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q) > BUS_ARRAY_MAX_SIZE)
2451 r = message_peek_body(m, &rindex, alignment, 0, NULL);
2457 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2458 c->index += 1 + strlen(contents);
2462 *array_size = (uint32_t*) q;
2467 static int bus_message_enter_variant(
2469 struct bus_container *c,
2470 const char *contents) {
2481 if (!signature_is_single(contents))
2484 if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
2487 if (!c->signature || c->signature[c->index] == 0)
2490 if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
2494 r = message_peek_body(m, &rindex, 1, 1, &q);
2499 r = message_peek_body(m, &rindex, 1, l+1, &q);
2505 if (!validate_signature(q, l))
2508 if (!streq(q, contents))
2511 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2519 static int bus_message_enter_struct(
2521 struct bus_container *c,
2522 const char *contents) {
2531 if (!signature_is_valid(contents, false))
2534 if (!c->signature || c->signature[c->index] == 0)
2537 l = strlen(contents);
2539 if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
2540 !startswith(c->signature + c->index + 1, contents) ||
2541 c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
2544 r = message_peek_body(m, &m->rindex, 8, 0, NULL);
2548 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2549 c->index += 1 + l + 1;
2554 static int bus_message_enter_dict_entry(
2556 struct bus_container *c,
2557 const char *contents) {
2566 if (!signature_is_pair(contents))
2569 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2572 if (!c->signature || c->signature[c->index] == 0)
2575 l = strlen(contents);
2577 if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
2578 !startswith(c->signature + c->index + 1, contents) ||
2579 c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
2582 r = message_peek_body(m, &m->rindex, 8, 0, NULL);
2586 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2587 c->index += 1 + l + 1;
2592 int sd_bus_message_enter_container(sd_bus_message *m, char type, const char *contents) {
2593 struct bus_container *c, *w;
2594 uint32_t *array_size = NULL;
2607 * We enforce a global limit on container depth, that is much
2608 * higher than the 32 structs and 32 arrays the specification
2609 * mandates. This is simpler to implement for us, and we need
2610 * this only to ensure our container array doesn't grow
2611 * without bounds. We are happy to return any data from a
2612 * message as long as the data itself is valid, even if the
2613 * overall message might be not.
2615 * Note that the message signature is validated when
2616 * parsing the headers, and that validation does check the
2619 * Note that the specification defines no limits on the depth
2620 * of stacked variants, but we do.
2622 if (m->n_containers >= BUS_CONTAINER_DEPTH)
2625 w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
2630 c = message_get_container(m);
2632 if (!c->signature || c->signature[c->index] == 0)
2635 signature = strdup(contents);
2639 c->saved_index = c->index;
2642 if (type == SD_BUS_TYPE_ARRAY)
2643 r = bus_message_enter_array(m, c, contents, &array_size);
2644 else if (type == SD_BUS_TYPE_VARIANT)
2645 r = bus_message_enter_variant(m, c, contents);
2646 else if (type == SD_BUS_TYPE_STRUCT)
2647 r = bus_message_enter_struct(m, c, contents);
2648 else if (type == SD_BUS_TYPE_DICT_ENTRY)
2649 r = bus_message_enter_dict_entry(m, c, contents);
2658 /* OK, let's fill it in */
2659 w += m->n_containers++;
2660 w->enclosing = type;
2661 w->signature = signature;
2663 w->array_size = array_size;
2665 w->begin = m->rindex;
2670 int sd_bus_message_exit_container(sd_bus_message *m) {
2671 struct bus_container *c;
2677 if (m->n_containers <= 0)
2680 c = message_get_container(m);
2681 if (c->enclosing == SD_BUS_TYPE_ARRAY) {
2684 l = BUS_MESSAGE_BSWAP32(m, *c->array_size);
2685 if (c->begin + l != m->rindex)
2689 if (c->signature && c->signature[c->index] != 0)
2699 static void message_quit_container(sd_bus_message *m) {
2700 struct bus_container *c;
2704 assert(m->n_containers > 0);
2706 c = message_get_container(m);
2709 assert(m->rindex >= c->before);
2710 m->rindex = c->before;
2712 /* Free container */
2716 /* Correct index of new top-level container */
2717 c = message_get_container(m);
2718 c->index = c->saved_index;
2721 int sd_bus_message_peek_type(sd_bus_message *m, char *type, const char **contents) {
2722 struct bus_container *c;
2730 c = message_get_container(m);
2732 if (!c->signature || c->signature[c->index] == 0)
2735 if (message_end_of_array(m, m->rindex))
2738 if (bus_type_is_basic(c->signature[c->index])) {
2742 *type = c->signature[c->index];
2746 if (c->signature[c->index] == SD_BUS_TYPE_ARRAY) {
2752 r = signature_element_length(c->signature+c->index+1, &l);
2758 sig = strndup(c->signature + c->index + 1, l);
2762 free(m->peeked_signature);
2763 m->peeked_signature = sig;
2769 *type = SD_BUS_TYPE_ARRAY;
2774 if (c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ||
2775 c->signature[c->index] == SD_BUS_TYPE_DICT_ENTRY_BEGIN) {
2781 r = signature_element_length(c->signature+c->index, &l);
2786 sig = strndup(c->signature + c->index + 1, l - 2);
2790 free(m->peeked_signature);
2791 m->peeked_signature = sig;
2797 *type = c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY;
2802 if (c->signature[c->index] == SD_BUS_TYPE_VARIANT) {
2808 r = message_peek_body(m, &rindex, 1, 1, &q);
2815 r = message_peek_body(m, &rindex, 1, l+1, &q);
2821 if (!validate_signature(q, l))
2828 *type = SD_BUS_TYPE_VARIANT;
2837 *type = c->enclosing;
2843 int sd_bus_message_rewind(sd_bus_message *m, int complete) {
2844 struct bus_container *c;
2852 message_reset_containers(m);
2854 m->root_container.index = 0;
2856 c = message_get_container(m);
2858 c = message_get_container(m);
2861 m->rindex = c->begin;
2864 return !isempty(c->signature);
2866 static int message_read_ap(
2871 unsigned n_array, n_struct;
2872 TypeStack stack[BUS_CONTAINER_DEPTH];
2873 unsigned stack_ptr = 0;
2881 /* Ideally, we'd just call ourselves recursively on every
2882 * complex type. However, the state of a va_list that is
2883 * passed to a function is undefined after that function
2884 * returns. This means we need to docode the va_list linearly
2885 * in a single stackframe. We hence implement our own
2886 * home-grown stack in an array. */
2888 n_array = (unsigned) -1;
2889 n_struct = strlen(types);
2894 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
2895 r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
2901 r = sd_bus_message_exit_container(m);
2909 if (n_array != (unsigned) -1)
2918 case SD_BUS_TYPE_BYTE:
2919 case SD_BUS_TYPE_BOOLEAN:
2920 case SD_BUS_TYPE_INT16:
2921 case SD_BUS_TYPE_UINT16:
2922 case SD_BUS_TYPE_INT32:
2923 case SD_BUS_TYPE_UINT32:
2924 case SD_BUS_TYPE_INT64:
2925 case SD_BUS_TYPE_UINT64:
2926 case SD_BUS_TYPE_DOUBLE:
2927 case SD_BUS_TYPE_STRING:
2928 case SD_BUS_TYPE_OBJECT_PATH:
2929 case SD_BUS_TYPE_SIGNATURE:
2930 case SD_BUS_TYPE_UNIX_FD: {
2933 p = va_arg(ap, void*);
2934 r = sd_bus_message_read_basic(m, *t, p);
2943 case SD_BUS_TYPE_ARRAY: {
2946 r = signature_element_length(t + 1, &k);
2952 memcpy(s, t + 1, k);
2955 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, s);
2962 if (n_array == (unsigned) -1) {
2967 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2973 n_array = va_arg(ap, unsigned);
2978 case SD_BUS_TYPE_VARIANT: {
2981 s = va_arg(ap, const char *);
2985 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, s);
2991 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2996 n_struct = strlen(s);
2997 n_array = (unsigned) -1;
3002 case SD_BUS_TYPE_STRUCT_BEGIN:
3003 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
3006 r = signature_element_length(t, &k);
3012 memcpy(s, t + 1, k - 2);
3015 r = sd_bus_message_enter_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
3022 if (n_array == (unsigned) -1) {
3027 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
3033 n_array = (unsigned) -1;
3046 int sd_bus_message_read(sd_bus_message *m, const char *types, ...) {
3057 va_start(ap, types);
3058 r = message_read_ap(m, types, ap);
3064 int sd_bus_message_read_array(sd_bus_message *m, char type, const void **ptr, size_t *size) {
3065 struct bus_container *c;
3075 if (!bus_type_is_trivial(type))
3081 if (BUS_MESSAGE_NEED_BSWAP(m))
3084 align = bus_type_get_alignment(type);
3088 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
3092 c = message_get_container(m);
3093 sz = BUS_MESSAGE_BSWAP32(m, *c->array_size);
3095 r = message_peek_body(m, &m->rindex, align, sz, &p);
3103 r = sd_bus_message_exit_container(m);
3107 *ptr = (const void*) p;
3113 message_quit_container(m);
3117 static int message_peek_fields(
3128 return buffer_peek(BUS_MESSAGE_FIELDS(m), BUS_MESSAGE_FIELDS_SIZE(m), rindex, align, nbytes, ret);
3131 static int message_peek_field_uint32(
3142 r = message_peek_fields(m, ri, 4, 4, &q);
3147 *ret = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
3152 static int message_peek_field_string(
3154 bool (*validate)(const char *p),
3165 r = message_peek_field_uint32(m, ri, &l);
3169 r = message_peek_fields(m, ri, 1, l+1, &q);
3174 if (!validate_nul(q, l))
3180 if (!validate_string(q, l))
3190 static int message_peek_field_signature(
3202 r = message_peek_fields(m, ri, 1, 1, &q);
3207 r = message_peek_fields(m, ri, 1, l+1, &q);
3211 if (!validate_signature(q, l))
3220 static int message_skip_fields(
3223 uint32_t array_size,
3224 const char **signature) {
3226 size_t original_index;
3233 original_index = *ri;
3239 if (array_size != (uint32_t) -1 &&
3240 array_size <= *ri - original_index)
3247 if (t == SD_BUS_TYPE_STRING) {
3249 r = message_peek_field_string(m, NULL, ri, NULL);
3255 } else if (t == SD_BUS_TYPE_OBJECT_PATH) {
3257 r = message_peek_field_string(m, object_path_is_valid, ri, NULL);
3263 } else if (t == SD_BUS_TYPE_SIGNATURE) {
3265 r = message_peek_field_signature(m, ri, NULL);
3271 } else if (bus_type_is_basic(t)) {
3274 align = bus_type_get_alignment(t);
3275 k = bus_type_get_size(t);
3276 assert(align > 0 && k > 0);
3278 r = message_peek_fields(m, ri, align, k, NULL);
3284 } else if (t == SD_BUS_TYPE_ARRAY) {
3286 r = signature_element_length(*signature+1, &l);
3296 strncpy(sig, *signature + 1, l-1);
3299 alignment = bus_type_get_alignment(sig[0]);
3303 r = message_peek_field_uint32(m, ri, &nas);
3306 if (nas > BUS_ARRAY_MAX_SIZE)
3309 r = message_peek_fields(m, ri, alignment, 0, NULL);
3313 r = message_skip_fields(m, ri, nas, (const char**) &s);
3318 (*signature) += 1 + l;
3320 } else if (t == SD_BUS_TYPE_VARIANT) {
3323 r = message_peek_field_signature(m, ri, &s);
3327 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
3333 } else if (t == SD_BUS_TYPE_STRUCT ||
3334 t == SD_BUS_TYPE_DICT_ENTRY) {
3336 r = signature_element_length(*signature, &l);
3343 strncpy(sig, *signature + 1, l-1);
3346 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
3357 int bus_message_parse_fields(sd_bus_message *m) {
3360 uint32_t unix_fds = 0;
3364 for (ri = 0; ri < BUS_MESSAGE_FIELDS_SIZE(m); ) {
3365 const char *signature;
3368 r = message_peek_fields(m, &ri, 8, 1, (void**) &header);
3372 r = message_peek_field_signature(m, &ri, &signature);
3377 case _SD_BUS_MESSAGE_HEADER_INVALID:
3380 case SD_BUS_MESSAGE_HEADER_PATH:
3385 if (!streq(signature, "o"))
3388 r = message_peek_field_string(m, object_path_is_valid, &ri, &m->path);
3391 case SD_BUS_MESSAGE_HEADER_INTERFACE:
3396 if (!streq(signature, "s"))
3399 r = message_peek_field_string(m, interface_name_is_valid, &ri, &m->interface);
3402 case SD_BUS_MESSAGE_HEADER_MEMBER:
3407 if (!streq(signature, "s"))
3410 r = message_peek_field_string(m, member_name_is_valid, &ri, &m->member);
3413 case SD_BUS_MESSAGE_HEADER_ERROR_NAME:
3418 if (!streq(signature, "s"))
3421 r = message_peek_field_string(m, error_name_is_valid, &ri, &m->error.name);
3424 case SD_BUS_MESSAGE_HEADER_DESTINATION:
3429 if (!streq(signature, "s"))
3432 r = message_peek_field_string(m, service_name_is_valid, &ri, &m->destination);
3435 case SD_BUS_MESSAGE_HEADER_SENDER:
3440 if (!streq(signature, "s"))
3443 r = message_peek_field_string(m, service_name_is_valid, &ri, &m->sender);
3447 case SD_BUS_MESSAGE_HEADER_SIGNATURE: {
3451 if (m->root_container.signature)
3454 if (!streq(signature, "g"))
3457 r = message_peek_field_signature(m, &ri, &s);
3465 free(m->root_container.signature);
3466 m->root_container.signature = c;
3470 case SD_BUS_MESSAGE_HEADER_REPLY_SERIAL:
3471 if (m->reply_serial != 0)
3474 if (!streq(signature, "u"))
3477 r = message_peek_field_uint32(m, &ri, &m->reply_serial);
3481 if (m->reply_serial == 0)
3486 case SD_BUS_MESSAGE_HEADER_UNIX_FDS:
3490 if (!streq(signature, "u"))
3493 r = message_peek_field_uint32(m, &ri, &unix_fds);
3503 r = message_skip_fields(m, &ri, (uint32_t) -1, (const char **) &signature);
3510 if (m->n_fds != unix_fds)
3513 if (isempty(m->root_container.signature) != (BUS_MESSAGE_BODY_SIZE(m) == 0))
3516 switch (m->header->type) {
3518 case SD_BUS_MESSAGE_TYPE_SIGNAL:
3519 if (!m->path || !m->interface || !m->member)
3523 case SD_BUS_MESSAGE_TYPE_METHOD_CALL:
3525 if (!m->path || !m->member)
3530 case SD_BUS_MESSAGE_TYPE_METHOD_RETURN:
3532 if (m->reply_serial == 0)
3536 case SD_BUS_MESSAGE_TYPE_METHOD_ERROR:
3538 if (m->reply_serial == 0 || !m->error.name)
3543 /* Try to read the error message, but if we can't it's a non-issue */
3544 if (m->header->type == SD_BUS_MESSAGE_TYPE_METHOD_ERROR)
3545 sd_bus_message_read(m, "s", &m->error.message);
3550 int bus_message_seal(sd_bus_message *m, uint64_t serial) {
3551 struct bus_body_part *part;
3561 if (m->n_containers > 0)
3567 /* If there's a non-trivial signature set, then add it in here */
3568 if (!isempty(m->root_container.signature)) {
3569 r = message_append_field_signature(m, SD_BUS_MESSAGE_HEADER_SIGNATURE, m->root_container.signature, NULL);
3575 r = message_append_field_uint32(m, SD_BUS_MESSAGE_HEADER_UNIX_FDS, m->n_fds);
3580 /* Add padding at the end, since we know the body
3581 * needs to start at an 8 byte alignment. */
3583 l = BUS_MESSAGE_FIELDS_SIZE(m);
3586 memset((uint8_t*) BUS_MESSAGE_FIELDS(m) + l, 0, a);
3588 MESSAGE_FOREACH_PART(part, i, m)
3589 if (part->memfd >= 0 && !part->sealed) {
3590 ioctl(part->memfd, KDBUS_CMD_MEMFD_SEAL_SET, 1);
3591 part->sealed = true;
3594 m->header->serial = serial;
3600 int sd_bus_message_set_destination(sd_bus_message *m, const char *destination) {
3610 return message_append_field_string(m, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &m->destination);
3613 int bus_message_dump(sd_bus_message *m) {
3614 const char *u = NULL, *uu = NULL, *s = NULL;
3615 char **cmdline = NULL;
3618 uid_t owner, audit_loginuid;
3619 uint32_t audit_sessionid;
3623 printf("Message %p\n"
3630 "\tfields_size=%u\n"
3635 "\tdestination=%s\n"
3638 "\treply_serial=%u\n"
3640 "\terror.message=%s\n"
3648 BUS_MESSAGE_SERIAL(m),
3649 BUS_MESSAGE_FIELDS_SIZE(m),
3650 BUS_MESSAGE_BODY_SIZE(m),
3652 strna(m->interface),
3654 strna(m->destination),
3656 strna(m->root_container.signature),
3658 strna(m->error.name),
3659 strna(m->error.message),
3663 printf("\tpid=%lu\n", (unsigned long) m->pid);
3665 printf("\ttid=%lu\n", (unsigned long) m->tid);
3667 printf("\tuid=%lu\n", (unsigned long) m->uid);
3669 printf("\tgid=%lu\n", (unsigned long) m->gid);
3670 if (m->pid_starttime != 0)
3671 printf("\tpid_starttime=%llu\n", (unsigned long long) m->pid_starttime);
3672 if (m->monotonic != 0)
3673 printf("\tmonotonic=%llu\n", (unsigned long long) m->monotonic);
3674 if (m->realtime != 0)
3675 printf("\trealtime=%llu\n", (unsigned long long) m->realtime);
3677 printf("\texe=[%s]\n", m->exe);
3679 printf("\tcomm=[%s]\n", m->comm);
3681 printf("\ttid_comm=[%s]\n", m->tid_comm);
3683 printf("\tlabel=[%s]\n", m->label);
3685 printf("\tcgroup=[%s]\n", m->cgroup);
3687 sd_bus_message_get_unit(m, &u);
3689 printf("\tunit=[%s]\n", u);
3690 sd_bus_message_get_user_unit(m, &uu);
3692 printf("\tuser_unit=[%s]\n", uu);
3693 sd_bus_message_get_session(m, &s);
3695 printf("\tsession=[%s]\n", s);
3696 if (sd_bus_message_get_owner_uid(m, &owner) >= 0)
3697 printf("\towner_uid=%lu\n", (unsigned long) owner);
3698 if (sd_bus_message_get_audit_loginuid(m, &audit_loginuid) >= 0)
3699 printf("\taudit_loginuid=%lu\n", (unsigned long) audit_loginuid);
3700 if (sd_bus_message_get_audit_sessionid(m, &audit_sessionid) >= 0)
3701 printf("\taudit_sessionid=%lu\n", (unsigned long) audit_sessionid);
3703 printf("\tCAP_KILL=%i\n", sd_bus_message_has_effective_cap(m, 5));
3705 if (sd_bus_message_get_cmdline(m, &cmdline) >= 0) {
3708 fputs("\tcmdline=[", stdout);
3709 STRV_FOREACH(c, cmdline) {
3716 fputs("]\n", stdout);
3719 r = sd_bus_message_rewind(m, true);
3721 log_error("Failed to rewind: %s", strerror(-r));
3725 printf("BEGIN_MESSAGE \"%s\" {\n", strempty(m->root_container.signature));
3728 _cleanup_free_ char *prefix = NULL;
3729 const char *contents = NULL;
3744 r = sd_bus_message_peek_type(m, &type, &contents);
3746 log_error("Failed to peek type: %s", strerror(-r));
3753 r = sd_bus_message_exit_container(m);
3755 log_error("Failed to exit container: %s", strerror(-r));
3761 prefix = strrep("\t", level);
3765 if (type == SD_BUS_TYPE_ARRAY)
3766 printf("%s} END_ARRAY \n", prefix);
3767 else if (type == SD_BUS_TYPE_VARIANT)
3768 printf("%s} END_VARIANT\n", prefix);
3769 else if (type == SD_BUS_TYPE_STRUCT)
3770 printf("%s} END_STRUCT\n", prefix);
3771 else if (type == SD_BUS_TYPE_DICT_ENTRY)
3772 printf("%s} END_DICT_ENTRY\n", prefix);
3777 prefix = strrep("\t", level);
3781 if (bus_type_is_container(type) > 0) {
3782 r = sd_bus_message_enter_container(m, type, contents);
3784 log_error("Failed to enter container: %s", strerror(-r));
3788 if (type == SD_BUS_TYPE_ARRAY)
3789 printf("%sBEGIN_ARRAY \"%s\" {\n", prefix, contents);
3790 else if (type == SD_BUS_TYPE_VARIANT)
3791 printf("%sBEGIN_VARIANT \"%s\" {\n", prefix, contents);
3792 else if (type == SD_BUS_TYPE_STRUCT)
3793 printf("%sBEGIN_STRUCT \"%s\" {\n", prefix, contents);
3794 else if (type == SD_BUS_TYPE_DICT_ENTRY)
3795 printf("%sBEGIN_DICT_ENTRY \"%s\" {\n", prefix, contents);
3802 r = sd_bus_message_read_basic(m, type, &basic);
3804 log_error("Failed to get basic: %s", strerror(-r));
3810 case SD_BUS_TYPE_BYTE:
3811 printf("%sBYTE: %u\n", prefix, basic.u8);
3814 case SD_BUS_TYPE_BOOLEAN:
3815 printf("%sBOOLEAN: %s\n", prefix, yes_no(basic.i));
3818 case SD_BUS_TYPE_INT16:
3819 printf("%sINT16: %i\n", prefix, basic.s16);
3822 case SD_BUS_TYPE_UINT16:
3823 printf("%sUINT16: %u\n", prefix, basic.u16);
3826 case SD_BUS_TYPE_INT32:
3827 printf("%sINT32: %i\n", prefix, basic.s32);
3830 case SD_BUS_TYPE_UINT32:
3831 printf("%sUINT32: %u\n", prefix, basic.u32);
3834 case SD_BUS_TYPE_INT64:
3835 printf("%sINT64: %lli\n", prefix, (long long) basic.s64);
3838 case SD_BUS_TYPE_UINT64:
3839 printf("%sUINT64: %llu\n", prefix, (unsigned long long) basic.u64);
3842 case SD_BUS_TYPE_DOUBLE:
3843 printf("%sDOUBLE: %g\n", prefix, basic.d64);
3846 case SD_BUS_TYPE_STRING:
3847 printf("%sSTRING: \"%s\"\n", prefix, basic.string);
3850 case SD_BUS_TYPE_OBJECT_PATH:
3851 printf("%sOBJECT_PATH: \"%s\"\n", prefix, basic.string);
3854 case SD_BUS_TYPE_SIGNATURE:
3855 printf("%sSIGNATURE: \"%s\"\n", prefix, basic.string);
3858 case SD_BUS_TYPE_UNIX_FD:
3859 printf("%sUNIX_FD: %i\n", prefix, basic.i);
3863 assert_not_reached("Unknown basic type.");
3867 printf("} END_MESSAGE\n");
3871 int bus_message_get_blob(sd_bus_message *m, void **buffer, size_t *sz) {
3875 struct bus_body_part *part;
3881 total = BUS_MESSAGE_SIZE(m);
3887 e = mempcpy(p, m->header, BUS_MESSAGE_BODY_BEGIN(m));
3888 MESSAGE_FOREACH_PART(part, i, m)
3889 e = mempcpy(e, part->data, part->size);
3891 assert(total == (size_t) ((uint8_t*) e - (uint8_t*) p));
3899 int bus_message_read_strv_extend(sd_bus_message *m, char ***l) {
3905 r = sd_bus_message_enter_container(m, 'a', "s");
3912 r = sd_bus_message_read_basic(m, 's', &s);
3918 r = strv_extend(l, s);
3923 r = sd_bus_message_exit_container(m);
3930 const char* bus_message_get_arg(sd_bus_message *m, unsigned i) {
3932 const char *t = NULL;
3937 r = sd_bus_message_rewind(m, true);
3941 for (j = 0; j <= i; j++) {
3944 r = sd_bus_message_peek_type(m, &type, NULL);
3948 if (type != SD_BUS_TYPE_STRING &&
3949 type != SD_BUS_TYPE_OBJECT_PATH &&
3950 type != SD_BUS_TYPE_SIGNATURE)
3953 r = sd_bus_message_read_basic(m, type, &t);
3961 bool bus_header_is_complete(struct bus_header *h, size_t size) {
3967 if (size < sizeof(struct bus_header))
3970 full = sizeof(struct bus_header) +
3971 (h->endian == SD_BUS_NATIVE_ENDIAN ? h->fields_size : bswap_32(h->fields_size));
3973 return size >= full;
3976 int bus_header_message_size(struct bus_header *h, size_t *sum) {
3982 if (h->endian == SD_BUS_NATIVE_ENDIAN) {
3983 fs = h->fields_size;
3985 } else if (h->endian == SD_BUS_REVERSE_ENDIAN) {
3986 fs = bswap_32(h->fields_size);
3987 bs = bswap_32(h->body_size);
3991 *sum = sizeof(struct bus_header) + ALIGN8(fs) + bs;