1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2013 Lennart Poettering
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
29 #include "time-util.h"
30 #include "cgroup-util.h"
33 #include "bus-message.h"
34 #include "bus-internal.h"
36 #include "bus-signature.h"
38 static int message_append_basic(sd_bus_message *m, char type, const void *p, const void **stored);
40 static void *adjust_pointer(const void *p, void *old_base, size_t sz, void *new_base) {
45 if (old_base == new_base)
48 if ((uint8_t*) p < (uint8_t*) old_base)
51 if ((uint8_t*) p >= (uint8_t*) old_base + sz)
54 return (uint8_t*) new_base + ((uint8_t*) p - (uint8_t*) old_base);
57 static void message_free_part(sd_bus_message *m, struct bus_body_part *part) {
61 if (part->memfd >= 0) {
62 /* If we can reuse the memfd, try that. For that it
63 * can't be sealed yet. */
66 bus_kernel_push_memfd(m->bus, part->memfd, part->data, part->mapped);
69 assert_se(munmap(part->data, part->mapped) == 0);
71 close_nointr_nofail(part->memfd);
74 } else if (part->munmap_this)
75 munmap(part->data, part->mapped);
76 else if (part->free_this)
83 static void message_reset_parts(sd_bus_message *m) {
84 struct bus_body_part *part;
89 while (m->n_body_parts > 0) {
90 struct bus_body_part *next = part->next;
91 message_free_part(m, part);
98 m->cached_rindex_part = NULL;
99 m->cached_rindex_part_begin = 0;
102 static void message_reset_containers(sd_bus_message *m) {
107 for (i = 0; i < m->n_containers; i++)
108 free(m->containers[i].signature);
111 m->containers = NULL;
114 m->root_container.index = 0;
117 static void message_free(sd_bus_message *m) {
123 message_reset_parts(m);
128 if (m->release_kdbus) {
131 off = (uint8_t *)m->kdbus - (uint8_t *)m->bus->kdbus_buffer;
132 ioctl(m->bus->input_fd, KDBUS_CMD_MSG_RELEASE, &off);
136 sd_bus_unref(m->bus);
139 close_many(m->fds, m->n_fds);
143 if (m->iovec != m->iovec_fixed)
146 free(m->cmdline_array);
148 message_reset_containers(m);
149 free(m->root_container.signature);
151 free(m->peeked_signature);
159 static void *message_extend_fields(sd_bus_message *m, size_t align, size_t sz) {
161 size_t old_size, new_size, start;
168 old_size = sizeof(struct bus_header) + m->header->fields_size;
169 start = ALIGN_TO(old_size, align);
170 new_size = start + sz;
172 if (old_size == new_size)
173 return (uint8_t*) m->header + old_size;
175 if (new_size > (size_t) ((uint32_t) -1))
178 if (m->free_header) {
179 np = realloc(m->header, ALIGN8(new_size));
183 /* Initially, the header is allocated as part of of
184 * the sd_bus_message itself, let's replace it by
187 np = malloc(ALIGN8(new_size));
191 memcpy(np, m->header, sizeof(struct bus_header));
194 /* Zero out padding */
195 if (start > old_size)
196 memset((uint8_t*) np + old_size, 0, start - old_size);
200 m->header->fields_size = new_size - sizeof(struct bus_header);
202 /* Adjust quick access pointers */
203 m->path = adjust_pointer(m->path, op, old_size, m->header);
204 m->interface = adjust_pointer(m->interface, op, old_size, m->header);
205 m->member = adjust_pointer(m->member, op, old_size, m->header);
206 m->destination = adjust_pointer(m->destination, op, old_size, m->header);
207 m->sender = adjust_pointer(m->sender, op, old_size, m->header);
208 m->error.name = adjust_pointer(m->error.name, op, old_size, m->header);
210 m->free_header = true;
212 return (uint8_t*) np + start;
219 static int message_append_field_string(
232 if (l > (size_t) (uint32_t) -1)
235 /* field id byte + signature length + signature 's' + NUL + string length + string + NUL */
236 p = message_extend_fields(m, 8, 4 + 4 + l + 1);
245 ((uint32_t*) p)[1] = l;
246 memcpy(p + 8, s, l + 1);
249 *ret = (char*) p + 8;
254 static int message_append_field_signature(
269 /* field id byte + signature length + signature 'g' + NUL + string length + string + NUL */
270 p = message_extend_fields(m, 8, 4 + 1 + l + 1);
276 p[2] = SD_BUS_TYPE_SIGNATURE;
279 memcpy(p + 5, s, l + 1);
282 *ret = (const char*) p + 5;
287 static int message_append_field_uint32(sd_bus_message *m, uint8_t h, uint32_t x) {
292 /* field id byte + signature length + signature 'u' + NUL + value */
293 p = message_extend_fields(m, 8, 4 + 4);
299 p[2] = SD_BUS_TYPE_UINT32;
302 ((uint32_t*) p)[1] = x;
307 int bus_message_from_header(
312 const struct ucred *ucred,
315 sd_bus_message **ret) {
318 struct bus_header *h;
321 assert(buffer || length <= 0);
322 assert(fds || n_fds <= 0);
325 if (length < sizeof(struct bus_header))
335 if (h->type == _SD_BUS_MESSAGE_TYPE_INVALID)
338 if (h->endian != SD_BUS_LITTLE_ENDIAN &&
339 h->endian != SD_BUS_BIG_ENDIAN)
342 a = ALIGN(sizeof(sd_bus_message)) + ALIGN(extra);
345 label_sz = strlen(label);
363 m->uid_valid = m->gid_valid = true;
367 m->label = (char*) m + ALIGN(sizeof(sd_bus_message)) + ALIGN(extra);
368 memcpy(m->label, label, label_sz + 1);
375 int bus_message_from_malloc(
380 const struct ucred *ucred,
382 sd_bus_message **ret) {
387 r = bus_message_from_header(buffer, length, fds, n_fds, ucred, label, 0, &m);
391 if (length != BUS_MESSAGE_SIZE(m)) {
397 m->body.data = (uint8_t*) buffer + sizeof(struct bus_header) + ALIGN8(BUS_MESSAGE_FIELDS_SIZE(m));
398 m->body.size = length - sizeof(struct bus_header) - ALIGN8(BUS_MESSAGE_FIELDS_SIZE(m));
399 m->body.sealed = true;
403 m->iovec = m->iovec_fixed;
404 m->iovec[0].iov_base = buffer;
405 m->iovec[0].iov_len = length;
407 r = bus_message_parse_fields(m);
411 /* We take possession of the memory and fds now */
412 m->free_header = true;
423 static sd_bus_message *message_new(sd_bus *bus, uint8_t type) {
426 m = malloc0(ALIGN(sizeof(sd_bus_message)) + sizeof(struct bus_header));
431 m->header = (struct bus_header*) ((uint8_t*) m + ALIGN(sizeof(struct sd_bus_message)));
432 m->header->endian = SD_BUS_NATIVE_ENDIAN;
433 m->header->type = type;
434 m->header->version = bus ? bus->message_version : 1;
435 m->allow_fds = !bus || bus->can_fds || (bus->state != BUS_HELLO && bus->state != BUS_RUNNING);
438 m->bus = sd_bus_ref(bus);
443 int sd_bus_message_new_signal(
446 const char *interface,
448 sd_bus_message **m) {
461 if (bus && bus->state == BUS_UNSET)
464 t = message_new(bus, SD_BUS_MESSAGE_TYPE_SIGNAL);
468 t->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
470 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_PATH, SD_BUS_TYPE_OBJECT_PATH, path, &t->path);
473 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_INTERFACE, SD_BUS_TYPE_STRING, interface, &t->interface);
476 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_MEMBER, SD_BUS_TYPE_STRING, member, &t->member);
484 sd_bus_message_unref(t);
488 int sd_bus_message_new_method_call(
490 const char *destination,
492 const char *interface,
494 sd_bus_message **m) {
505 if (bus && bus->state == BUS_UNSET)
508 t = message_new(bus, SD_BUS_MESSAGE_TYPE_METHOD_CALL);
512 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_PATH, SD_BUS_TYPE_OBJECT_PATH, path, &t->path);
515 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_MEMBER, SD_BUS_TYPE_STRING, member, &t->member);
520 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_INTERFACE, SD_BUS_TYPE_STRING, interface, &t->interface);
526 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &t->destination);
539 static int message_new_reply(
541 sd_bus_message *call,
543 sd_bus_message **m) {
552 if (call->header->type != SD_BUS_MESSAGE_TYPE_METHOD_CALL)
556 if (bus && bus->state == BUS_UNSET)
559 t = message_new(bus, type);
563 t->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
564 t->reply_serial = BUS_MESSAGE_SERIAL(call);
566 r = message_append_field_uint32(t, SD_BUS_MESSAGE_HEADER_REPLY_SERIAL, t->reply_serial);
571 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, call->sender, &t->destination);
576 t->dont_send = !!(call->header->flags & SD_BUS_MESSAGE_NO_REPLY_EXPECTED);
586 int sd_bus_message_new_method_return(
588 sd_bus_message *call,
589 sd_bus_message **m) {
591 return message_new_reply(bus, call, SD_BUS_MESSAGE_TYPE_METHOD_RETURN, m);
594 int sd_bus_message_new_method_error(
596 sd_bus_message *call,
597 const sd_bus_error *e,
598 sd_bus_message **m) {
603 if (!sd_bus_error_is_set(e))
608 r = message_new_reply(bus, call, SD_BUS_MESSAGE_TYPE_METHOD_ERROR, &t);
612 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_ERROR_NAME, SD_BUS_TYPE_STRING, e->name, &t->error.name);
617 r = message_append_basic(t, SD_BUS_TYPE_STRING, e->message, (const void**) &t->error.message);
630 int bus_message_new_synthetic_error(
633 const sd_bus_error *e,
634 sd_bus_message **m) {
639 assert(sd_bus_error_is_set(e));
642 t = message_new(bus, SD_BUS_MESSAGE_TYPE_METHOD_ERROR);
646 t->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
647 t->reply_serial = serial;
649 r = message_append_field_uint32(t, SD_BUS_MESSAGE_HEADER_REPLY_SERIAL, t->reply_serial);
653 if (bus && bus->unique_name) {
654 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, bus->unique_name, &t->destination);
667 sd_bus_message* sd_bus_message_ref(sd_bus_message *m) {
671 assert(m->n_ref > 0);
677 sd_bus_message* sd_bus_message_unref(sd_bus_message *m) {
681 assert(m->n_ref > 0);
690 int sd_bus_message_get_type(sd_bus_message *m, uint8_t *type) {
696 *type = m->header->type;
700 int sd_bus_message_get_serial(sd_bus_message *m, uint64_t *serial) {
705 if (m->header->serial == 0)
708 *serial = BUS_MESSAGE_SERIAL(m);
712 int sd_bus_message_get_reply_serial(sd_bus_message *m, uint64_t *serial) {
717 if (m->reply_serial == 0)
720 *serial = m->reply_serial;
724 int sd_bus_message_get_no_reply(sd_bus_message *m) {
728 return m->header->type == SD_BUS_MESSAGE_TYPE_METHOD_CALL ? !!(m->header->flags & SD_BUS_MESSAGE_NO_REPLY_EXPECTED) : 0;
731 const char *sd_bus_message_get_path(sd_bus_message *m) {
738 const char *sd_bus_message_get_interface(sd_bus_message *m) {
745 const char *sd_bus_message_get_member(sd_bus_message *m) {
751 const char *sd_bus_message_get_destination(sd_bus_message *m) {
755 return m->destination;
758 const char *sd_bus_message_get_sender(sd_bus_message *m) {
765 const sd_bus_error *sd_bus_message_get_error(sd_bus_message *m) {
769 if (!sd_bus_error_is_set(&m->error))
775 int sd_bus_message_get_uid(sd_bus_message *m, uid_t *uid) {
787 int sd_bus_message_get_gid(sd_bus_message *m, gid_t *gid) {
799 int sd_bus_message_get_pid(sd_bus_message *m, pid_t *pid) {
811 int sd_bus_message_get_tid(sd_bus_message *m, pid_t *tid) {
823 int sd_bus_message_get_pid_starttime(sd_bus_message *m, uint64_t *usec) {
828 if (m->pid_starttime <= 0)
831 *usec = m->pid_starttime;
835 int sd_bus_message_get_selinux_context(sd_bus_message *m, const char **ret) {
845 int sd_bus_message_get_monotonic_timestamp(sd_bus_message *m, uint64_t *usec) {
850 if (m->monotonic <= 0)
853 *usec = m->monotonic;
857 int sd_bus_message_get_realtime_timestamp(sd_bus_message *m, uint64_t *usec) {
862 if (m->realtime <= 0)
869 int sd_bus_message_get_comm(sd_bus_message *m, const char **ret) {
881 int sd_bus_message_get_tid_comm(sd_bus_message *m, const char **ret) {
893 int sd_bus_message_get_exe(sd_bus_message *m, const char **ret) {
905 int sd_bus_message_get_cgroup(sd_bus_message *m, const char **ret) {
917 int sd_bus_message_get_unit(sd_bus_message *m, const char **ret) {
928 r = cg_path_get_unit(m->cgroup, &m->unit);
937 int sd_bus_message_get_user_unit(sd_bus_message *m, const char **ret) {
948 r = cg_path_get_user_unit(m->cgroup, &m->user_unit);
957 int sd_bus_message_get_session(sd_bus_message *m, const char **ret) {
968 r = cg_path_get_session(m->cgroup, &m->session);
977 int sd_bus_message_get_owner_uid(sd_bus_message *m, uid_t *uid) {
985 return cg_path_get_owner_uid(m->cgroup, uid);
988 int sd_bus_message_get_cmdline(sd_bus_message *m, char ***cmdline) {
999 for (p = m->cmdline, n = 0; p < m->cmdline + m->cmdline_length; p++)
1003 m->cmdline_array = new(char*, n + 1);
1004 if (!m->cmdline_array)
1007 for (p = m->cmdline, i = 0, first = true; p < m->cmdline + m->cmdline_length; p++) {
1009 m->cmdline_array[i++] = (char*) p;
1014 m->cmdline_array[i] = NULL;
1015 *cmdline = m->cmdline_array;
1020 int sd_bus_message_get_audit_sessionid(sd_bus_message *m, uint32_t *sessionid) {
1028 *sessionid = m->audit->sessionid;
1032 int sd_bus_message_get_audit_loginuid(sd_bus_message *m, uid_t *uid) {
1040 *uid = m->audit->loginuid;
1044 int sd_bus_message_has_effective_cap(sd_bus_message *m, int capability) {
1054 sz = m->capability_size / 4;
1055 if ((unsigned) capability >= sz*8)
1058 return !!(m->capability[2 * sz + (capability / 8)] & (1 << (capability % 8)));
1061 int sd_bus_message_is_signal(sd_bus_message *m, const char *interface, const char *member) {
1065 if (m->header->type != SD_BUS_MESSAGE_TYPE_SIGNAL)
1068 if (interface && (!m->interface || !streq(m->interface, interface)))
1071 if (member && (!m->member || !streq(m->member, member)))
1077 int sd_bus_message_is_method_call(sd_bus_message *m, const char *interface, const char *member) {
1081 if (m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_CALL)
1084 if (interface && (!m->interface || !streq(m->interface, interface)))
1087 if (member && (!m->member || !streq(m->member, member)))
1093 int sd_bus_message_is_method_error(sd_bus_message *m, const char *name) {
1097 if (m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_ERROR)
1100 if (name && (!m->error.name || !streq(m->error.name, name)))
1106 int sd_bus_message_set_no_reply(sd_bus_message *m, int b) {
1111 if (m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_CALL)
1115 m->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
1117 m->header->flags &= ~SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
1122 static struct bus_container *message_get_container(sd_bus_message *m) {
1125 if (m->n_containers == 0)
1126 return &m->root_container;
1128 assert(m->containers);
1129 return m->containers + m->n_containers - 1;
1132 struct bus_body_part *message_append_part(sd_bus_message *m) {
1133 struct bus_body_part *part;
1140 if (m->n_body_parts <= 0) {
1144 assert(m->body_end);
1146 part = new0(struct bus_body_part, 1);
1152 m->body_end->next = part;
1162 static void part_zero(struct bus_body_part *part, size_t sz) {
1167 /* All other fields can be left in their defaults */
1168 assert(!part->data);
1169 assert(part->memfd < 0);
1172 part->is_zero = true;
1173 part->sealed = true;
1176 static int part_make_space(
1177 struct sd_bus_message *m,
1178 struct bus_body_part *part,
1187 assert(!part->sealed);
1192 if (!part->data && part->memfd < 0)
1193 part->memfd = bus_kernel_pop_memfd(m->bus, &part->data, &part->mapped);
1195 if (part->memfd >= 0) {
1198 r = ioctl(part->memfd, KDBUS_CMD_MEMFD_SIZE_SET, &u);
1204 if (!part->data || sz > part->mapped) {
1205 size_t psz = PAGE_ALIGN(sz > 0 ? sz : 1);
1207 if (part->mapped <= 0)
1208 n = mmap(NULL, psz, PROT_READ|PROT_WRITE, MAP_SHARED, part->memfd, 0);
1210 n = mremap(part->data, part->mapped, psz, MREMAP_MAYMOVE);
1212 if (n == MAP_FAILED) {
1221 part->munmap_this = true;
1223 n = realloc(part->data, sz);
1230 part->free_this = true;
1234 *q = part->data ? (uint8_t*) part->data + part->size : NULL;
1240 static void message_extend_containers(sd_bus_message *m, size_t expand) {
1241 struct bus_container *c;
1248 /* Update counters */
1249 for (c = m->containers; c < m->containers + m->n_containers; c++)
1251 *c->array_size += expand;
1254 static void *message_extend_body(sd_bus_message *m, size_t align, size_t sz) {
1255 struct bus_body_part *part = NULL;
1256 size_t start_body, end_body, padding, start_part, end_part, added;
1268 start_body = ALIGN_TO((size_t) m->header->body_size, align);
1269 end_body = start_body + sz;
1271 padding = start_body - m->header->body_size;
1272 added = padding + sz;
1274 /* Check for 32bit overflows */
1275 if (end_body > (size_t) ((uint32_t) -1)) {
1281 m->n_body_parts <= 0 ||
1282 m->body_end->sealed ||
1283 padding != ALIGN_TO(m->body_end->size, align) - m->body_end->size;
1287 part = message_append_part(m);
1291 part_zero(part, padding);
1294 part = message_append_part(m);
1298 r = part_make_space(m, part, sz, &p);
1302 struct bus_container *c;
1310 start_part = ALIGN_TO(part->size, align);
1311 end_part = start_part + sz;
1313 r = part_make_space(m, part, end_part, &p);
1318 memset(p, 0, padding);
1319 p = (uint8_t*) p + padding;
1322 /* Readjust pointers */
1323 for (c = m->containers; c < m->containers + m->n_containers; c++)
1324 c->array_size = adjust_pointer(c->array_size, op, os, part->data);
1326 m->error.message = (const char*) adjust_pointer(m->error.message, op, os, part->data);
1329 m->header->body_size = end_body;
1330 message_extend_containers(m, added);
1335 int message_append_basic(sd_bus_message *m, char type, const void *p, const void **stored) {
1336 struct bus_container *c;
1350 if (!bus_type_is_basic(type))
1355 c = message_get_container(m);
1357 if (c->signature && c->signature[c->index]) {
1358 /* Container signature is already set */
1360 if (c->signature[c->index] != type)
1365 /* Maybe we can append to the signature? But only if this is the top-level container*/
1366 if (c->enclosing != 0)
1369 e = strextend(&c->signature, CHAR_TO_STR(type), NULL);
1378 case SD_BUS_TYPE_STRING:
1379 case SD_BUS_TYPE_OBJECT_PATH:
1382 sz = 4 + strlen(p) + 1;
1385 case SD_BUS_TYPE_SIGNATURE:
1388 sz = 1 + strlen(p) + 1;
1391 case SD_BUS_TYPE_BOOLEAN:
1394 assert_cc(sizeof(int) == sizeof(uint32_t));
1400 case SD_BUS_TYPE_UNIX_FD: {
1403 if (!m->allow_fds) {
1416 fd = fcntl(z, F_DUPFD_CLOEXEC, 3);
1422 f = realloc(m->fds, sizeof(int) * (m->n_fds + 1));
1437 align = bus_type_get_alignment(type);
1438 sz = bus_type_get_size(type);
1445 a = message_extend_body(m, align, sz);
1451 if (type == SD_BUS_TYPE_STRING || type == SD_BUS_TYPE_OBJECT_PATH) {
1452 *(uint32_t*) a = sz - 5;
1453 memcpy((uint8_t*) a + 4, p, sz - 4);
1456 *stored = (const uint8_t*) a + 4;
1458 } else if (type == SD_BUS_TYPE_SIGNATURE) {
1459 *(uint8_t*) a = sz - 1;
1460 memcpy((uint8_t*) a + 1, p, sz - 1);
1463 *stored = (const uint8_t*) a + 1;
1464 } else if (type == SD_BUS_TYPE_UNIX_FD) {
1465 *(uint32_t*) a = fdi;
1479 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1486 close_nointr_nofail(fd);
1491 int sd_bus_message_append_basic(sd_bus_message *m, char type, const void *p) {
1492 return message_append_basic(m, type, p, NULL);
1495 int sd_bus_message_append_string_space(sd_bus_message *m, size_t size, char **s) {
1496 struct bus_container *c;
1508 c = message_get_container(m);
1510 if (c->signature && c->signature[c->index]) {
1511 /* Container signature is already set */
1513 if (c->signature[c->index] != SD_BUS_TYPE_STRING)
1518 /* Maybe we can append to the signature? But only if this is the top-level container*/
1519 if (c->enclosing != 0)
1522 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRING), NULL);
1529 a = message_extend_body(m, 4, 4 + size + 1);
1533 *(uint32_t*) a = size;
1538 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1544 static int bus_message_open_array(
1546 struct bus_container *c,
1547 const char *contents,
1548 uint32_t **array_size) {
1554 struct bus_body_part *o;
1561 if (!signature_is_single(contents))
1564 alignment = bus_type_get_alignment(contents[0]);
1568 if (c->signature && c->signature[c->index]) {
1570 /* Verify the existing signature */
1572 if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
1575 if (!startswith(c->signature + c->index + 1, contents))
1578 nindex = c->index + 1 + strlen(contents);
1582 if (c->enclosing != 0)
1585 /* Extend the existing signature */
1587 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_ARRAY), contents, NULL);
1593 nindex = e - c->signature;
1596 a = message_extend_body(m, 4, 4);
1601 op = m->body_end->data;
1602 os = m->body_end->size;
1604 /* Add alignment between size and first element */
1605 if (!message_extend_body(m, alignment, 0))
1608 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1611 /* location of array size might have changed so let's readjust a */
1612 if (o == m->body_end)
1613 a = adjust_pointer(a, op, os, m->body_end->data);
1620 static int bus_message_open_variant(
1622 struct bus_container *c,
1623 const char *contents) {
1632 if (!signature_is_single(contents))
1635 if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
1638 if (c->signature && c->signature[c->index]) {
1640 if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
1646 if (c->enclosing != 0)
1649 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_VARIANT), NULL);
1656 l = strlen(contents);
1657 a = message_extend_body(m, 1, 1 + l + 1);
1662 memcpy((uint8_t*) a + 1, contents, l + 1);
1664 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1670 static int bus_message_open_struct(
1672 struct bus_container *c,
1673 const char *contents) {
1681 if (!signature_is_valid(contents, false))
1684 if (c->signature && c->signature[c->index]) {
1687 l = strlen(contents);
1689 if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
1690 !startswith(c->signature + c->index + 1, contents) ||
1691 c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
1694 nindex = c->index + 1 + l + 1;
1698 if (c->enclosing != 0)
1701 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_BEGIN), contents, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_END), NULL);
1707 nindex = e - c->signature;
1710 /* Align contents to 8 byte boundary */
1711 if (!message_extend_body(m, 8, 0))
1714 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1720 static int bus_message_open_dict_entry(
1722 struct bus_container *c,
1723 const char *contents) {
1731 if (!signature_is_pair(contents))
1734 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1737 if (c->signature && c->signature[c->index]) {
1740 l = strlen(contents);
1742 if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
1743 !startswith(c->signature + c->index + 1, contents) ||
1744 c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
1747 nindex = c->index + 1 + l + 1;
1751 /* Align contents to 8 byte boundary */
1752 if (!message_extend_body(m, 8, 0))
1755 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1761 int sd_bus_message_open_container(
1764 const char *contents) {
1766 struct bus_container *c, *w;
1767 uint32_t *array_size = NULL;
1781 /* Make sure we have space for one more container */
1782 w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
1790 c = message_get_container(m);
1792 signature = strdup(contents);
1798 /* Save old index in the parent container, in case we have to
1799 * abort this container */
1800 c->saved_index = c->index;
1801 before = m->header->body_size;
1803 if (type == SD_BUS_TYPE_ARRAY)
1804 r = bus_message_open_array(m, c, contents, &array_size);
1805 else if (type == SD_BUS_TYPE_VARIANT)
1806 r = bus_message_open_variant(m, c, contents);
1807 else if (type == SD_BUS_TYPE_STRUCT)
1808 r = bus_message_open_struct(m, c, contents);
1809 else if (type == SD_BUS_TYPE_DICT_ENTRY)
1810 r = bus_message_open_dict_entry(m, c, contents);
1819 /* OK, let's fill it in */
1820 w += m->n_containers++;
1821 w->enclosing = type;
1822 w->signature = signature;
1824 w->array_size = array_size;
1826 w->begin = m->rindex;
1831 int sd_bus_message_close_container(sd_bus_message *m) {
1832 struct bus_container *c;
1838 if (m->n_containers <= 0)
1843 c = message_get_container(m);
1844 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1845 if (c->signature && c->signature[c->index] != 0)
1860 static int type_stack_push(TypeStack *stack, unsigned max, unsigned *i, const char *types, unsigned n_struct, unsigned n_array) {
1867 stack[*i].types = types;
1868 stack[*i].n_struct = n_struct;
1869 stack[*i].n_array = n_array;
1875 static int type_stack_pop(TypeStack *stack, unsigned max, unsigned *i, const char **types, unsigned *n_struct, unsigned *n_array) {
1886 *types = stack[*i].types;
1887 *n_struct = stack[*i].n_struct;
1888 *n_array = stack[*i].n_array;
1893 int bus_message_append_ap(
1898 unsigned n_array, n_struct;
1899 TypeStack stack[BUS_CONTAINER_DEPTH];
1900 unsigned stack_ptr = 0;
1908 n_array = (unsigned) -1;
1909 n_struct = strlen(types);
1914 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
1915 r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
1921 r = sd_bus_message_close_container(m);
1929 if (n_array != (unsigned) -1)
1938 case SD_BUS_TYPE_BYTE: {
1941 x = (uint8_t) va_arg(ap, int);
1942 r = sd_bus_message_append_basic(m, *t, &x);
1946 case SD_BUS_TYPE_BOOLEAN:
1947 case SD_BUS_TYPE_INT32:
1948 case SD_BUS_TYPE_UINT32:
1949 case SD_BUS_TYPE_UNIX_FD: {
1952 /* We assume a boolean is the same as int32_t */
1953 assert_cc(sizeof(int32_t) == sizeof(int));
1955 x = va_arg(ap, uint32_t);
1956 r = sd_bus_message_append_basic(m, *t, &x);
1960 case SD_BUS_TYPE_INT16:
1961 case SD_BUS_TYPE_UINT16: {
1964 x = (uint16_t) va_arg(ap, int);
1965 r = sd_bus_message_append_basic(m, *t, &x);
1969 case SD_BUS_TYPE_INT64:
1970 case SD_BUS_TYPE_UINT64:
1971 case SD_BUS_TYPE_DOUBLE: {
1974 x = va_arg(ap, uint64_t);
1975 r = sd_bus_message_append_basic(m, *t, &x);
1979 case SD_BUS_TYPE_STRING:
1980 case SD_BUS_TYPE_OBJECT_PATH:
1981 case SD_BUS_TYPE_SIGNATURE: {
1984 x = va_arg(ap, const char*);
1985 r = sd_bus_message_append_basic(m, *t, x);
1989 case SD_BUS_TYPE_ARRAY: {
1992 r = signature_element_length(t + 1, &k);
1998 memcpy(s, t + 1, k);
2001 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, s);
2006 if (n_array == (unsigned) -1) {
2011 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2017 n_array = va_arg(ap, unsigned);
2022 case SD_BUS_TYPE_VARIANT: {
2025 s = va_arg(ap, const char*);
2029 r = sd_bus_message_open_container(m, SD_BUS_TYPE_VARIANT, s);
2033 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2038 n_struct = strlen(s);
2039 n_array = (unsigned) -1;
2044 case SD_BUS_TYPE_STRUCT_BEGIN:
2045 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
2048 r = signature_element_length(t, &k);
2055 memcpy(s, t + 1, k - 2);
2058 r = sd_bus_message_open_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
2063 if (n_array == (unsigned) -1) {
2068 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2074 n_array = (unsigned) -1;
2090 int sd_bus_message_append(sd_bus_message *m, const char *types, ...) {
2103 va_start(ap, types);
2104 r = bus_message_append_ap(m, types, ap);
2110 int sd_bus_message_append_array_space(sd_bus_message *m, char type, size_t size, void **ptr) {
2119 if (!bus_type_is_trivial(type))
2121 if (!ptr && size > 0)
2126 align = bus_type_get_alignment(type);
2127 sz = bus_type_get_size(type);
2129 assert_se(align > 0);
2135 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
2139 a = message_extend_body(m, align, size);
2143 r = sd_bus_message_close_container(m);
2151 int sd_bus_message_append_array(sd_bus_message *m, char type, const void *ptr, size_t size) {
2155 if (!ptr && size > 0)
2158 r = sd_bus_message_append_array_space(m, type, size, &p);
2163 memcpy(p, ptr, size);
2168 int sd_bus_message_append_array_memfd(sd_bus_message *m, char type, sd_memfd *memfd) {
2169 _cleanup_close_ int copy_fd = -1;
2170 struct bus_body_part *part;
2182 if (!bus_type_is_trivial(type))
2187 r = sd_memfd_set_sealed(memfd, true);
2191 copy_fd = sd_memfd_dup_fd(memfd);
2195 r = sd_memfd_get_size(memfd, &size);
2199 align = bus_type_get_alignment(type);
2200 sz = bus_type_get_size(type);
2202 assert_se(align > 0);
2208 if (size > (uint64_t) (uint32_t) -1)
2211 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
2215 a = message_extend_body(m, align, 0);
2219 part = message_append_part(m);
2223 part->memfd = copy_fd;
2224 part->sealed = true;
2228 message_extend_containers(m, size);
2229 m->header->body_size += size;
2231 return sd_bus_message_close_container(m);
2234 int sd_bus_message_append_string_memfd(sd_bus_message *m, sd_memfd *memfd) {
2235 _cleanup_close_ int copy_fd = -1;
2236 struct bus_body_part *part;
2237 struct bus_container *c;
2251 r = sd_memfd_set_sealed(memfd, true);
2255 copy_fd = sd_memfd_dup_fd(memfd);
2259 r = sd_memfd_get_size(memfd, &size);
2263 /* We require this to be NUL terminated */
2267 if (size > (uint64_t) (uint32_t) -1)
2270 c = message_get_container(m);
2271 if (c->signature && c->signature[c->index]) {
2272 /* Container signature is already set */
2274 if (c->signature[c->index] != SD_BUS_TYPE_STRING)
2279 /* Maybe we can append to the signature? But only if this is the top-level container*/
2280 if (c->enclosing != 0)
2283 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRING), NULL);
2290 a = message_extend_body(m, 4, 4);
2294 *(uint32_t*) a = size - 1;
2296 part = message_append_part(m);
2300 part->memfd = copy_fd;
2301 part->sealed = true;
2305 message_extend_containers(m, size);
2306 m->header->body_size += size;
2308 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2314 int bus_body_part_map(struct bus_body_part *part) {
2323 if (part->size <= 0)
2326 /* For smaller zero parts (as used for padding) we don't need to map anything... */
2327 if (part->memfd < 0 && part->is_zero && part->size < 8) {
2328 static const uint8_t zeroes[7] = { };
2329 part->data = (void*) zeroes;
2333 psz = PAGE_ALIGN(part->size);
2335 if (part->memfd >= 0)
2336 p = mmap(NULL, psz, PROT_READ, MAP_SHARED, part->memfd, 0);
2337 else if (part->is_zero)
2338 p = mmap(NULL, psz, PROT_READ, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
2342 if (p == MAP_FAILED)
2347 part->munmap_this = true;
2352 void bus_body_part_unmap(struct bus_body_part *part) {
2356 if (part->memfd < 0)
2362 if (!part->munmap_this)
2365 assert_se(munmap(part->data, part->mapped) == 0);
2369 part->munmap_this = false;
2374 static int buffer_peek(const void *p, uint32_t sz, size_t *rindex, size_t align, size_t nbytes, void **r) {
2375 size_t k, start, end;
2380 start = ALIGN_TO((size_t) *rindex, align);
2381 end = start + nbytes;
2386 /* Verify that padding is 0 */
2387 for (k = *rindex; k < start; k++)
2388 if (((const uint8_t*) p)[k] != 0)
2392 *r = (uint8_t*) p + start;
2399 static bool message_end_of_array(sd_bus_message *m, size_t index) {
2400 struct bus_container *c;
2404 c = message_get_container(m);
2408 return index >= c->begin + BUS_MESSAGE_BSWAP32(m, *c->array_size);
2411 static struct bus_body_part* find_part(sd_bus_message *m, size_t index, size_t sz, void **p) {
2412 struct bus_body_part *part;
2418 if (m->cached_rindex_part && index >= m->cached_rindex_part_begin) {
2419 part = m->cached_rindex_part;
2420 begin = m->cached_rindex_part_begin;
2430 if (index + sz <= begin + part->size) {
2432 r = bus_body_part_map(part);
2437 *p = (uint8_t*) part->data + index - begin;
2439 m->cached_rindex_part = part;
2440 m->cached_rindex_part_begin = begin;
2445 begin += part->size;
2452 static int message_peek_body(
2459 size_t k, start, end, padding;
2460 struct bus_body_part *part;
2467 if (message_end_of_array(m, *rindex))
2470 start = ALIGN_TO((size_t) *rindex, align);
2471 padding = start - *rindex;
2472 end = start + nbytes;
2474 if (end > BUS_MESSAGE_BODY_SIZE(m))
2477 part = find_part(m, *rindex, padding, (void**) &q);
2482 /* Verify padding */
2483 for (k = 0; k < padding; k++)
2488 part = find_part(m, start, nbytes, (void**) &q);
2500 static bool validate_nul(const char *s, size_t l) {
2502 /* Check for NUL chars in the string */
2503 if (memchr(s, 0, l))
2506 /* Check for NUL termination */
2513 static bool validate_string(const char *s, size_t l) {
2515 if (!validate_nul(s, l))
2518 /* Check if valid UTF8 */
2519 if (!utf8_is_valid(s))
2525 static bool validate_signature(const char *s, size_t l) {
2527 if (!validate_nul(s, l))
2530 /* Check if valid signature */
2531 if (!signature_is_valid(s, true))
2537 static bool validate_object_path(const char *s, size_t l) {
2539 if (!validate_nul(s, l))
2542 if (!object_path_is_valid(s))
2548 int sd_bus_message_read_basic(sd_bus_message *m, char type, void *p) {
2549 struct bus_container *c;
2557 if (!bus_type_is_basic(type))
2562 c = message_get_container(m);
2564 if (!c->signature || c->signature[c->index] == 0)
2567 if (c->signature[c->index] != type)
2572 case SD_BUS_TYPE_STRING:
2573 case SD_BUS_TYPE_OBJECT_PATH: {
2578 r = message_peek_body(m, &rindex, 4, 4, &q);
2582 l = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2583 r = message_peek_body(m, &rindex, 1, l+1, &q);
2589 if (type == SD_BUS_TYPE_OBJECT_PATH) {
2590 if (!validate_object_path(q, l))
2593 if (!validate_string(q, l))
2598 *(const char**) p = q;
2602 case SD_BUS_TYPE_SIGNATURE: {
2607 r = message_peek_body(m, &rindex, 1, 1, &q);
2612 r = message_peek_body(m, &rindex, 1, l+1, &q);
2618 if (!validate_signature(q, l))
2622 *(const char**) p = q;
2630 align = bus_type_get_alignment(type);
2631 sz = bus_type_get_size(type);
2632 assert(align > 0 && sz > 0);
2635 r = message_peek_body(m, &rindex, align, sz, &q);
2641 case SD_BUS_TYPE_BYTE:
2642 *(uint8_t*) p = *(uint8_t*) q;
2645 case SD_BUS_TYPE_BOOLEAN:
2646 *(int*) p = !!*(uint32_t*) q;
2649 case SD_BUS_TYPE_INT16:
2650 case SD_BUS_TYPE_UINT16:
2651 *(uint16_t*) p = BUS_MESSAGE_BSWAP16(m, *(uint16_t*) q);
2654 case SD_BUS_TYPE_INT32:
2655 case SD_BUS_TYPE_UINT32:
2656 *(uint32_t*) p = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2659 case SD_BUS_TYPE_INT64:
2660 case SD_BUS_TYPE_UINT64:
2661 case SD_BUS_TYPE_DOUBLE:
2662 *(uint64_t*) p = BUS_MESSAGE_BSWAP64(m, *(uint64_t*) q);
2665 case SD_BUS_TYPE_UNIX_FD: {
2668 j = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2672 *(int*) p = m->fds[j];
2677 assert_not_reached("Unknown basic type...");
2686 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2692 static int bus_message_enter_array(
2694 struct bus_container *c,
2695 const char *contents,
2696 uint32_t **array_size) {
2707 if (!signature_is_single(contents))
2710 alignment = bus_type_get_alignment(contents[0]);
2714 if (!c->signature || c->signature[c->index] == 0)
2717 if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
2720 if (!startswith(c->signature + c->index + 1, contents))
2724 r = message_peek_body(m, &rindex, 4, 4, &q);
2728 if (BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q) > BUS_ARRAY_MAX_SIZE)
2731 r = message_peek_body(m, &rindex, alignment, 0, NULL);
2737 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2738 c->index += 1 + strlen(contents);
2742 *array_size = (uint32_t*) q;
2747 static int bus_message_enter_variant(
2749 struct bus_container *c,
2750 const char *contents) {
2761 if (!signature_is_single(contents))
2764 if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
2767 if (!c->signature || c->signature[c->index] == 0)
2770 if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
2774 r = message_peek_body(m, &rindex, 1, 1, &q);
2779 r = message_peek_body(m, &rindex, 1, l+1, &q);
2785 if (!validate_signature(q, l))
2788 if (!streq(q, contents))
2791 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2799 static int bus_message_enter_struct(
2801 struct bus_container *c,
2802 const char *contents) {
2811 if (!signature_is_valid(contents, false))
2814 if (!c->signature || c->signature[c->index] == 0)
2817 l = strlen(contents);
2819 if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
2820 !startswith(c->signature + c->index + 1, contents) ||
2821 c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
2824 r = message_peek_body(m, &m->rindex, 8, 0, NULL);
2828 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2829 c->index += 1 + l + 1;
2834 static int bus_message_enter_dict_entry(
2836 struct bus_container *c,
2837 const char *contents) {
2846 if (!signature_is_pair(contents))
2849 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2852 if (!c->signature || c->signature[c->index] == 0)
2855 l = strlen(contents);
2857 if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
2858 !startswith(c->signature + c->index + 1, contents) ||
2859 c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
2862 r = message_peek_body(m, &m->rindex, 8, 0, NULL);
2866 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2867 c->index += 1 + l + 1;
2872 int sd_bus_message_enter_container(sd_bus_message *m, char type, const char *contents) {
2873 struct bus_container *c, *w;
2874 uint32_t *array_size = NULL;
2887 * We enforce a global limit on container depth, that is much
2888 * higher than the 32 structs and 32 arrays the specification
2889 * mandates. This is simpler to implement for us, and we need
2890 * this only to ensure our container array doesn't grow
2891 * without bounds. We are happy to return any data from a
2892 * message as long as the data itself is valid, even if the
2893 * overall message might be not.
2895 * Note that the message signature is validated when
2896 * parsing the headers, and that validation does check the
2899 * Note that the specification defines no limits on the depth
2900 * of stacked variants, but we do.
2902 if (m->n_containers >= BUS_CONTAINER_DEPTH)
2905 w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
2910 c = message_get_container(m);
2912 if (!c->signature || c->signature[c->index] == 0)
2915 signature = strdup(contents);
2919 c->saved_index = c->index;
2922 if (type == SD_BUS_TYPE_ARRAY)
2923 r = bus_message_enter_array(m, c, contents, &array_size);
2924 else if (type == SD_BUS_TYPE_VARIANT)
2925 r = bus_message_enter_variant(m, c, contents);
2926 else if (type == SD_BUS_TYPE_STRUCT)
2927 r = bus_message_enter_struct(m, c, contents);
2928 else if (type == SD_BUS_TYPE_DICT_ENTRY)
2929 r = bus_message_enter_dict_entry(m, c, contents);
2938 /* OK, let's fill it in */
2939 w += m->n_containers++;
2940 w->enclosing = type;
2941 w->signature = signature;
2943 w->array_size = array_size;
2945 w->begin = m->rindex;
2950 int sd_bus_message_exit_container(sd_bus_message *m) {
2951 struct bus_container *c;
2957 if (m->n_containers <= 0)
2960 c = message_get_container(m);
2961 if (c->enclosing == SD_BUS_TYPE_ARRAY) {
2964 l = BUS_MESSAGE_BSWAP32(m, *c->array_size);
2965 if (c->begin + l != m->rindex)
2969 if (c->signature && c->signature[c->index] != 0)
2979 static void message_quit_container(sd_bus_message *m) {
2980 struct bus_container *c;
2984 assert(m->n_containers > 0);
2986 c = message_get_container(m);
2989 assert(m->rindex >= c->before);
2990 m->rindex = c->before;
2992 /* Free container */
2996 /* Correct index of new top-level container */
2997 c = message_get_container(m);
2998 c->index = c->saved_index;
3001 int sd_bus_message_peek_type(sd_bus_message *m, char *type, const char **contents) {
3002 struct bus_container *c;
3010 c = message_get_container(m);
3012 if (!c->signature || c->signature[c->index] == 0)
3015 if (message_end_of_array(m, m->rindex))
3018 if (bus_type_is_basic(c->signature[c->index])) {
3022 *type = c->signature[c->index];
3026 if (c->signature[c->index] == SD_BUS_TYPE_ARRAY) {
3032 r = signature_element_length(c->signature+c->index+1, &l);
3038 sig = strndup(c->signature + c->index + 1, l);
3042 free(m->peeked_signature);
3043 m->peeked_signature = sig;
3049 *type = SD_BUS_TYPE_ARRAY;
3054 if (c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ||
3055 c->signature[c->index] == SD_BUS_TYPE_DICT_ENTRY_BEGIN) {
3061 r = signature_element_length(c->signature+c->index, &l);
3066 sig = strndup(c->signature + c->index + 1, l - 2);
3070 free(m->peeked_signature);
3071 m->peeked_signature = sig;
3077 *type = c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY;
3082 if (c->signature[c->index] == SD_BUS_TYPE_VARIANT) {
3088 r = message_peek_body(m, &rindex, 1, 1, &q);
3095 r = message_peek_body(m, &rindex, 1, l+1, &q);
3101 if (!validate_signature(q, l))
3108 *type = SD_BUS_TYPE_VARIANT;
3117 *type = c->enclosing;
3123 int sd_bus_message_rewind(sd_bus_message *m, int complete) {
3124 struct bus_container *c;
3132 message_reset_containers(m);
3134 m->root_container.index = 0;
3136 c = message_get_container(m);
3138 c = message_get_container(m);
3141 m->rindex = c->begin;
3144 return !isempty(c->signature);
3146 static int message_read_ap(
3151 unsigned n_array, n_struct;
3152 TypeStack stack[BUS_CONTAINER_DEPTH];
3153 unsigned stack_ptr = 0;
3161 /* Ideally, we'd just call ourselves recursively on every
3162 * complex type. However, the state of a va_list that is
3163 * passed to a function is undefined after that function
3164 * returns. This means we need to docode the va_list linearly
3165 * in a single stackframe. We hence implement our own
3166 * home-grown stack in an array. */
3168 n_array = (unsigned) -1;
3169 n_struct = strlen(types);
3174 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
3175 r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
3181 r = sd_bus_message_exit_container(m);
3189 if (n_array != (unsigned) -1)
3198 case SD_BUS_TYPE_BYTE:
3199 case SD_BUS_TYPE_BOOLEAN:
3200 case SD_BUS_TYPE_INT16:
3201 case SD_BUS_TYPE_UINT16:
3202 case SD_BUS_TYPE_INT32:
3203 case SD_BUS_TYPE_UINT32:
3204 case SD_BUS_TYPE_INT64:
3205 case SD_BUS_TYPE_UINT64:
3206 case SD_BUS_TYPE_DOUBLE:
3207 case SD_BUS_TYPE_STRING:
3208 case SD_BUS_TYPE_OBJECT_PATH:
3209 case SD_BUS_TYPE_SIGNATURE:
3210 case SD_BUS_TYPE_UNIX_FD: {
3213 p = va_arg(ap, void*);
3214 r = sd_bus_message_read_basic(m, *t, p);
3223 case SD_BUS_TYPE_ARRAY: {
3226 r = signature_element_length(t + 1, &k);
3232 memcpy(s, t + 1, k);
3235 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, s);
3242 if (n_array == (unsigned) -1) {
3247 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
3253 n_array = va_arg(ap, unsigned);
3258 case SD_BUS_TYPE_VARIANT: {
3261 s = va_arg(ap, const char *);
3265 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, s);
3271 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
3276 n_struct = strlen(s);
3277 n_array = (unsigned) -1;
3282 case SD_BUS_TYPE_STRUCT_BEGIN:
3283 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
3286 r = signature_element_length(t, &k);
3292 memcpy(s, t + 1, k - 2);
3295 r = sd_bus_message_enter_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
3302 if (n_array == (unsigned) -1) {
3307 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
3313 n_array = (unsigned) -1;
3326 int sd_bus_message_read(sd_bus_message *m, const char *types, ...) {
3337 va_start(ap, types);
3338 r = message_read_ap(m, types, ap);
3344 int sd_bus_message_read_array(sd_bus_message *m, char type, const void **ptr, size_t *size) {
3345 struct bus_container *c;
3355 if (!bus_type_is_trivial(type))
3361 if (BUS_MESSAGE_NEED_BSWAP(m))
3364 align = bus_type_get_alignment(type);
3368 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
3372 c = message_get_container(m);
3373 sz = BUS_MESSAGE_BSWAP32(m, *c->array_size);
3375 r = message_peek_body(m, &m->rindex, align, sz, &p);
3383 r = sd_bus_message_exit_container(m);
3387 *ptr = (const void*) p;
3393 message_quit_container(m);
3397 static int message_peek_fields(
3408 return buffer_peek(BUS_MESSAGE_FIELDS(m), BUS_MESSAGE_FIELDS_SIZE(m), rindex, align, nbytes, ret);
3411 static int message_peek_field_uint32(
3422 r = message_peek_fields(m, ri, 4, 4, &q);
3427 *ret = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
3432 static int message_peek_field_string(
3434 bool (*validate)(const char *p),
3445 r = message_peek_field_uint32(m, ri, &l);
3449 r = message_peek_fields(m, ri, 1, l+1, &q);
3454 if (!validate_nul(q, l))
3460 if (!validate_string(q, l))
3470 static int message_peek_field_signature(
3482 r = message_peek_fields(m, ri, 1, 1, &q);
3487 r = message_peek_fields(m, ri, 1, l+1, &q);
3491 if (!validate_signature(q, l))
3500 static int message_skip_fields(
3503 uint32_t array_size,
3504 const char **signature) {
3506 size_t original_index;
3513 original_index = *ri;
3519 if (array_size != (uint32_t) -1 &&
3520 array_size <= *ri - original_index)
3527 if (t == SD_BUS_TYPE_STRING) {
3529 r = message_peek_field_string(m, NULL, ri, NULL);
3535 } else if (t == SD_BUS_TYPE_OBJECT_PATH) {
3537 r = message_peek_field_string(m, object_path_is_valid, ri, NULL);
3543 } else if (t == SD_BUS_TYPE_SIGNATURE) {
3545 r = message_peek_field_signature(m, ri, NULL);
3551 } else if (bus_type_is_basic(t)) {
3554 align = bus_type_get_alignment(t);
3555 k = bus_type_get_size(t);
3556 assert(align > 0 && k > 0);
3558 r = message_peek_fields(m, ri, align, k, NULL);
3564 } else if (t == SD_BUS_TYPE_ARRAY) {
3566 r = signature_element_length(*signature+1, &l);
3576 strncpy(sig, *signature + 1, l-1);
3579 alignment = bus_type_get_alignment(sig[0]);
3583 r = message_peek_field_uint32(m, ri, &nas);
3586 if (nas > BUS_ARRAY_MAX_SIZE)
3589 r = message_peek_fields(m, ri, alignment, 0, NULL);
3593 r = message_skip_fields(m, ri, nas, (const char**) &s);
3598 (*signature) += 1 + l;
3600 } else if (t == SD_BUS_TYPE_VARIANT) {
3603 r = message_peek_field_signature(m, ri, &s);
3607 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
3613 } else if (t == SD_BUS_TYPE_STRUCT ||
3614 t == SD_BUS_TYPE_DICT_ENTRY) {
3616 r = signature_element_length(*signature, &l);
3623 strncpy(sig, *signature + 1, l-1);
3626 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
3637 int bus_message_parse_fields(sd_bus_message *m) {
3640 uint32_t unix_fds = 0;
3644 for (ri = 0; ri < BUS_MESSAGE_FIELDS_SIZE(m); ) {
3645 const char *signature;
3648 r = message_peek_fields(m, &ri, 8, 1, (void**) &header);
3652 r = message_peek_field_signature(m, &ri, &signature);
3657 case _SD_BUS_MESSAGE_HEADER_INVALID:
3660 case SD_BUS_MESSAGE_HEADER_PATH:
3665 if (!streq(signature, "o"))
3668 r = message_peek_field_string(m, object_path_is_valid, &ri, &m->path);
3671 case SD_BUS_MESSAGE_HEADER_INTERFACE:
3676 if (!streq(signature, "s"))
3679 r = message_peek_field_string(m, interface_name_is_valid, &ri, &m->interface);
3682 case SD_BUS_MESSAGE_HEADER_MEMBER:
3687 if (!streq(signature, "s"))
3690 r = message_peek_field_string(m, member_name_is_valid, &ri, &m->member);
3693 case SD_BUS_MESSAGE_HEADER_ERROR_NAME:
3698 if (!streq(signature, "s"))
3701 r = message_peek_field_string(m, error_name_is_valid, &ri, &m->error.name);
3704 case SD_BUS_MESSAGE_HEADER_DESTINATION:
3709 if (!streq(signature, "s"))
3712 r = message_peek_field_string(m, service_name_is_valid, &ri, &m->destination);
3715 case SD_BUS_MESSAGE_HEADER_SENDER:
3720 if (!streq(signature, "s"))
3723 r = message_peek_field_string(m, service_name_is_valid, &ri, &m->sender);
3727 case SD_BUS_MESSAGE_HEADER_SIGNATURE: {
3731 if (m->root_container.signature)
3734 if (!streq(signature, "g"))
3737 r = message_peek_field_signature(m, &ri, &s);
3745 free(m->root_container.signature);
3746 m->root_container.signature = c;
3750 case SD_BUS_MESSAGE_HEADER_REPLY_SERIAL:
3751 if (m->reply_serial != 0)
3754 if (!streq(signature, "u"))
3757 r = message_peek_field_uint32(m, &ri, &m->reply_serial);
3761 if (m->reply_serial == 0)
3766 case SD_BUS_MESSAGE_HEADER_UNIX_FDS:
3770 if (!streq(signature, "u"))
3773 r = message_peek_field_uint32(m, &ri, &unix_fds);
3783 r = message_skip_fields(m, &ri, (uint32_t) -1, (const char **) &signature);
3790 if (m->n_fds != unix_fds)
3793 if (isempty(m->root_container.signature) != (BUS_MESSAGE_BODY_SIZE(m) == 0))
3796 switch (m->header->type) {
3798 case SD_BUS_MESSAGE_TYPE_SIGNAL:
3799 if (!m->path || !m->interface || !m->member)
3803 case SD_BUS_MESSAGE_TYPE_METHOD_CALL:
3805 if (!m->path || !m->member)
3810 case SD_BUS_MESSAGE_TYPE_METHOD_RETURN:
3812 if (m->reply_serial == 0)
3816 case SD_BUS_MESSAGE_TYPE_METHOD_ERROR:
3818 if (m->reply_serial == 0 || !m->error.name)
3823 /* Try to read the error message, but if we can't it's a non-issue */
3824 if (m->header->type == SD_BUS_MESSAGE_TYPE_METHOD_ERROR)
3825 sd_bus_message_read(m, "s", &m->error.message);
3830 int bus_message_seal(sd_bus_message *m, uint64_t serial) {
3831 struct bus_body_part *part;
3841 if (m->n_containers > 0)
3847 /* If there's a non-trivial signature set, then add it in here */
3848 if (!isempty(m->root_container.signature)) {
3849 r = message_append_field_signature(m, SD_BUS_MESSAGE_HEADER_SIGNATURE, m->root_container.signature, NULL);
3855 r = message_append_field_uint32(m, SD_BUS_MESSAGE_HEADER_UNIX_FDS, m->n_fds);
3860 /* Add padding at the end of the fields part, since we know
3861 * the body needs to start at an 8 byte alignment. We made
3862 * sure we allocated enough space for this, so all we need to
3863 * do here is to zero it out. */
3864 l = BUS_MESSAGE_FIELDS_SIZE(m);
3867 memset((uint8_t*) BUS_MESSAGE_FIELDS(m) + l, 0, a);
3869 /* If this is something we can send as memfd, then let's seal
3870 the memfd now. Note that we can send memfds as payload only
3871 for directed messages, and not for broadcasts. */
3872 if (m->destination && m->bus && m->bus->use_memfd) {
3873 MESSAGE_FOREACH_PART(part, i, m)
3874 if (part->memfd >= 0 && !part->sealed && (part->size > MEMFD_MIN_SIZE || m->bus->use_memfd < 0)) {
3875 bus_body_part_unmap(part);
3877 if (ioctl(part->memfd, KDBUS_CMD_MEMFD_SEAL_SET, 1) >= 0)
3878 part->sealed = true;
3882 m->header->serial = serial;
3888 int sd_bus_message_set_destination(sd_bus_message *m, const char *destination) {
3898 return message_append_field_string(m, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &m->destination);
3901 int bus_message_dump(sd_bus_message *m) {
3902 const char *u = NULL, *uu = NULL, *s = NULL;
3903 char **cmdline = NULL;
3906 uid_t owner, audit_loginuid;
3907 uint32_t audit_sessionid;
3911 printf("Message %p\n"
3918 "\tfields_size=%u\n"
3923 "\tdestination=%s\n"
3926 "\treply_serial=%u\n"
3928 "\terror.message=%s\n"
3930 "\tn_body_parts=%u\n",
3937 BUS_MESSAGE_SERIAL(m),
3938 BUS_MESSAGE_FIELDS_SIZE(m),
3939 BUS_MESSAGE_BODY_SIZE(m),
3941 strna(m->interface),
3943 strna(m->destination),
3945 strna(m->root_container.signature),
3947 strna(m->error.name),
3948 strna(m->error.message),
3953 printf("\tpid=%lu\n", (unsigned long) m->pid);
3955 printf("\ttid=%lu\n", (unsigned long) m->tid);
3957 printf("\tuid=%lu\n", (unsigned long) m->uid);
3959 printf("\tgid=%lu\n", (unsigned long) m->gid);
3960 if (m->pid_starttime != 0)
3961 printf("\tpid_starttime=%llu\n", (unsigned long long) m->pid_starttime);
3962 if (m->monotonic != 0)
3963 printf("\tmonotonic=%llu\n", (unsigned long long) m->monotonic);
3964 if (m->realtime != 0)
3965 printf("\trealtime=%llu\n", (unsigned long long) m->realtime);
3967 printf("\texe=[%s]\n", m->exe);
3969 printf("\tcomm=[%s]\n", m->comm);
3971 printf("\ttid_comm=[%s]\n", m->tid_comm);
3973 printf("\tlabel=[%s]\n", m->label);
3975 printf("\tcgroup=[%s]\n", m->cgroup);
3977 sd_bus_message_get_unit(m, &u);
3979 printf("\tunit=[%s]\n", u);
3980 sd_bus_message_get_user_unit(m, &uu);
3982 printf("\tuser_unit=[%s]\n", uu);
3983 sd_bus_message_get_session(m, &s);
3985 printf("\tsession=[%s]\n", s);
3986 if (sd_bus_message_get_owner_uid(m, &owner) >= 0)
3987 printf("\towner_uid=%lu\n", (unsigned long) owner);
3988 if (sd_bus_message_get_audit_loginuid(m, &audit_loginuid) >= 0)
3989 printf("\taudit_loginuid=%lu\n", (unsigned long) audit_loginuid);
3990 if (sd_bus_message_get_audit_sessionid(m, &audit_sessionid) >= 0)
3991 printf("\taudit_sessionid=%lu\n", (unsigned long) audit_sessionid);
3993 printf("\tCAP_KILL=%i\n", sd_bus_message_has_effective_cap(m, 5));
3995 if (sd_bus_message_get_cmdline(m, &cmdline) >= 0) {
3998 fputs("\tcmdline=[", stdout);
3999 STRV_FOREACH(c, cmdline) {
4006 fputs("]\n", stdout);
4009 r = sd_bus_message_rewind(m, true);
4011 log_error("Failed to rewind: %s", strerror(-r));
4015 printf("BEGIN_MESSAGE \"%s\" {\n", strempty(m->root_container.signature));
4018 _cleanup_free_ char *prefix = NULL;
4019 const char *contents = NULL;
4034 r = sd_bus_message_peek_type(m, &type, &contents);
4036 log_error("Failed to peek type: %s", strerror(-r));
4043 r = sd_bus_message_exit_container(m);
4045 log_error("Failed to exit container: %s", strerror(-r));
4051 prefix = strrep("\t", level);
4055 if (type == SD_BUS_TYPE_ARRAY)
4056 printf("%s} END_ARRAY \n", prefix);
4057 else if (type == SD_BUS_TYPE_VARIANT)
4058 printf("%s} END_VARIANT\n", prefix);
4059 else if (type == SD_BUS_TYPE_STRUCT)
4060 printf("%s} END_STRUCT\n", prefix);
4061 else if (type == SD_BUS_TYPE_DICT_ENTRY)
4062 printf("%s} END_DICT_ENTRY\n", prefix);
4067 prefix = strrep("\t", level);
4071 if (bus_type_is_container(type) > 0) {
4072 r = sd_bus_message_enter_container(m, type, contents);
4074 log_error("Failed to enter container: %s", strerror(-r));
4078 if (type == SD_BUS_TYPE_ARRAY)
4079 printf("%sBEGIN_ARRAY \"%s\" {\n", prefix, contents);
4080 else if (type == SD_BUS_TYPE_VARIANT)
4081 printf("%sBEGIN_VARIANT \"%s\" {\n", prefix, contents);
4082 else if (type == SD_BUS_TYPE_STRUCT)
4083 printf("%sBEGIN_STRUCT \"%s\" {\n", prefix, contents);
4084 else if (type == SD_BUS_TYPE_DICT_ENTRY)
4085 printf("%sBEGIN_DICT_ENTRY \"%s\" {\n", prefix, contents);
4092 r = sd_bus_message_read_basic(m, type, &basic);
4094 log_error("Failed to get basic: %s", strerror(-r));
4100 case SD_BUS_TYPE_BYTE:
4101 printf("%sBYTE: %u\n", prefix, basic.u8);
4104 case SD_BUS_TYPE_BOOLEAN:
4105 printf("%sBOOLEAN: %s\n", prefix, yes_no(basic.i));
4108 case SD_BUS_TYPE_INT16:
4109 printf("%sINT16: %i\n", prefix, basic.s16);
4112 case SD_BUS_TYPE_UINT16:
4113 printf("%sUINT16: %u\n", prefix, basic.u16);
4116 case SD_BUS_TYPE_INT32:
4117 printf("%sINT32: %i\n", prefix, basic.s32);
4120 case SD_BUS_TYPE_UINT32:
4121 printf("%sUINT32: %u\n", prefix, basic.u32);
4124 case SD_BUS_TYPE_INT64:
4125 printf("%sINT64: %lli\n", prefix, (long long) basic.s64);
4128 case SD_BUS_TYPE_UINT64:
4129 printf("%sUINT64: %llu\n", prefix, (unsigned long long) basic.u64);
4132 case SD_BUS_TYPE_DOUBLE:
4133 printf("%sDOUBLE: %g\n", prefix, basic.d64);
4136 case SD_BUS_TYPE_STRING:
4137 printf("%sSTRING: \"%s\"\n", prefix, basic.string);
4140 case SD_BUS_TYPE_OBJECT_PATH:
4141 printf("%sOBJECT_PATH: \"%s\"\n", prefix, basic.string);
4144 case SD_BUS_TYPE_SIGNATURE:
4145 printf("%sSIGNATURE: \"%s\"\n", prefix, basic.string);
4148 case SD_BUS_TYPE_UNIX_FD:
4149 printf("%sUNIX_FD: %i\n", prefix, basic.i);
4153 assert_not_reached("Unknown basic type.");
4157 printf("} END_MESSAGE\n");
4161 int bus_message_get_blob(sd_bus_message *m, void **buffer, size_t *sz) {
4165 struct bus_body_part *part;
4171 total = BUS_MESSAGE_SIZE(m);
4177 e = mempcpy(p, m->header, BUS_MESSAGE_BODY_BEGIN(m));
4178 MESSAGE_FOREACH_PART(part, i, m)
4179 e = mempcpy(e, part->data, part->size);
4181 assert(total == (size_t) ((uint8_t*) e - (uint8_t*) p));
4189 int bus_message_read_strv_extend(sd_bus_message *m, char ***l) {
4195 r = sd_bus_message_enter_container(m, 'a', "s");
4202 r = sd_bus_message_read_basic(m, 's', &s);
4208 r = strv_extend(l, s);
4213 r = sd_bus_message_exit_container(m);
4220 const char* bus_message_get_arg(sd_bus_message *m, unsigned i) {
4222 const char *t = NULL;
4227 r = sd_bus_message_rewind(m, true);
4231 for (j = 0; j <= i; j++) {
4234 r = sd_bus_message_peek_type(m, &type, NULL);
4238 if (type != SD_BUS_TYPE_STRING &&
4239 type != SD_BUS_TYPE_OBJECT_PATH &&
4240 type != SD_BUS_TYPE_SIGNATURE)
4243 r = sd_bus_message_read_basic(m, type, &t);
4251 bool bus_header_is_complete(struct bus_header *h, size_t size) {
4257 if (size < sizeof(struct bus_header))
4260 full = sizeof(struct bus_header) +
4261 (h->endian == SD_BUS_NATIVE_ENDIAN ? h->fields_size : bswap_32(h->fields_size));
4263 return size >= full;
4266 int bus_header_message_size(struct bus_header *h, size_t *sum) {
4272 if (h->endian == SD_BUS_NATIVE_ENDIAN) {
4273 fs = h->fields_size;
4275 } else if (h->endian == SD_BUS_REVERSE_ENDIAN) {
4276 fs = bswap_32(h->fields_size);
4277 bs = bswap_32(h->body_size);
4281 *sum = sizeof(struct bus_header) + ALIGN8(fs) + bs;
4285 int bus_message_to_errno(sd_bus_message *m) {
4288 if (m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_ERROR)
4291 return bus_error_to_errno(&m->error);