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) {
499 if (destination && !service_name_is_valid(destination))
501 if (!object_path_is_valid(path))
503 if (interface && !interface_name_is_valid(interface))
505 if (!member_name_is_valid(member))
509 if (bus && bus->state == BUS_UNSET)
512 t = message_new(bus, SD_BUS_MESSAGE_TYPE_METHOD_CALL);
516 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_PATH, SD_BUS_TYPE_OBJECT_PATH, path, &t->path);
519 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_MEMBER, SD_BUS_TYPE_STRING, member, &t->member);
524 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_INTERFACE, SD_BUS_TYPE_STRING, interface, &t->interface);
530 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &t->destination);
543 static int message_new_reply(
545 sd_bus_message *call,
547 sd_bus_message **m) {
556 if (call->header->type != SD_BUS_MESSAGE_TYPE_METHOD_CALL)
560 if (bus && bus->state == BUS_UNSET)
563 t = message_new(bus, type);
567 t->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
568 t->reply_serial = BUS_MESSAGE_SERIAL(call);
570 r = message_append_field_uint32(t, SD_BUS_MESSAGE_HEADER_REPLY_SERIAL, t->reply_serial);
575 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, call->sender, &t->destination);
580 t->dont_send = !!(call->header->flags & SD_BUS_MESSAGE_NO_REPLY_EXPECTED);
590 int sd_bus_message_new_method_return(
592 sd_bus_message *call,
593 sd_bus_message **m) {
595 return message_new_reply(bus, call, SD_BUS_MESSAGE_TYPE_METHOD_RETURN, m);
598 int sd_bus_message_new_method_error(
600 sd_bus_message *call,
601 const sd_bus_error *e,
602 sd_bus_message **m) {
607 if (!sd_bus_error_is_set(e))
612 r = message_new_reply(bus, call, SD_BUS_MESSAGE_TYPE_METHOD_ERROR, &t);
616 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_ERROR_NAME, SD_BUS_TYPE_STRING, e->name, &t->error.name);
621 r = message_append_basic(t, SD_BUS_TYPE_STRING, e->message, (const void**) &t->error.message);
634 int sd_bus_message_new_method_errorf(
636 sd_bus_message *call,
642 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
652 r = message_new_reply(bus, call, SD_BUS_MESSAGE_TYPE_METHOD_ERROR, &t);
656 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_ERROR_NAME, SD_BUS_TYPE_STRING, name, &t->error.name);
661 _cleanup_free_ char *message = NULL;
663 va_start(ap, format);
664 r = vasprintf(&message, format, ap);
672 r = message_append_basic(t, SD_BUS_TYPE_STRING, message, (const void**) &t->error.message);
686 int bus_message_new_synthetic_error(
689 const sd_bus_error *e,
690 sd_bus_message **m) {
695 assert(sd_bus_error_is_set(e));
698 t = message_new(bus, SD_BUS_MESSAGE_TYPE_METHOD_ERROR);
702 t->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
703 t->reply_serial = serial;
705 r = message_append_field_uint32(t, SD_BUS_MESSAGE_HEADER_REPLY_SERIAL, t->reply_serial);
709 if (bus && bus->unique_name) {
710 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, bus->unique_name, &t->destination);
723 sd_bus_message* sd_bus_message_ref(sd_bus_message *m) {
727 assert(m->n_ref > 0);
733 sd_bus_message* sd_bus_message_unref(sd_bus_message *m) {
737 assert(m->n_ref > 0);
746 int sd_bus_message_get_type(sd_bus_message *m, uint8_t *type) {
752 *type = m->header->type;
756 int sd_bus_message_get_serial(sd_bus_message *m, uint64_t *serial) {
761 if (m->header->serial == 0)
764 *serial = BUS_MESSAGE_SERIAL(m);
768 int sd_bus_message_get_reply_serial(sd_bus_message *m, uint64_t *serial) {
773 if (m->reply_serial == 0)
776 *serial = m->reply_serial;
780 int sd_bus_message_get_no_reply(sd_bus_message *m) {
784 return m->header->type == SD_BUS_MESSAGE_TYPE_METHOD_CALL ? !!(m->header->flags & SD_BUS_MESSAGE_NO_REPLY_EXPECTED) : 0;
787 const char *sd_bus_message_get_path(sd_bus_message *m) {
794 const char *sd_bus_message_get_interface(sd_bus_message *m) {
801 const char *sd_bus_message_get_member(sd_bus_message *m) {
807 const char *sd_bus_message_get_destination(sd_bus_message *m) {
811 return m->destination;
814 const char *sd_bus_message_get_sender(sd_bus_message *m) {
821 const sd_bus_error *sd_bus_message_get_error(sd_bus_message *m) {
825 if (!sd_bus_error_is_set(&m->error))
831 int sd_bus_message_get_uid(sd_bus_message *m, uid_t *uid) {
843 int sd_bus_message_get_gid(sd_bus_message *m, gid_t *gid) {
855 int sd_bus_message_get_pid(sd_bus_message *m, pid_t *pid) {
867 int sd_bus_message_get_tid(sd_bus_message *m, pid_t *tid) {
879 int sd_bus_message_get_pid_starttime(sd_bus_message *m, uint64_t *usec) {
884 if (m->pid_starttime <= 0)
887 *usec = m->pid_starttime;
891 int sd_bus_message_get_selinux_context(sd_bus_message *m, const char **ret) {
901 int sd_bus_message_get_monotonic_timestamp(sd_bus_message *m, uint64_t *usec) {
906 if (m->monotonic <= 0)
909 *usec = m->monotonic;
913 int sd_bus_message_get_realtime_timestamp(sd_bus_message *m, uint64_t *usec) {
918 if (m->realtime <= 0)
925 int sd_bus_message_get_comm(sd_bus_message *m, const char **ret) {
937 int sd_bus_message_get_tid_comm(sd_bus_message *m, const char **ret) {
949 int sd_bus_message_get_exe(sd_bus_message *m, const char **ret) {
961 int sd_bus_message_get_cgroup(sd_bus_message *m, const char **ret) {
973 int sd_bus_message_get_unit(sd_bus_message *m, const char **ret) {
984 r = cg_path_get_unit(m->cgroup, &m->unit);
993 int sd_bus_message_get_user_unit(sd_bus_message *m, const char **ret) {
1003 if (!m->user_unit) {
1004 r = cg_path_get_user_unit(m->cgroup, &m->user_unit);
1009 *ret = m->user_unit;
1013 int sd_bus_message_get_session(sd_bus_message *m, const char **ret) {
1024 r = cg_path_get_session(m->cgroup, &m->session);
1033 int sd_bus_message_get_owner_uid(sd_bus_message *m, uid_t *uid) {
1041 return cg_path_get_owner_uid(m->cgroup, uid);
1044 int sd_bus_message_get_cmdline(sd_bus_message *m, char ***cmdline) {
1055 for (p = m->cmdline, n = 0; p < m->cmdline + m->cmdline_length; p++)
1059 m->cmdline_array = new(char*, n + 1);
1060 if (!m->cmdline_array)
1063 for (p = m->cmdline, i = 0, first = true; p < m->cmdline + m->cmdline_length; p++) {
1065 m->cmdline_array[i++] = (char*) p;
1070 m->cmdline_array[i] = NULL;
1071 *cmdline = m->cmdline_array;
1076 int sd_bus_message_get_audit_sessionid(sd_bus_message *m, uint32_t *sessionid) {
1084 *sessionid = m->audit->sessionid;
1088 int sd_bus_message_get_audit_loginuid(sd_bus_message *m, uid_t *uid) {
1096 *uid = m->audit->loginuid;
1100 int sd_bus_message_has_effective_cap(sd_bus_message *m, int capability) {
1110 sz = m->capability_size / 4;
1111 if ((unsigned) capability >= sz*8)
1114 return !!(m->capability[2 * sz + (capability / 8)] & (1 << (capability % 8)));
1117 int sd_bus_message_is_signal(sd_bus_message *m, const char *interface, const char *member) {
1121 if (m->header->type != SD_BUS_MESSAGE_TYPE_SIGNAL)
1124 if (interface && (!m->interface || !streq(m->interface, interface)))
1127 if (member && (!m->member || !streq(m->member, member)))
1133 int sd_bus_message_is_method_call(sd_bus_message *m, const char *interface, const char *member) {
1137 if (m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_CALL)
1140 if (interface && (!m->interface || !streq(m->interface, interface)))
1143 if (member && (!m->member || !streq(m->member, member)))
1149 int sd_bus_message_is_method_error(sd_bus_message *m, const char *name) {
1153 if (m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_ERROR)
1156 if (name && (!m->error.name || !streq(m->error.name, name)))
1162 int sd_bus_message_set_no_reply(sd_bus_message *m, int b) {
1167 if (m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_CALL)
1171 m->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
1173 m->header->flags &= ~SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
1178 static struct bus_container *message_get_container(sd_bus_message *m) {
1181 if (m->n_containers == 0)
1182 return &m->root_container;
1184 assert(m->containers);
1185 return m->containers + m->n_containers - 1;
1188 struct bus_body_part *message_append_part(sd_bus_message *m) {
1189 struct bus_body_part *part;
1196 if (m->n_body_parts <= 0) {
1200 assert(m->body_end);
1202 part = new0(struct bus_body_part, 1);
1208 m->body_end->next = part;
1218 static void part_zero(struct bus_body_part *part, size_t sz) {
1223 /* All other fields can be left in their defaults */
1224 assert(!part->data);
1225 assert(part->memfd < 0);
1228 part->is_zero = true;
1229 part->sealed = true;
1232 static int part_make_space(
1233 struct sd_bus_message *m,
1234 struct bus_body_part *part,
1243 assert(!part->sealed);
1248 if (!part->data && part->memfd < 0)
1249 part->memfd = bus_kernel_pop_memfd(m->bus, &part->data, &part->mapped);
1251 if (part->memfd >= 0) {
1254 r = ioctl(part->memfd, KDBUS_CMD_MEMFD_SIZE_SET, &u);
1260 if (!part->data || sz > part->mapped) {
1261 size_t psz = PAGE_ALIGN(sz > 0 ? sz : 1);
1263 if (part->mapped <= 0)
1264 n = mmap(NULL, psz, PROT_READ|PROT_WRITE, MAP_SHARED, part->memfd, 0);
1266 n = mremap(part->data, part->mapped, psz, MREMAP_MAYMOVE);
1268 if (n == MAP_FAILED) {
1277 part->munmap_this = true;
1279 n = realloc(part->data, sz);
1286 part->free_this = true;
1290 *q = part->data ? (uint8_t*) part->data + part->size : NULL;
1296 static void message_extend_containers(sd_bus_message *m, size_t expand) {
1297 struct bus_container *c;
1304 /* Update counters */
1305 for (c = m->containers; c < m->containers + m->n_containers; c++)
1307 *c->array_size += expand;
1310 static void *message_extend_body(sd_bus_message *m, size_t align, size_t sz) {
1311 struct bus_body_part *part = NULL;
1312 size_t start_body, end_body, padding, start_part, end_part, added;
1324 start_body = ALIGN_TO((size_t) m->header->body_size, align);
1325 end_body = start_body + sz;
1327 padding = start_body - m->header->body_size;
1328 added = padding + sz;
1330 /* Check for 32bit overflows */
1331 if (end_body > (size_t) ((uint32_t) -1)) {
1337 m->n_body_parts <= 0 ||
1338 m->body_end->sealed ||
1339 padding != ALIGN_TO(m->body_end->size, align) - m->body_end->size;
1343 part = message_append_part(m);
1347 part_zero(part, padding);
1350 part = message_append_part(m);
1354 r = part_make_space(m, part, sz, &p);
1358 struct bus_container *c;
1366 start_part = ALIGN_TO(part->size, align);
1367 end_part = start_part + sz;
1369 r = part_make_space(m, part, end_part, &p);
1374 memset(p, 0, padding);
1375 p = (uint8_t*) p + padding;
1378 /* Readjust pointers */
1379 for (c = m->containers; c < m->containers + m->n_containers; c++)
1380 c->array_size = adjust_pointer(c->array_size, op, os, part->data);
1382 m->error.message = (const char*) adjust_pointer(m->error.message, op, os, part->data);
1385 m->header->body_size = end_body;
1386 message_extend_containers(m, added);
1391 int message_append_basic(sd_bus_message *m, char type, const void *p, const void **stored) {
1392 struct bus_container *c;
1406 if (!bus_type_is_basic(type))
1411 c = message_get_container(m);
1413 if (c->signature && c->signature[c->index]) {
1414 /* Container signature is already set */
1416 if (c->signature[c->index] != type)
1421 /* Maybe we can append to the signature? But only if this is the top-level container*/
1422 if (c->enclosing != 0)
1425 e = strextend(&c->signature, CHAR_TO_STR(type), NULL);
1434 case SD_BUS_TYPE_STRING:
1435 case SD_BUS_TYPE_OBJECT_PATH:
1438 sz = 4 + strlen(p) + 1;
1441 case SD_BUS_TYPE_SIGNATURE:
1444 sz = 1 + strlen(p) + 1;
1447 case SD_BUS_TYPE_BOOLEAN:
1450 assert_cc(sizeof(int) == sizeof(uint32_t));
1456 case SD_BUS_TYPE_UNIX_FD: {
1459 if (!m->allow_fds) {
1472 fd = fcntl(z, F_DUPFD_CLOEXEC, 3);
1478 f = realloc(m->fds, sizeof(int) * (m->n_fds + 1));
1493 align = bus_type_get_alignment(type);
1494 sz = bus_type_get_size(type);
1501 a = message_extend_body(m, align, sz);
1507 if (type == SD_BUS_TYPE_STRING || type == SD_BUS_TYPE_OBJECT_PATH) {
1508 *(uint32_t*) a = sz - 5;
1509 memcpy((uint8_t*) a + 4, p, sz - 4);
1512 *stored = (const uint8_t*) a + 4;
1514 } else if (type == SD_BUS_TYPE_SIGNATURE) {
1515 *(uint8_t*) a = sz - 1;
1516 memcpy((uint8_t*) a + 1, p, sz - 1);
1519 *stored = (const uint8_t*) a + 1;
1520 } else if (type == SD_BUS_TYPE_UNIX_FD) {
1521 *(uint32_t*) a = fdi;
1535 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1542 close_nointr_nofail(fd);
1547 int sd_bus_message_append_basic(sd_bus_message *m, char type, const void *p) {
1548 return message_append_basic(m, type, p, NULL);
1551 int sd_bus_message_append_string_space(sd_bus_message *m, size_t size, char **s) {
1552 struct bus_container *c;
1564 c = message_get_container(m);
1566 if (c->signature && c->signature[c->index]) {
1567 /* Container signature is already set */
1569 if (c->signature[c->index] != SD_BUS_TYPE_STRING)
1574 /* Maybe we can append to the signature? But only if this is the top-level container*/
1575 if (c->enclosing != 0)
1578 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRING), NULL);
1585 a = message_extend_body(m, 4, 4 + size + 1);
1589 *(uint32_t*) a = size;
1594 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1600 static int bus_message_open_array(
1602 struct bus_container *c,
1603 const char *contents,
1604 uint32_t **array_size) {
1610 struct bus_body_part *o;
1617 if (!signature_is_single(contents, true))
1620 alignment = bus_type_get_alignment(contents[0]);
1624 if (c->signature && c->signature[c->index]) {
1626 /* Verify the existing signature */
1628 if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
1631 if (!startswith(c->signature + c->index + 1, contents))
1634 nindex = c->index + 1 + strlen(contents);
1638 if (c->enclosing != 0)
1641 /* Extend the existing signature */
1643 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_ARRAY), contents, NULL);
1649 nindex = e - c->signature;
1652 a = message_extend_body(m, 4, 4);
1657 op = m->body_end->data;
1658 os = m->body_end->size;
1660 /* Add alignment between size and first element */
1661 if (!message_extend_body(m, alignment, 0))
1664 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1667 /* location of array size might have changed so let's readjust a */
1668 if (o == m->body_end)
1669 a = adjust_pointer(a, op, os, m->body_end->data);
1676 static int bus_message_open_variant(
1678 struct bus_container *c,
1679 const char *contents) {
1688 if (!signature_is_single(contents, false))
1691 if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
1694 if (c->signature && c->signature[c->index]) {
1696 if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
1702 if (c->enclosing != 0)
1705 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_VARIANT), NULL);
1712 l = strlen(contents);
1713 a = message_extend_body(m, 1, 1 + l + 1);
1718 memcpy((uint8_t*) a + 1, contents, l + 1);
1720 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1726 static int bus_message_open_struct(
1728 struct bus_container *c,
1729 const char *contents) {
1737 if (!signature_is_valid(contents, false))
1740 if (c->signature && c->signature[c->index]) {
1743 l = strlen(contents);
1745 if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
1746 !startswith(c->signature + c->index + 1, contents) ||
1747 c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
1750 nindex = c->index + 1 + l + 1;
1754 if (c->enclosing != 0)
1757 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_BEGIN), contents, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_END), NULL);
1763 nindex = e - c->signature;
1766 /* Align contents to 8 byte boundary */
1767 if (!message_extend_body(m, 8, 0))
1770 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1776 static int bus_message_open_dict_entry(
1778 struct bus_container *c,
1779 const char *contents) {
1787 if (!signature_is_pair(contents))
1790 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1793 if (c->signature && c->signature[c->index]) {
1796 l = strlen(contents);
1798 if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
1799 !startswith(c->signature + c->index + 1, contents) ||
1800 c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
1803 nindex = c->index + 1 + l + 1;
1807 /* Align contents to 8 byte boundary */
1808 if (!message_extend_body(m, 8, 0))
1811 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1817 int sd_bus_message_open_container(
1820 const char *contents) {
1822 struct bus_container *c, *w;
1823 uint32_t *array_size = NULL;
1837 /* Make sure we have space for one more container */
1838 w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
1846 c = message_get_container(m);
1848 signature = strdup(contents);
1854 /* Save old index in the parent container, in case we have to
1855 * abort this container */
1856 c->saved_index = c->index;
1857 before = m->header->body_size;
1859 if (type == SD_BUS_TYPE_ARRAY)
1860 r = bus_message_open_array(m, c, contents, &array_size);
1861 else if (type == SD_BUS_TYPE_VARIANT)
1862 r = bus_message_open_variant(m, c, contents);
1863 else if (type == SD_BUS_TYPE_STRUCT)
1864 r = bus_message_open_struct(m, c, contents);
1865 else if (type == SD_BUS_TYPE_DICT_ENTRY)
1866 r = bus_message_open_dict_entry(m, c, contents);
1875 /* OK, let's fill it in */
1876 w += m->n_containers++;
1877 w->enclosing = type;
1878 w->signature = signature;
1880 w->array_size = array_size;
1882 w->begin = m->rindex;
1887 int sd_bus_message_close_container(sd_bus_message *m) {
1888 struct bus_container *c;
1894 if (m->n_containers <= 0)
1899 c = message_get_container(m);
1900 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1901 if (c->signature && c->signature[c->index] != 0)
1916 static int type_stack_push(TypeStack *stack, unsigned max, unsigned *i, const char *types, unsigned n_struct, unsigned n_array) {
1923 stack[*i].types = types;
1924 stack[*i].n_struct = n_struct;
1925 stack[*i].n_array = n_array;
1931 static int type_stack_pop(TypeStack *stack, unsigned max, unsigned *i, const char **types, unsigned *n_struct, unsigned *n_array) {
1942 *types = stack[*i].types;
1943 *n_struct = stack[*i].n_struct;
1944 *n_array = stack[*i].n_array;
1949 int bus_message_append_ap(
1954 unsigned n_array, n_struct;
1955 TypeStack stack[BUS_CONTAINER_DEPTH];
1956 unsigned stack_ptr = 0;
1964 n_array = (unsigned) -1;
1965 n_struct = strlen(types);
1970 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
1971 r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
1977 r = sd_bus_message_close_container(m);
1985 if (n_array != (unsigned) -1)
1994 case SD_BUS_TYPE_BYTE: {
1997 x = (uint8_t) va_arg(ap, int);
1998 r = sd_bus_message_append_basic(m, *t, &x);
2002 case SD_BUS_TYPE_BOOLEAN:
2003 case SD_BUS_TYPE_INT32:
2004 case SD_BUS_TYPE_UINT32:
2005 case SD_BUS_TYPE_UNIX_FD: {
2008 /* We assume a boolean is the same as int32_t */
2009 assert_cc(sizeof(int32_t) == sizeof(int));
2011 x = va_arg(ap, uint32_t);
2012 r = sd_bus_message_append_basic(m, *t, &x);
2016 case SD_BUS_TYPE_INT16:
2017 case SD_BUS_TYPE_UINT16: {
2020 x = (uint16_t) va_arg(ap, int);
2021 r = sd_bus_message_append_basic(m, *t, &x);
2025 case SD_BUS_TYPE_INT64:
2026 case SD_BUS_TYPE_UINT64:
2027 case SD_BUS_TYPE_DOUBLE: {
2030 x = va_arg(ap, uint64_t);
2031 r = sd_bus_message_append_basic(m, *t, &x);
2035 case SD_BUS_TYPE_STRING:
2036 case SD_BUS_TYPE_OBJECT_PATH:
2037 case SD_BUS_TYPE_SIGNATURE: {
2040 x = va_arg(ap, const char*);
2041 r = sd_bus_message_append_basic(m, *t, x);
2045 case SD_BUS_TYPE_ARRAY: {
2048 r = signature_element_length(t + 1, &k);
2054 memcpy(s, t + 1, k);
2057 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, s);
2062 if (n_array == (unsigned) -1) {
2067 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2073 n_array = va_arg(ap, unsigned);
2078 case SD_BUS_TYPE_VARIANT: {
2081 s = va_arg(ap, const char*);
2085 r = sd_bus_message_open_container(m, SD_BUS_TYPE_VARIANT, s);
2089 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2094 n_struct = strlen(s);
2095 n_array = (unsigned) -1;
2100 case SD_BUS_TYPE_STRUCT_BEGIN:
2101 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
2104 r = signature_element_length(t, &k);
2111 memcpy(s, t + 1, k - 2);
2114 r = sd_bus_message_open_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
2119 if (n_array == (unsigned) -1) {
2124 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2130 n_array = (unsigned) -1;
2146 int sd_bus_message_append(sd_bus_message *m, const char *types, ...) {
2159 va_start(ap, types);
2160 r = bus_message_append_ap(m, types, ap);
2166 int sd_bus_message_append_array_space(sd_bus_message *m, char type, size_t size, void **ptr) {
2175 if (!bus_type_is_trivial(type))
2177 if (!ptr && size > 0)
2182 align = bus_type_get_alignment(type);
2183 sz = bus_type_get_size(type);
2185 assert_se(align > 0);
2191 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
2195 a = message_extend_body(m, align, size);
2199 r = sd_bus_message_close_container(m);
2207 int sd_bus_message_append_array(sd_bus_message *m, char type, const void *ptr, size_t size) {
2211 if (!ptr && size > 0)
2214 r = sd_bus_message_append_array_space(m, type, size, &p);
2219 memcpy(p, ptr, size);
2224 int sd_bus_message_append_array_memfd(sd_bus_message *m, char type, sd_memfd *memfd) {
2225 _cleanup_close_ int copy_fd = -1;
2226 struct bus_body_part *part;
2238 if (!bus_type_is_trivial(type))
2243 r = sd_memfd_set_sealed(memfd, true);
2247 copy_fd = sd_memfd_dup_fd(memfd);
2251 r = sd_memfd_get_size(memfd, &size);
2255 align = bus_type_get_alignment(type);
2256 sz = bus_type_get_size(type);
2258 assert_se(align > 0);
2264 if (size > (uint64_t) (uint32_t) -1)
2267 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
2271 a = message_extend_body(m, align, 0);
2275 part = message_append_part(m);
2279 part->memfd = copy_fd;
2280 part->sealed = true;
2284 message_extend_containers(m, size);
2285 m->header->body_size += size;
2287 return sd_bus_message_close_container(m);
2290 int sd_bus_message_append_string_memfd(sd_bus_message *m, sd_memfd *memfd) {
2291 _cleanup_close_ int copy_fd = -1;
2292 struct bus_body_part *part;
2293 struct bus_container *c;
2307 r = sd_memfd_set_sealed(memfd, true);
2311 copy_fd = sd_memfd_dup_fd(memfd);
2315 r = sd_memfd_get_size(memfd, &size);
2319 /* We require this to be NUL terminated */
2323 if (size > (uint64_t) (uint32_t) -1)
2326 c = message_get_container(m);
2327 if (c->signature && c->signature[c->index]) {
2328 /* Container signature is already set */
2330 if (c->signature[c->index] != SD_BUS_TYPE_STRING)
2335 /* Maybe we can append to the signature? But only if this is the top-level container*/
2336 if (c->enclosing != 0)
2339 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRING), NULL);
2346 a = message_extend_body(m, 4, 4);
2350 *(uint32_t*) a = size - 1;
2352 part = message_append_part(m);
2356 part->memfd = copy_fd;
2357 part->sealed = true;
2361 message_extend_containers(m, size);
2362 m->header->body_size += size;
2364 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2370 int bus_body_part_map(struct bus_body_part *part) {
2379 if (part->size <= 0)
2382 /* For smaller zero parts (as used for padding) we don't need to map anything... */
2383 if (part->memfd < 0 && part->is_zero && part->size < 8) {
2384 static const uint8_t zeroes[7] = { };
2385 part->data = (void*) zeroes;
2389 psz = PAGE_ALIGN(part->size);
2391 if (part->memfd >= 0)
2392 p = mmap(NULL, psz, PROT_READ, MAP_SHARED, part->memfd, 0);
2393 else if (part->is_zero)
2394 p = mmap(NULL, psz, PROT_READ, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
2398 if (p == MAP_FAILED)
2403 part->munmap_this = true;
2408 void bus_body_part_unmap(struct bus_body_part *part) {
2412 if (part->memfd < 0)
2418 if (!part->munmap_this)
2421 assert_se(munmap(part->data, part->mapped) == 0);
2425 part->munmap_this = false;
2430 static int buffer_peek(const void *p, uint32_t sz, size_t *rindex, size_t align, size_t nbytes, void **r) {
2431 size_t k, start, end;
2436 start = ALIGN_TO((size_t) *rindex, align);
2437 end = start + nbytes;
2442 /* Verify that padding is 0 */
2443 for (k = *rindex; k < start; k++)
2444 if (((const uint8_t*) p)[k] != 0)
2448 *r = (uint8_t*) p + start;
2455 static bool message_end_of_array(sd_bus_message *m, size_t index) {
2456 struct bus_container *c;
2460 c = message_get_container(m);
2464 return index >= c->begin + BUS_MESSAGE_BSWAP32(m, *c->array_size);
2467 static struct bus_body_part* find_part(sd_bus_message *m, size_t index, size_t sz, void **p) {
2468 struct bus_body_part *part;
2474 if (m->cached_rindex_part && index >= m->cached_rindex_part_begin) {
2475 part = m->cached_rindex_part;
2476 begin = m->cached_rindex_part_begin;
2486 if (index + sz <= begin + part->size) {
2488 r = bus_body_part_map(part);
2493 *p = (uint8_t*) part->data + index - begin;
2495 m->cached_rindex_part = part;
2496 m->cached_rindex_part_begin = begin;
2501 begin += part->size;
2508 static int message_peek_body(
2515 size_t k, start, end, padding;
2516 struct bus_body_part *part;
2523 if (message_end_of_array(m, *rindex))
2526 start = ALIGN_TO((size_t) *rindex, align);
2527 padding = start - *rindex;
2528 end = start + nbytes;
2530 if (end > BUS_MESSAGE_BODY_SIZE(m))
2533 part = find_part(m, *rindex, padding, (void**) &q);
2538 /* Verify padding */
2539 for (k = 0; k < padding; k++)
2544 part = find_part(m, start, nbytes, (void**) &q);
2556 static bool validate_nul(const char *s, size_t l) {
2558 /* Check for NUL chars in the string */
2559 if (memchr(s, 0, l))
2562 /* Check for NUL termination */
2569 static bool validate_string(const char *s, size_t l) {
2571 if (!validate_nul(s, l))
2574 /* Check if valid UTF8 */
2575 if (!utf8_is_valid(s))
2581 static bool validate_signature(const char *s, size_t l) {
2583 if (!validate_nul(s, l))
2586 /* Check if valid signature */
2587 if (!signature_is_valid(s, true))
2593 static bool validate_object_path(const char *s, size_t l) {
2595 if (!validate_nul(s, l))
2598 if (!object_path_is_valid(s))
2604 int sd_bus_message_read_basic(sd_bus_message *m, char type, void *p) {
2605 struct bus_container *c;
2613 if (!bus_type_is_basic(type))
2618 c = message_get_container(m);
2620 if (!c->signature || c->signature[c->index] == 0)
2623 if (c->signature[c->index] != type)
2628 case SD_BUS_TYPE_STRING:
2629 case SD_BUS_TYPE_OBJECT_PATH: {
2634 r = message_peek_body(m, &rindex, 4, 4, &q);
2638 l = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2639 r = message_peek_body(m, &rindex, 1, l+1, &q);
2645 if (type == SD_BUS_TYPE_OBJECT_PATH) {
2646 if (!validate_object_path(q, l))
2649 if (!validate_string(q, l))
2654 *(const char**) p = q;
2658 case SD_BUS_TYPE_SIGNATURE: {
2663 r = message_peek_body(m, &rindex, 1, 1, &q);
2668 r = message_peek_body(m, &rindex, 1, l+1, &q);
2674 if (!validate_signature(q, l))
2678 *(const char**) p = q;
2686 align = bus_type_get_alignment(type);
2687 sz = bus_type_get_size(type);
2688 assert(align > 0 && sz > 0);
2691 r = message_peek_body(m, &rindex, align, sz, &q);
2697 case SD_BUS_TYPE_BYTE:
2698 *(uint8_t*) p = *(uint8_t*) q;
2701 case SD_BUS_TYPE_BOOLEAN:
2702 *(int*) p = !!*(uint32_t*) q;
2705 case SD_BUS_TYPE_INT16:
2706 case SD_BUS_TYPE_UINT16:
2707 *(uint16_t*) p = BUS_MESSAGE_BSWAP16(m, *(uint16_t*) q);
2710 case SD_BUS_TYPE_INT32:
2711 case SD_BUS_TYPE_UINT32:
2712 *(uint32_t*) p = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2715 case SD_BUS_TYPE_INT64:
2716 case SD_BUS_TYPE_UINT64:
2717 case SD_BUS_TYPE_DOUBLE:
2718 *(uint64_t*) p = BUS_MESSAGE_BSWAP64(m, *(uint64_t*) q);
2721 case SD_BUS_TYPE_UNIX_FD: {
2724 j = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2728 *(int*) p = m->fds[j];
2733 assert_not_reached("Unknown basic type...");
2742 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2748 static int bus_message_enter_array(
2750 struct bus_container *c,
2751 const char *contents,
2752 uint32_t **array_size) {
2763 if (!signature_is_single(contents, true))
2766 alignment = bus_type_get_alignment(contents[0]);
2770 if (!c->signature || c->signature[c->index] == 0)
2773 if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
2776 if (!startswith(c->signature + c->index + 1, contents))
2780 r = message_peek_body(m, &rindex, 4, 4, &q);
2784 if (BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q) > BUS_ARRAY_MAX_SIZE)
2787 r = message_peek_body(m, &rindex, alignment, 0, NULL);
2793 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2794 c->index += 1 + strlen(contents);
2798 *array_size = (uint32_t*) q;
2803 static int bus_message_enter_variant(
2805 struct bus_container *c,
2806 const char *contents) {
2817 if (!signature_is_single(contents, false))
2820 if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
2823 if (!c->signature || c->signature[c->index] == 0)
2826 if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
2830 r = message_peek_body(m, &rindex, 1, 1, &q);
2835 r = message_peek_body(m, &rindex, 1, l+1, &q);
2841 if (!validate_signature(q, l))
2844 if (!streq(q, contents))
2847 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2855 static int bus_message_enter_struct(
2857 struct bus_container *c,
2858 const char *contents) {
2867 if (!signature_is_valid(contents, false))
2870 if (!c->signature || c->signature[c->index] == 0)
2873 l = strlen(contents);
2875 if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
2876 !startswith(c->signature + c->index + 1, contents) ||
2877 c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
2880 r = message_peek_body(m, &m->rindex, 8, 0, NULL);
2884 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2885 c->index += 1 + l + 1;
2890 static int bus_message_enter_dict_entry(
2892 struct bus_container *c,
2893 const char *contents) {
2902 if (!signature_is_pair(contents))
2905 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2908 if (!c->signature || c->signature[c->index] == 0)
2911 l = strlen(contents);
2913 if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
2914 !startswith(c->signature + c->index + 1, contents) ||
2915 c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
2918 r = message_peek_body(m, &m->rindex, 8, 0, NULL);
2922 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2923 c->index += 1 + l + 1;
2928 int sd_bus_message_enter_container(sd_bus_message *m, char type, const char *contents) {
2929 struct bus_container *c, *w;
2930 uint32_t *array_size = NULL;
2943 * We enforce a global limit on container depth, that is much
2944 * higher than the 32 structs and 32 arrays the specification
2945 * mandates. This is simpler to implement for us, and we need
2946 * this only to ensure our container array doesn't grow
2947 * without bounds. We are happy to return any data from a
2948 * message as long as the data itself is valid, even if the
2949 * overall message might be not.
2951 * Note that the message signature is validated when
2952 * parsing the headers, and that validation does check the
2955 * Note that the specification defines no limits on the depth
2956 * of stacked variants, but we do.
2958 if (m->n_containers >= BUS_CONTAINER_DEPTH)
2961 w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
2966 c = message_get_container(m);
2968 if (!c->signature || c->signature[c->index] == 0)
2971 signature = strdup(contents);
2975 c->saved_index = c->index;
2978 if (type == SD_BUS_TYPE_ARRAY)
2979 r = bus_message_enter_array(m, c, contents, &array_size);
2980 else if (type == SD_BUS_TYPE_VARIANT)
2981 r = bus_message_enter_variant(m, c, contents);
2982 else if (type == SD_BUS_TYPE_STRUCT)
2983 r = bus_message_enter_struct(m, c, contents);
2984 else if (type == SD_BUS_TYPE_DICT_ENTRY)
2985 r = bus_message_enter_dict_entry(m, c, contents);
2994 /* OK, let's fill it in */
2995 w += m->n_containers++;
2996 w->enclosing = type;
2997 w->signature = signature;
2999 w->array_size = array_size;
3001 w->begin = m->rindex;
3006 int sd_bus_message_exit_container(sd_bus_message *m) {
3007 struct bus_container *c;
3013 if (m->n_containers <= 0)
3016 c = message_get_container(m);
3017 if (c->enclosing == SD_BUS_TYPE_ARRAY) {
3020 l = BUS_MESSAGE_BSWAP32(m, *c->array_size);
3021 if (c->begin + l != m->rindex)
3025 if (c->signature && c->signature[c->index] != 0)
3035 static void message_quit_container(sd_bus_message *m) {
3036 struct bus_container *c;
3040 assert(m->n_containers > 0);
3042 c = message_get_container(m);
3045 assert(m->rindex >= c->before);
3046 m->rindex = c->before;
3048 /* Free container */
3052 /* Correct index of new top-level container */
3053 c = message_get_container(m);
3054 c->index = c->saved_index;
3057 int sd_bus_message_peek_type(sd_bus_message *m, char *type, const char **contents) {
3058 struct bus_container *c;
3066 c = message_get_container(m);
3068 if (!c->signature || c->signature[c->index] == 0)
3071 if (message_end_of_array(m, m->rindex))
3074 if (bus_type_is_basic(c->signature[c->index])) {
3078 *type = c->signature[c->index];
3082 if (c->signature[c->index] == SD_BUS_TYPE_ARRAY) {
3088 r = signature_element_length(c->signature+c->index+1, &l);
3094 sig = strndup(c->signature + c->index + 1, l);
3098 free(m->peeked_signature);
3099 m->peeked_signature = sig;
3105 *type = SD_BUS_TYPE_ARRAY;
3110 if (c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ||
3111 c->signature[c->index] == SD_BUS_TYPE_DICT_ENTRY_BEGIN) {
3117 r = signature_element_length(c->signature+c->index, &l);
3122 sig = strndup(c->signature + c->index + 1, l - 2);
3126 free(m->peeked_signature);
3127 m->peeked_signature = sig;
3133 *type = c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY;
3138 if (c->signature[c->index] == SD_BUS_TYPE_VARIANT) {
3144 r = message_peek_body(m, &rindex, 1, 1, &q);
3151 r = message_peek_body(m, &rindex, 1, l+1, &q);
3157 if (!validate_signature(q, l))
3164 *type = SD_BUS_TYPE_VARIANT;
3173 *type = c->enclosing;
3179 int sd_bus_message_rewind(sd_bus_message *m, int complete) {
3180 struct bus_container *c;
3188 message_reset_containers(m);
3190 m->root_container.index = 0;
3192 c = message_get_container(m);
3194 c = message_get_container(m);
3197 m->rindex = c->begin;
3200 return !isempty(c->signature);
3202 static int message_read_ap(
3207 unsigned n_array, n_struct;
3208 TypeStack stack[BUS_CONTAINER_DEPTH];
3209 unsigned stack_ptr = 0;
3217 /* Ideally, we'd just call ourselves recursively on every
3218 * complex type. However, the state of a va_list that is
3219 * passed to a function is undefined after that function
3220 * returns. This means we need to docode the va_list linearly
3221 * in a single stackframe. We hence implement our own
3222 * home-grown stack in an array. */
3224 n_array = (unsigned) -1;
3225 n_struct = strlen(types);
3230 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
3231 r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
3237 r = sd_bus_message_exit_container(m);
3245 if (n_array != (unsigned) -1)
3254 case SD_BUS_TYPE_BYTE:
3255 case SD_BUS_TYPE_BOOLEAN:
3256 case SD_BUS_TYPE_INT16:
3257 case SD_BUS_TYPE_UINT16:
3258 case SD_BUS_TYPE_INT32:
3259 case SD_BUS_TYPE_UINT32:
3260 case SD_BUS_TYPE_INT64:
3261 case SD_BUS_TYPE_UINT64:
3262 case SD_BUS_TYPE_DOUBLE:
3263 case SD_BUS_TYPE_STRING:
3264 case SD_BUS_TYPE_OBJECT_PATH:
3265 case SD_BUS_TYPE_SIGNATURE:
3266 case SD_BUS_TYPE_UNIX_FD: {
3269 p = va_arg(ap, void*);
3270 r = sd_bus_message_read_basic(m, *t, p);
3279 case SD_BUS_TYPE_ARRAY: {
3282 r = signature_element_length(t + 1, &k);
3288 memcpy(s, t + 1, k);
3291 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, s);
3298 if (n_array == (unsigned) -1) {
3303 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
3309 n_array = va_arg(ap, unsigned);
3314 case SD_BUS_TYPE_VARIANT: {
3317 s = va_arg(ap, const char *);
3321 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, s);
3327 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
3332 n_struct = strlen(s);
3333 n_array = (unsigned) -1;
3338 case SD_BUS_TYPE_STRUCT_BEGIN:
3339 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
3342 r = signature_element_length(t, &k);
3348 memcpy(s, t + 1, k - 2);
3351 r = sd_bus_message_enter_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
3358 if (n_array == (unsigned) -1) {
3363 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
3369 n_array = (unsigned) -1;
3382 int sd_bus_message_read(sd_bus_message *m, const char *types, ...) {
3393 va_start(ap, types);
3394 r = message_read_ap(m, types, ap);
3400 int sd_bus_message_read_array(sd_bus_message *m, char type, const void **ptr, size_t *size) {
3401 struct bus_container *c;
3411 if (!bus_type_is_trivial(type))
3417 if (BUS_MESSAGE_NEED_BSWAP(m))
3420 align = bus_type_get_alignment(type);
3424 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
3428 c = message_get_container(m);
3429 sz = BUS_MESSAGE_BSWAP32(m, *c->array_size);
3431 r = message_peek_body(m, &m->rindex, align, sz, &p);
3439 r = sd_bus_message_exit_container(m);
3443 *ptr = (const void*) p;
3449 message_quit_container(m);
3453 static int message_peek_fields(
3464 return buffer_peek(BUS_MESSAGE_FIELDS(m), BUS_MESSAGE_FIELDS_SIZE(m), rindex, align, nbytes, ret);
3467 static int message_peek_field_uint32(
3478 r = message_peek_fields(m, ri, 4, 4, &q);
3483 *ret = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
3488 static int message_peek_field_string(
3490 bool (*validate)(const char *p),
3501 r = message_peek_field_uint32(m, ri, &l);
3505 r = message_peek_fields(m, ri, 1, l+1, &q);
3510 if (!validate_nul(q, l))
3516 if (!validate_string(q, l))
3526 static int message_peek_field_signature(
3538 r = message_peek_fields(m, ri, 1, 1, &q);
3543 r = message_peek_fields(m, ri, 1, l+1, &q);
3547 if (!validate_signature(q, l))
3556 static int message_skip_fields(
3559 uint32_t array_size,
3560 const char **signature) {
3562 size_t original_index;
3569 original_index = *ri;
3575 if (array_size != (uint32_t) -1 &&
3576 array_size <= *ri - original_index)
3583 if (t == SD_BUS_TYPE_STRING) {
3585 r = message_peek_field_string(m, NULL, ri, NULL);
3591 } else if (t == SD_BUS_TYPE_OBJECT_PATH) {
3593 r = message_peek_field_string(m, object_path_is_valid, ri, NULL);
3599 } else if (t == SD_BUS_TYPE_SIGNATURE) {
3601 r = message_peek_field_signature(m, ri, NULL);
3607 } else if (bus_type_is_basic(t)) {
3610 align = bus_type_get_alignment(t);
3611 k = bus_type_get_size(t);
3612 assert(align > 0 && k > 0);
3614 r = message_peek_fields(m, ri, align, k, NULL);
3620 } else if (t == SD_BUS_TYPE_ARRAY) {
3622 r = signature_element_length(*signature+1, &l);
3632 strncpy(sig, *signature + 1, l-1);
3635 alignment = bus_type_get_alignment(sig[0]);
3639 r = message_peek_field_uint32(m, ri, &nas);
3642 if (nas > BUS_ARRAY_MAX_SIZE)
3645 r = message_peek_fields(m, ri, alignment, 0, NULL);
3649 r = message_skip_fields(m, ri, nas, (const char**) &s);
3654 (*signature) += 1 + l;
3656 } else if (t == SD_BUS_TYPE_VARIANT) {
3659 r = message_peek_field_signature(m, ri, &s);
3663 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
3669 } else if (t == SD_BUS_TYPE_STRUCT ||
3670 t == SD_BUS_TYPE_DICT_ENTRY) {
3672 r = signature_element_length(*signature, &l);
3679 strncpy(sig, *signature + 1, l-1);
3682 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
3693 int bus_message_parse_fields(sd_bus_message *m) {
3696 uint32_t unix_fds = 0;
3700 for (ri = 0; ri < BUS_MESSAGE_FIELDS_SIZE(m); ) {
3701 const char *signature;
3704 r = message_peek_fields(m, &ri, 8, 1, (void**) &header);
3708 r = message_peek_field_signature(m, &ri, &signature);
3713 case _SD_BUS_MESSAGE_HEADER_INVALID:
3716 case SD_BUS_MESSAGE_HEADER_PATH:
3721 if (!streq(signature, "o"))
3724 r = message_peek_field_string(m, object_path_is_valid, &ri, &m->path);
3727 case SD_BUS_MESSAGE_HEADER_INTERFACE:
3732 if (!streq(signature, "s"))
3735 r = message_peek_field_string(m, interface_name_is_valid, &ri, &m->interface);
3738 case SD_BUS_MESSAGE_HEADER_MEMBER:
3743 if (!streq(signature, "s"))
3746 r = message_peek_field_string(m, member_name_is_valid, &ri, &m->member);
3749 case SD_BUS_MESSAGE_HEADER_ERROR_NAME:
3754 if (!streq(signature, "s"))
3757 r = message_peek_field_string(m, error_name_is_valid, &ri, &m->error.name);
3760 case SD_BUS_MESSAGE_HEADER_DESTINATION:
3765 if (!streq(signature, "s"))
3768 r = message_peek_field_string(m, service_name_is_valid, &ri, &m->destination);
3771 case SD_BUS_MESSAGE_HEADER_SENDER:
3776 if (!streq(signature, "s"))
3779 r = message_peek_field_string(m, service_name_is_valid, &ri, &m->sender);
3783 case SD_BUS_MESSAGE_HEADER_SIGNATURE: {
3787 if (m->root_container.signature)
3790 if (!streq(signature, "g"))
3793 r = message_peek_field_signature(m, &ri, &s);
3801 free(m->root_container.signature);
3802 m->root_container.signature = c;
3806 case SD_BUS_MESSAGE_HEADER_REPLY_SERIAL:
3807 if (m->reply_serial != 0)
3810 if (!streq(signature, "u"))
3813 r = message_peek_field_uint32(m, &ri, &m->reply_serial);
3817 if (m->reply_serial == 0)
3822 case SD_BUS_MESSAGE_HEADER_UNIX_FDS:
3826 if (!streq(signature, "u"))
3829 r = message_peek_field_uint32(m, &ri, &unix_fds);
3839 r = message_skip_fields(m, &ri, (uint32_t) -1, (const char **) &signature);
3846 if (m->n_fds != unix_fds)
3849 if (isempty(m->root_container.signature) != (BUS_MESSAGE_BODY_SIZE(m) == 0))
3852 switch (m->header->type) {
3854 case SD_BUS_MESSAGE_TYPE_SIGNAL:
3855 if (!m->path || !m->interface || !m->member)
3859 case SD_BUS_MESSAGE_TYPE_METHOD_CALL:
3861 if (!m->path || !m->member)
3866 case SD_BUS_MESSAGE_TYPE_METHOD_RETURN:
3868 if (m->reply_serial == 0)
3872 case SD_BUS_MESSAGE_TYPE_METHOD_ERROR:
3874 if (m->reply_serial == 0 || !m->error.name)
3879 /* Try to read the error message, but if we can't it's a non-issue */
3880 if (m->header->type == SD_BUS_MESSAGE_TYPE_METHOD_ERROR)
3881 sd_bus_message_read(m, "s", &m->error.message);
3886 int bus_message_seal(sd_bus_message *m, uint64_t serial) {
3887 struct bus_body_part *part;
3897 if (m->n_containers > 0)
3903 /* If there's a non-trivial signature set, then add it in here */
3904 if (!isempty(m->root_container.signature)) {
3905 r = message_append_field_signature(m, SD_BUS_MESSAGE_HEADER_SIGNATURE, m->root_container.signature, NULL);
3911 r = message_append_field_uint32(m, SD_BUS_MESSAGE_HEADER_UNIX_FDS, m->n_fds);
3916 /* Add padding at the end of the fields part, since we know
3917 * the body needs to start at an 8 byte alignment. We made
3918 * sure we allocated enough space for this, so all we need to
3919 * do here is to zero it out. */
3920 l = BUS_MESSAGE_FIELDS_SIZE(m);
3923 memset((uint8_t*) BUS_MESSAGE_FIELDS(m) + l, 0, a);
3925 /* If this is something we can send as memfd, then let's seal
3926 the memfd now. Note that we can send memfds as payload only
3927 for directed messages, and not for broadcasts. */
3928 if (m->destination && m->bus && m->bus->use_memfd) {
3929 MESSAGE_FOREACH_PART(part, i, m)
3930 if (part->memfd >= 0 && !part->sealed && (part->size > MEMFD_MIN_SIZE || m->bus->use_memfd < 0)) {
3931 bus_body_part_unmap(part);
3933 if (ioctl(part->memfd, KDBUS_CMD_MEMFD_SEAL_SET, 1) >= 0)
3934 part->sealed = true;
3938 m->header->serial = serial;
3944 int sd_bus_message_set_destination(sd_bus_message *m, const char *destination) {
3954 return message_append_field_string(m, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &m->destination);
3957 int bus_message_dump(sd_bus_message *m) {
3958 const char *u = NULL, *uu = NULL, *s = NULL;
3959 char **cmdline = NULL;
3962 uid_t owner, audit_loginuid;
3963 uint32_t audit_sessionid;
3967 printf("Message %p\n"
3974 "\tfields_size=%u\n"
3979 "\tdestination=%s\n"
3982 "\treply_serial=%u\n"
3984 "\terror.message=%s\n"
3986 "\tn_body_parts=%u\n",
3993 BUS_MESSAGE_SERIAL(m),
3994 BUS_MESSAGE_FIELDS_SIZE(m),
3995 BUS_MESSAGE_BODY_SIZE(m),
3997 strna(m->interface),
3999 strna(m->destination),
4001 strna(m->root_container.signature),
4003 strna(m->error.name),
4004 strna(m->error.message),
4009 printf("\tpid=%lu\n", (unsigned long) m->pid);
4011 printf("\ttid=%lu\n", (unsigned long) m->tid);
4013 printf("\tuid=%lu\n", (unsigned long) m->uid);
4015 printf("\tgid=%lu\n", (unsigned long) m->gid);
4016 if (m->pid_starttime != 0)
4017 printf("\tpid_starttime=%llu\n", (unsigned long long) m->pid_starttime);
4018 if (m->monotonic != 0)
4019 printf("\tmonotonic=%llu\n", (unsigned long long) m->monotonic);
4020 if (m->realtime != 0)
4021 printf("\trealtime=%llu\n", (unsigned long long) m->realtime);
4023 printf("\texe=[%s]\n", m->exe);
4025 printf("\tcomm=[%s]\n", m->comm);
4027 printf("\ttid_comm=[%s]\n", m->tid_comm);
4029 printf("\tlabel=[%s]\n", m->label);
4031 printf("\tcgroup=[%s]\n", m->cgroup);
4033 sd_bus_message_get_unit(m, &u);
4035 printf("\tunit=[%s]\n", u);
4036 sd_bus_message_get_user_unit(m, &uu);
4038 printf("\tuser_unit=[%s]\n", uu);
4039 sd_bus_message_get_session(m, &s);
4041 printf("\tsession=[%s]\n", s);
4042 if (sd_bus_message_get_owner_uid(m, &owner) >= 0)
4043 printf("\towner_uid=%lu\n", (unsigned long) owner);
4044 if (sd_bus_message_get_audit_loginuid(m, &audit_loginuid) >= 0)
4045 printf("\taudit_loginuid=%lu\n", (unsigned long) audit_loginuid);
4046 if (sd_bus_message_get_audit_sessionid(m, &audit_sessionid) >= 0)
4047 printf("\taudit_sessionid=%lu\n", (unsigned long) audit_sessionid);
4049 printf("\tCAP_KILL=%i\n", sd_bus_message_has_effective_cap(m, 5));
4051 if (sd_bus_message_get_cmdline(m, &cmdline) >= 0) {
4054 fputs("\tcmdline=[", stdout);
4055 STRV_FOREACH(c, cmdline) {
4062 fputs("]\n", stdout);
4065 r = sd_bus_message_rewind(m, true);
4067 log_error("Failed to rewind: %s", strerror(-r));
4071 printf("BEGIN_MESSAGE \"%s\" {\n", strempty(m->root_container.signature));
4074 _cleanup_free_ char *prefix = NULL;
4075 const char *contents = NULL;
4090 r = sd_bus_message_peek_type(m, &type, &contents);
4092 log_error("Failed to peek type: %s", strerror(-r));
4099 r = sd_bus_message_exit_container(m);
4101 log_error("Failed to exit container: %s", strerror(-r));
4107 prefix = strrep("\t", level);
4111 if (type == SD_BUS_TYPE_ARRAY)
4112 printf("%s} END_ARRAY \n", prefix);
4113 else if (type == SD_BUS_TYPE_VARIANT)
4114 printf("%s} END_VARIANT\n", prefix);
4115 else if (type == SD_BUS_TYPE_STRUCT)
4116 printf("%s} END_STRUCT\n", prefix);
4117 else if (type == SD_BUS_TYPE_DICT_ENTRY)
4118 printf("%s} END_DICT_ENTRY\n", prefix);
4123 prefix = strrep("\t", level);
4127 if (bus_type_is_container(type) > 0) {
4128 r = sd_bus_message_enter_container(m, type, contents);
4130 log_error("Failed to enter container: %s", strerror(-r));
4134 if (type == SD_BUS_TYPE_ARRAY)
4135 printf("%sBEGIN_ARRAY \"%s\" {\n", prefix, contents);
4136 else if (type == SD_BUS_TYPE_VARIANT)
4137 printf("%sBEGIN_VARIANT \"%s\" {\n", prefix, contents);
4138 else if (type == SD_BUS_TYPE_STRUCT)
4139 printf("%sBEGIN_STRUCT \"%s\" {\n", prefix, contents);
4140 else if (type == SD_BUS_TYPE_DICT_ENTRY)
4141 printf("%sBEGIN_DICT_ENTRY \"%s\" {\n", prefix, contents);
4148 r = sd_bus_message_read_basic(m, type, &basic);
4150 log_error("Failed to get basic: %s", strerror(-r));
4156 case SD_BUS_TYPE_BYTE:
4157 printf("%sBYTE: %u\n", prefix, basic.u8);
4160 case SD_BUS_TYPE_BOOLEAN:
4161 printf("%sBOOLEAN: %s\n", prefix, yes_no(basic.i));
4164 case SD_BUS_TYPE_INT16:
4165 printf("%sINT16: %i\n", prefix, basic.s16);
4168 case SD_BUS_TYPE_UINT16:
4169 printf("%sUINT16: %u\n", prefix, basic.u16);
4172 case SD_BUS_TYPE_INT32:
4173 printf("%sINT32: %i\n", prefix, basic.s32);
4176 case SD_BUS_TYPE_UINT32:
4177 printf("%sUINT32: %u\n", prefix, basic.u32);
4180 case SD_BUS_TYPE_INT64:
4181 printf("%sINT64: %lli\n", prefix, (long long) basic.s64);
4184 case SD_BUS_TYPE_UINT64:
4185 printf("%sUINT64: %llu\n", prefix, (unsigned long long) basic.u64);
4188 case SD_BUS_TYPE_DOUBLE:
4189 printf("%sDOUBLE: %g\n", prefix, basic.d64);
4192 case SD_BUS_TYPE_STRING:
4193 printf("%sSTRING: \"%s\"\n", prefix, basic.string);
4196 case SD_BUS_TYPE_OBJECT_PATH:
4197 printf("%sOBJECT_PATH: \"%s\"\n", prefix, basic.string);
4200 case SD_BUS_TYPE_SIGNATURE:
4201 printf("%sSIGNATURE: \"%s\"\n", prefix, basic.string);
4204 case SD_BUS_TYPE_UNIX_FD:
4205 printf("%sUNIX_FD: %i\n", prefix, basic.i);
4209 assert_not_reached("Unknown basic type.");
4213 printf("} END_MESSAGE\n");
4217 int bus_message_get_blob(sd_bus_message *m, void **buffer, size_t *sz) {
4221 struct bus_body_part *part;
4227 total = BUS_MESSAGE_SIZE(m);
4233 e = mempcpy(p, m->header, BUS_MESSAGE_BODY_BEGIN(m));
4234 MESSAGE_FOREACH_PART(part, i, m)
4235 e = mempcpy(e, part->data, part->size);
4237 assert(total == (size_t) ((uint8_t*) e - (uint8_t*) p));
4245 int bus_message_read_strv_extend(sd_bus_message *m, char ***l) {
4251 r = sd_bus_message_enter_container(m, 'a', "s");
4258 r = sd_bus_message_read_basic(m, 's', &s);
4264 r = strv_extend(l, s);
4269 r = sd_bus_message_exit_container(m);
4276 const char* bus_message_get_arg(sd_bus_message *m, unsigned i) {
4278 const char *t = NULL;
4283 r = sd_bus_message_rewind(m, true);
4287 for (j = 0; j <= i; j++) {
4290 r = sd_bus_message_peek_type(m, &type, NULL);
4294 if (type != SD_BUS_TYPE_STRING &&
4295 type != SD_BUS_TYPE_OBJECT_PATH &&
4296 type != SD_BUS_TYPE_SIGNATURE)
4299 r = sd_bus_message_read_basic(m, type, &t);
4307 bool bus_header_is_complete(struct bus_header *h, size_t size) {
4313 if (size < sizeof(struct bus_header))
4316 full = sizeof(struct bus_header) +
4317 (h->endian == SD_BUS_NATIVE_ENDIAN ? h->fields_size : bswap_32(h->fields_size));
4319 return size >= full;
4322 int bus_header_message_size(struct bus_header *h, size_t *sum) {
4328 if (h->endian == SD_BUS_NATIVE_ENDIAN) {
4329 fs = h->fields_size;
4331 } else if (h->endian == SD_BUS_REVERSE_ENDIAN) {
4332 fs = bswap_32(h->fields_size);
4333 bs = bswap_32(h->body_size);
4337 *sum = sizeof(struct bus_header) + ALIGN8(fs) + bs;
4341 int bus_message_to_errno(sd_bus_message *m) {
4344 if (m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_ERROR)
4347 return bus_error_to_errno(&m->error);
4350 int sd_bus_message_get_signature(sd_bus_message *m, int complete, const char **signature) {
4351 struct bus_container *c;
4358 c = complete ? &m->root_container : message_get_container(m);
4359 *signature = c->signature ?: "";