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,
651 r = message_new_reply(bus, call, SD_BUS_MESSAGE_TYPE_METHOD_ERROR, &t);
655 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_ERROR_NAME, SD_BUS_TYPE_STRING, name, &t->error.name);
660 _cleanup_free_ char *message = NULL;
662 va_start(ap, format);
663 r = vasprintf(&message, format, ap);
671 r = message_append_basic(t, SD_BUS_TYPE_STRING, message, (const void**) &t->error.message);
684 int bus_message_new_synthetic_error(
687 const sd_bus_error *e,
688 sd_bus_message **m) {
693 assert(sd_bus_error_is_set(e));
696 t = message_new(bus, SD_BUS_MESSAGE_TYPE_METHOD_ERROR);
700 t->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
701 t->reply_serial = serial;
703 r = message_append_field_uint32(t, SD_BUS_MESSAGE_HEADER_REPLY_SERIAL, t->reply_serial);
707 if (bus && bus->unique_name) {
708 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, bus->unique_name, &t->destination);
713 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_ERROR_NAME, SD_BUS_TYPE_STRING, e->name, &t->error.name);
718 r = message_append_basic(t, SD_BUS_TYPE_STRING, e->message, (const void**) &t->error.message);
731 sd_bus_message* sd_bus_message_ref(sd_bus_message *m) {
735 assert(m->n_ref > 0);
741 sd_bus_message* sd_bus_message_unref(sd_bus_message *m) {
745 assert(m->n_ref > 0);
754 int sd_bus_message_get_type(sd_bus_message *m, uint8_t *type) {
760 *type = m->header->type;
764 int sd_bus_message_get_serial(sd_bus_message *m, uint64_t *serial) {
769 if (m->header->serial == 0)
772 *serial = BUS_MESSAGE_SERIAL(m);
776 int sd_bus_message_get_reply_serial(sd_bus_message *m, uint64_t *serial) {
781 if (m->reply_serial == 0)
784 *serial = m->reply_serial;
788 int sd_bus_message_get_no_reply(sd_bus_message *m) {
792 return m->header->type == SD_BUS_MESSAGE_TYPE_METHOD_CALL ? !!(m->header->flags & SD_BUS_MESSAGE_NO_REPLY_EXPECTED) : 0;
795 const char *sd_bus_message_get_path(sd_bus_message *m) {
802 const char *sd_bus_message_get_interface(sd_bus_message *m) {
809 const char *sd_bus_message_get_member(sd_bus_message *m) {
815 const char *sd_bus_message_get_destination(sd_bus_message *m) {
819 return m->destination;
822 const char *sd_bus_message_get_sender(sd_bus_message *m) {
829 const sd_bus_error *sd_bus_message_get_error(sd_bus_message *m) {
833 if (!sd_bus_error_is_set(&m->error))
839 int sd_bus_message_get_uid(sd_bus_message *m, uid_t *uid) {
851 int sd_bus_message_get_gid(sd_bus_message *m, gid_t *gid) {
863 int sd_bus_message_get_pid(sd_bus_message *m, pid_t *pid) {
875 int sd_bus_message_get_tid(sd_bus_message *m, pid_t *tid) {
887 int sd_bus_message_get_pid_starttime(sd_bus_message *m, uint64_t *usec) {
892 if (m->pid_starttime <= 0)
895 *usec = m->pid_starttime;
899 int sd_bus_message_get_selinux_context(sd_bus_message *m, const char **ret) {
909 int sd_bus_message_get_monotonic_timestamp(sd_bus_message *m, uint64_t *usec) {
914 if (m->monotonic <= 0)
917 *usec = m->monotonic;
921 int sd_bus_message_get_realtime_timestamp(sd_bus_message *m, uint64_t *usec) {
926 if (m->realtime <= 0)
933 int sd_bus_message_get_comm(sd_bus_message *m, const char **ret) {
945 int sd_bus_message_get_tid_comm(sd_bus_message *m, const char **ret) {
957 int sd_bus_message_get_exe(sd_bus_message *m, const char **ret) {
969 int sd_bus_message_get_cgroup(sd_bus_message *m, const char **ret) {
981 int sd_bus_message_get_unit(sd_bus_message *m, const char **ret) {
992 r = cg_path_get_unit(m->cgroup, &m->unit);
1001 int sd_bus_message_get_user_unit(sd_bus_message *m, const char **ret) {
1011 if (!m->user_unit) {
1012 r = cg_path_get_user_unit(m->cgroup, &m->user_unit);
1017 *ret = m->user_unit;
1021 int sd_bus_message_get_session(sd_bus_message *m, const char **ret) {
1032 r = cg_path_get_session(m->cgroup, &m->session);
1041 int sd_bus_message_get_owner_uid(sd_bus_message *m, uid_t *uid) {
1049 return cg_path_get_owner_uid(m->cgroup, uid);
1052 int sd_bus_message_get_cmdline(sd_bus_message *m, char ***cmdline) {
1063 for (p = m->cmdline, n = 0; p < m->cmdline + m->cmdline_length; p++)
1067 m->cmdline_array = new(char*, n + 1);
1068 if (!m->cmdline_array)
1071 for (p = m->cmdline, i = 0, first = true; p < m->cmdline + m->cmdline_length; p++) {
1073 m->cmdline_array[i++] = (char*) p;
1078 m->cmdline_array[i] = NULL;
1079 *cmdline = m->cmdline_array;
1084 int sd_bus_message_get_audit_sessionid(sd_bus_message *m, uint32_t *sessionid) {
1092 *sessionid = m->audit->sessionid;
1096 int sd_bus_message_get_audit_loginuid(sd_bus_message *m, uid_t *uid) {
1104 *uid = m->audit->loginuid;
1108 int sd_bus_message_has_effective_cap(sd_bus_message *m, int capability) {
1118 sz = m->capability_size / 4;
1119 if ((unsigned) capability >= sz*8)
1122 return !!(m->capability[2 * sz + (capability / 8)] & (1 << (capability % 8)));
1125 int sd_bus_message_is_signal(sd_bus_message *m, const char *interface, const char *member) {
1129 if (m->header->type != SD_BUS_MESSAGE_TYPE_SIGNAL)
1132 if (interface && (!m->interface || !streq(m->interface, interface)))
1135 if (member && (!m->member || !streq(m->member, member)))
1141 int sd_bus_message_is_method_call(sd_bus_message *m, const char *interface, const char *member) {
1145 if (m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_CALL)
1148 if (interface && (!m->interface || !streq(m->interface, interface)))
1151 if (member && (!m->member || !streq(m->member, member)))
1157 int sd_bus_message_is_method_error(sd_bus_message *m, const char *name) {
1161 if (m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_ERROR)
1164 if (name && (!m->error.name || !streq(m->error.name, name)))
1170 int sd_bus_message_set_no_reply(sd_bus_message *m, int b) {
1175 if (m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_CALL)
1179 m->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
1181 m->header->flags &= ~SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
1186 static struct bus_container *message_get_container(sd_bus_message *m) {
1189 if (m->n_containers == 0)
1190 return &m->root_container;
1192 assert(m->containers);
1193 return m->containers + m->n_containers - 1;
1196 struct bus_body_part *message_append_part(sd_bus_message *m) {
1197 struct bus_body_part *part;
1204 if (m->n_body_parts <= 0) {
1208 assert(m->body_end);
1210 part = new0(struct bus_body_part, 1);
1216 m->body_end->next = part;
1226 static void part_zero(struct bus_body_part *part, size_t sz) {
1231 /* All other fields can be left in their defaults */
1232 assert(!part->data);
1233 assert(part->memfd < 0);
1236 part->is_zero = true;
1237 part->sealed = true;
1240 static int part_make_space(
1241 struct sd_bus_message *m,
1242 struct bus_body_part *part,
1251 assert(!part->sealed);
1256 if (!part->data && part->memfd < 0)
1257 part->memfd = bus_kernel_pop_memfd(m->bus, &part->data, &part->mapped);
1259 if (part->memfd >= 0) {
1262 r = ioctl(part->memfd, KDBUS_CMD_MEMFD_SIZE_SET, &u);
1268 if (!part->data || sz > part->mapped) {
1269 size_t psz = PAGE_ALIGN(sz > 0 ? sz : 1);
1271 if (part->mapped <= 0)
1272 n = mmap(NULL, psz, PROT_READ|PROT_WRITE, MAP_SHARED, part->memfd, 0);
1274 n = mremap(part->data, part->mapped, psz, MREMAP_MAYMOVE);
1276 if (n == MAP_FAILED) {
1285 part->munmap_this = true;
1287 n = realloc(part->data, sz);
1294 part->free_this = true;
1298 *q = part->data ? (uint8_t*) part->data + part->size : NULL;
1304 static void message_extend_containers(sd_bus_message *m, size_t expand) {
1305 struct bus_container *c;
1312 /* Update counters */
1313 for (c = m->containers; c < m->containers + m->n_containers; c++)
1315 *c->array_size += expand;
1318 static void *message_extend_body(sd_bus_message *m, size_t align, size_t sz) {
1319 struct bus_body_part *part = NULL;
1320 size_t start_body, end_body, padding, start_part, end_part, added;
1332 start_body = ALIGN_TO((size_t) m->header->body_size, align);
1333 end_body = start_body + sz;
1335 padding = start_body - m->header->body_size;
1336 added = padding + sz;
1338 /* Check for 32bit overflows */
1339 if (end_body > (size_t) ((uint32_t) -1)) {
1345 m->n_body_parts <= 0 ||
1346 m->body_end->sealed ||
1347 padding != ALIGN_TO(m->body_end->size, align) - m->body_end->size;
1351 part = message_append_part(m);
1355 part_zero(part, padding);
1358 part = message_append_part(m);
1362 r = part_make_space(m, part, sz, &p);
1366 struct bus_container *c;
1374 start_part = ALIGN_TO(part->size, align);
1375 end_part = start_part + sz;
1377 r = part_make_space(m, part, end_part, &p);
1382 memset(p, 0, padding);
1383 p = (uint8_t*) p + padding;
1386 /* Readjust pointers */
1387 for (c = m->containers; c < m->containers + m->n_containers; c++)
1388 c->array_size = adjust_pointer(c->array_size, op, os, part->data);
1390 m->error.message = (const char*) adjust_pointer(m->error.message, op, os, part->data);
1393 m->header->body_size = end_body;
1394 message_extend_containers(m, added);
1399 int message_append_basic(sd_bus_message *m, char type, const void *p, const void **stored) {
1400 struct bus_container *c;
1414 if (!bus_type_is_basic(type))
1419 c = message_get_container(m);
1421 if (c->signature && c->signature[c->index]) {
1422 /* Container signature is already set */
1424 if (c->signature[c->index] != type)
1429 /* Maybe we can append to the signature? But only if this is the top-level container*/
1430 if (c->enclosing != 0)
1433 e = strextend(&c->signature, CHAR_TO_STR(type), NULL);
1442 case SD_BUS_TYPE_STRING:
1443 case SD_BUS_TYPE_OBJECT_PATH:
1446 sz = 4 + strlen(p) + 1;
1449 case SD_BUS_TYPE_SIGNATURE:
1452 sz = 1 + strlen(p) + 1;
1455 case SD_BUS_TYPE_BOOLEAN:
1458 assert_cc(sizeof(int) == sizeof(uint32_t));
1464 case SD_BUS_TYPE_UNIX_FD: {
1467 if (!m->allow_fds) {
1480 fd = fcntl(z, F_DUPFD_CLOEXEC, 3);
1486 f = realloc(m->fds, sizeof(int) * (m->n_fds + 1));
1501 align = bus_type_get_alignment(type);
1502 sz = bus_type_get_size(type);
1509 a = message_extend_body(m, align, sz);
1515 if (type == SD_BUS_TYPE_STRING || type == SD_BUS_TYPE_OBJECT_PATH) {
1516 *(uint32_t*) a = sz - 5;
1517 memcpy((uint8_t*) a + 4, p, sz - 4);
1520 *stored = (const uint8_t*) a + 4;
1522 } else if (type == SD_BUS_TYPE_SIGNATURE) {
1523 *(uint8_t*) a = sz - 1;
1524 memcpy((uint8_t*) a + 1, p, sz - 1);
1527 *stored = (const uint8_t*) a + 1;
1528 } else if (type == SD_BUS_TYPE_UNIX_FD) {
1529 *(uint32_t*) a = fdi;
1543 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1550 close_nointr_nofail(fd);
1555 int sd_bus_message_append_basic(sd_bus_message *m, char type, const void *p) {
1556 return message_append_basic(m, type, p, NULL);
1559 int sd_bus_message_append_string_space(sd_bus_message *m, size_t size, char **s) {
1560 struct bus_container *c;
1572 c = message_get_container(m);
1574 if (c->signature && c->signature[c->index]) {
1575 /* Container signature is already set */
1577 if (c->signature[c->index] != SD_BUS_TYPE_STRING)
1582 /* Maybe we can append to the signature? But only if this is the top-level container*/
1583 if (c->enclosing != 0)
1586 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRING), NULL);
1593 a = message_extend_body(m, 4, 4 + size + 1);
1597 *(uint32_t*) a = size;
1602 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1608 static int bus_message_open_array(
1610 struct bus_container *c,
1611 const char *contents,
1612 uint32_t **array_size) {
1618 struct bus_body_part *o;
1625 if (!signature_is_single(contents, true))
1628 alignment = bus_type_get_alignment(contents[0]);
1632 if (c->signature && c->signature[c->index]) {
1634 /* Verify the existing signature */
1636 if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
1639 if (!startswith(c->signature + c->index + 1, contents))
1642 nindex = c->index + 1 + strlen(contents);
1646 if (c->enclosing != 0)
1649 /* Extend the existing signature */
1651 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_ARRAY), contents, NULL);
1657 nindex = e - c->signature;
1660 a = message_extend_body(m, 4, 4);
1665 op = m->body_end->data;
1666 os = m->body_end->size;
1668 /* Add alignment between size and first element */
1669 if (!message_extend_body(m, alignment, 0))
1672 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1675 /* location of array size might have changed so let's readjust a */
1676 if (o == m->body_end)
1677 a = adjust_pointer(a, op, os, m->body_end->data);
1684 static int bus_message_open_variant(
1686 struct bus_container *c,
1687 const char *contents) {
1696 if (!signature_is_single(contents, false))
1699 if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
1702 if (c->signature && c->signature[c->index]) {
1704 if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
1710 if (c->enclosing != 0)
1713 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_VARIANT), NULL);
1720 l = strlen(contents);
1721 a = message_extend_body(m, 1, 1 + l + 1);
1726 memcpy((uint8_t*) a + 1, contents, l + 1);
1728 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1734 static int bus_message_open_struct(
1736 struct bus_container *c,
1737 const char *contents) {
1745 if (!signature_is_valid(contents, false))
1748 if (c->signature && c->signature[c->index]) {
1751 l = strlen(contents);
1753 if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
1754 !startswith(c->signature + c->index + 1, contents) ||
1755 c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
1758 nindex = c->index + 1 + l + 1;
1762 if (c->enclosing != 0)
1765 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_BEGIN), contents, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_END), NULL);
1771 nindex = e - c->signature;
1774 /* Align contents to 8 byte boundary */
1775 if (!message_extend_body(m, 8, 0))
1778 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1784 static int bus_message_open_dict_entry(
1786 struct bus_container *c,
1787 const char *contents) {
1795 if (!signature_is_pair(contents))
1798 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1801 if (c->signature && c->signature[c->index]) {
1804 l = strlen(contents);
1806 if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
1807 !startswith(c->signature + c->index + 1, contents) ||
1808 c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
1811 nindex = c->index + 1 + l + 1;
1815 /* Align contents to 8 byte boundary */
1816 if (!message_extend_body(m, 8, 0))
1819 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1825 int sd_bus_message_open_container(
1828 const char *contents) {
1830 struct bus_container *c, *w;
1831 uint32_t *array_size = NULL;
1845 /* Make sure we have space for one more container */
1846 w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
1854 c = message_get_container(m);
1856 signature = strdup(contents);
1862 /* Save old index in the parent container, in case we have to
1863 * abort this container */
1864 c->saved_index = c->index;
1865 before = m->header->body_size;
1867 if (type == SD_BUS_TYPE_ARRAY)
1868 r = bus_message_open_array(m, c, contents, &array_size);
1869 else if (type == SD_BUS_TYPE_VARIANT)
1870 r = bus_message_open_variant(m, c, contents);
1871 else if (type == SD_BUS_TYPE_STRUCT)
1872 r = bus_message_open_struct(m, c, contents);
1873 else if (type == SD_BUS_TYPE_DICT_ENTRY)
1874 r = bus_message_open_dict_entry(m, c, contents);
1883 /* OK, let's fill it in */
1884 w += m->n_containers++;
1885 w->enclosing = type;
1886 w->signature = signature;
1888 w->array_size = array_size;
1890 w->begin = m->rindex;
1895 int sd_bus_message_close_container(sd_bus_message *m) {
1896 struct bus_container *c;
1902 if (m->n_containers <= 0)
1907 c = message_get_container(m);
1908 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1909 if (c->signature && c->signature[c->index] != 0)
1924 static int type_stack_push(TypeStack *stack, unsigned max, unsigned *i, const char *types, unsigned n_struct, unsigned n_array) {
1931 stack[*i].types = types;
1932 stack[*i].n_struct = n_struct;
1933 stack[*i].n_array = n_array;
1939 static int type_stack_pop(TypeStack *stack, unsigned max, unsigned *i, const char **types, unsigned *n_struct, unsigned *n_array) {
1950 *types = stack[*i].types;
1951 *n_struct = stack[*i].n_struct;
1952 *n_array = stack[*i].n_array;
1957 int bus_message_append_ap(
1962 unsigned n_array, n_struct;
1963 TypeStack stack[BUS_CONTAINER_DEPTH];
1964 unsigned stack_ptr = 0;
1972 n_array = (unsigned) -1;
1973 n_struct = strlen(types);
1978 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
1979 r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
1985 r = sd_bus_message_close_container(m);
1993 if (n_array != (unsigned) -1)
2002 case SD_BUS_TYPE_BYTE: {
2005 x = (uint8_t) va_arg(ap, int);
2006 r = sd_bus_message_append_basic(m, *t, &x);
2010 case SD_BUS_TYPE_BOOLEAN:
2011 case SD_BUS_TYPE_INT32:
2012 case SD_BUS_TYPE_UINT32:
2013 case SD_BUS_TYPE_UNIX_FD: {
2016 /* We assume a boolean is the same as int32_t */
2017 assert_cc(sizeof(int32_t) == sizeof(int));
2019 x = va_arg(ap, uint32_t);
2020 r = sd_bus_message_append_basic(m, *t, &x);
2024 case SD_BUS_TYPE_INT16:
2025 case SD_BUS_TYPE_UINT16: {
2028 x = (uint16_t) va_arg(ap, int);
2029 r = sd_bus_message_append_basic(m, *t, &x);
2033 case SD_BUS_TYPE_INT64:
2034 case SD_BUS_TYPE_UINT64:
2035 case SD_BUS_TYPE_DOUBLE: {
2038 x = va_arg(ap, uint64_t);
2039 r = sd_bus_message_append_basic(m, *t, &x);
2043 case SD_BUS_TYPE_STRING:
2044 case SD_BUS_TYPE_OBJECT_PATH:
2045 case SD_BUS_TYPE_SIGNATURE: {
2048 x = va_arg(ap, const char*);
2049 r = sd_bus_message_append_basic(m, *t, x);
2053 case SD_BUS_TYPE_ARRAY: {
2056 r = signature_element_length(t + 1, &k);
2062 memcpy(s, t + 1, k);
2065 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, s);
2070 if (n_array == (unsigned) -1) {
2075 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2081 n_array = va_arg(ap, unsigned);
2086 case SD_BUS_TYPE_VARIANT: {
2089 s = va_arg(ap, const char*);
2093 r = sd_bus_message_open_container(m, SD_BUS_TYPE_VARIANT, s);
2097 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2102 n_struct = strlen(s);
2103 n_array = (unsigned) -1;
2108 case SD_BUS_TYPE_STRUCT_BEGIN:
2109 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
2112 r = signature_element_length(t, &k);
2119 memcpy(s, t + 1, k - 2);
2122 r = sd_bus_message_open_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
2127 if (n_array == (unsigned) -1) {
2132 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2138 n_array = (unsigned) -1;
2154 int sd_bus_message_append(sd_bus_message *m, const char *types, ...) {
2167 va_start(ap, types);
2168 r = bus_message_append_ap(m, types, ap);
2174 int sd_bus_message_append_array_space(sd_bus_message *m, char type, size_t size, void **ptr) {
2183 if (!bus_type_is_trivial(type))
2185 if (!ptr && size > 0)
2190 align = bus_type_get_alignment(type);
2191 sz = bus_type_get_size(type);
2193 assert_se(align > 0);
2199 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
2203 a = message_extend_body(m, align, size);
2207 r = sd_bus_message_close_container(m);
2215 int sd_bus_message_append_array(sd_bus_message *m, char type, const void *ptr, size_t size) {
2219 if (!ptr && size > 0)
2222 r = sd_bus_message_append_array_space(m, type, size, &p);
2227 memcpy(p, ptr, size);
2232 int sd_bus_message_append_array_memfd(sd_bus_message *m, char type, sd_memfd *memfd) {
2233 _cleanup_close_ int copy_fd = -1;
2234 struct bus_body_part *part;
2246 if (!bus_type_is_trivial(type))
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 align = bus_type_get_alignment(type);
2264 sz = bus_type_get_size(type);
2266 assert_se(align > 0);
2272 if (size > (uint64_t) (uint32_t) -1)
2275 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
2279 a = message_extend_body(m, align, 0);
2283 part = message_append_part(m);
2287 part->memfd = copy_fd;
2288 part->sealed = true;
2292 message_extend_containers(m, size);
2293 m->header->body_size += size;
2295 return sd_bus_message_close_container(m);
2298 int sd_bus_message_append_string_memfd(sd_bus_message *m, sd_memfd *memfd) {
2299 _cleanup_close_ int copy_fd = -1;
2300 struct bus_body_part *part;
2301 struct bus_container *c;
2306 assert_return(m, -EINVAL);
2307 assert_return(memfd, -EINVAL);
2308 assert_return(!m->sealed, -EPERM);
2309 assert_return(!m->poisoned, -ESTALE);
2311 r = sd_memfd_set_sealed(memfd, true);
2315 copy_fd = sd_memfd_dup_fd(memfd);
2319 r = sd_memfd_get_size(memfd, &size);
2323 /* We require this to be NUL terminated */
2327 if (size > (uint64_t) (uint32_t) -1)
2330 c = message_get_container(m);
2331 if (c->signature && c->signature[c->index]) {
2332 /* Container signature is already set */
2334 if (c->signature[c->index] != SD_BUS_TYPE_STRING)
2339 /* Maybe we can append to the signature? But only if this is the top-level container*/
2340 if (c->enclosing != 0)
2343 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRING), NULL);
2350 a = message_extend_body(m, 4, 4);
2354 *(uint32_t*) a = size - 1;
2356 part = message_append_part(m);
2360 part->memfd = copy_fd;
2361 part->sealed = true;
2365 message_extend_containers(m, size);
2366 m->header->body_size += size;
2368 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2374 int sd_bus_message_append_strv(sd_bus_message *m, char **l) {
2378 assert_return(m, -EINVAL);
2379 assert_return(!m->sealed, -EPERM);
2380 assert_return(!m->poisoned, -ESTALE);
2382 r = sd_bus_message_open_container(m, 'a', "s");
2386 STRV_FOREACH(i, l) {
2387 r = sd_bus_message_append_basic(m, 's', *i);
2392 return sd_bus_message_close_container(m);
2395 int bus_body_part_map(struct bus_body_part *part) {
2404 if (part->size <= 0)
2407 /* For smaller zero parts (as used for padding) we don't need to map anything... */
2408 if (part->memfd < 0 && part->is_zero && part->size < 8) {
2409 static const uint8_t zeroes[7] = { };
2410 part->data = (void*) zeroes;
2414 psz = PAGE_ALIGN(part->size);
2416 if (part->memfd >= 0)
2417 p = mmap(NULL, psz, PROT_READ, MAP_SHARED, part->memfd, 0);
2418 else if (part->is_zero)
2419 p = mmap(NULL, psz, PROT_READ, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
2423 if (p == MAP_FAILED)
2428 part->munmap_this = true;
2433 void bus_body_part_unmap(struct bus_body_part *part) {
2437 if (part->memfd < 0)
2443 if (!part->munmap_this)
2446 assert_se(munmap(part->data, part->mapped) == 0);
2450 part->munmap_this = false;
2455 static int buffer_peek(const void *p, uint32_t sz, size_t *rindex, size_t align, size_t nbytes, void **r) {
2456 size_t k, start, end;
2461 start = ALIGN_TO((size_t) *rindex, align);
2462 end = start + nbytes;
2467 /* Verify that padding is 0 */
2468 for (k = *rindex; k < start; k++)
2469 if (((const uint8_t*) p)[k] != 0)
2473 *r = (uint8_t*) p + start;
2480 static bool message_end_of_array(sd_bus_message *m, size_t index) {
2481 struct bus_container *c;
2485 c = message_get_container(m);
2489 return index >= c->begin + BUS_MESSAGE_BSWAP32(m, *c->array_size);
2492 static struct bus_body_part* find_part(sd_bus_message *m, size_t index, size_t sz, void **p) {
2493 struct bus_body_part *part;
2499 if (m->cached_rindex_part && index >= m->cached_rindex_part_begin) {
2500 part = m->cached_rindex_part;
2501 begin = m->cached_rindex_part_begin;
2511 if (index + sz <= begin + part->size) {
2513 r = bus_body_part_map(part);
2518 *p = (uint8_t*) part->data + index - begin;
2520 m->cached_rindex_part = part;
2521 m->cached_rindex_part_begin = begin;
2526 begin += part->size;
2533 static int message_peek_body(
2540 size_t k, start, end, padding;
2541 struct bus_body_part *part;
2548 if (message_end_of_array(m, *rindex))
2551 start = ALIGN_TO((size_t) *rindex, align);
2552 padding = start - *rindex;
2553 end = start + nbytes;
2555 if (end > BUS_MESSAGE_BODY_SIZE(m))
2558 part = find_part(m, *rindex, padding, (void**) &q);
2563 /* Verify padding */
2564 for (k = 0; k < padding; k++)
2569 part = find_part(m, start, nbytes, (void**) &q);
2581 static bool validate_nul(const char *s, size_t l) {
2583 /* Check for NUL chars in the string */
2584 if (memchr(s, 0, l))
2587 /* Check for NUL termination */
2594 static bool validate_string(const char *s, size_t l) {
2596 if (!validate_nul(s, l))
2599 /* Check if valid UTF8 */
2600 if (!utf8_is_valid(s))
2606 static bool validate_signature(const char *s, size_t l) {
2608 if (!validate_nul(s, l))
2611 /* Check if valid signature */
2612 if (!signature_is_valid(s, true))
2618 static bool validate_object_path(const char *s, size_t l) {
2620 if (!validate_nul(s, l))
2623 if (!object_path_is_valid(s))
2629 int sd_bus_message_read_basic(sd_bus_message *m, char type, void *p) {
2630 struct bus_container *c;
2638 if (!bus_type_is_basic(type))
2643 c = message_get_container(m);
2645 if (!c->signature || c->signature[c->index] == 0)
2648 if (c->signature[c->index] != type)
2653 case SD_BUS_TYPE_STRING:
2654 case SD_BUS_TYPE_OBJECT_PATH: {
2659 r = message_peek_body(m, &rindex, 4, 4, &q);
2663 l = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2664 r = message_peek_body(m, &rindex, 1, l+1, &q);
2670 if (type == SD_BUS_TYPE_OBJECT_PATH) {
2671 if (!validate_object_path(q, l))
2674 if (!validate_string(q, l))
2679 *(const char**) p = q;
2683 case SD_BUS_TYPE_SIGNATURE: {
2688 r = message_peek_body(m, &rindex, 1, 1, &q);
2693 r = message_peek_body(m, &rindex, 1, l+1, &q);
2699 if (!validate_signature(q, l))
2703 *(const char**) p = q;
2711 align = bus_type_get_alignment(type);
2712 sz = bus_type_get_size(type);
2713 assert(align > 0 && sz > 0);
2716 r = message_peek_body(m, &rindex, align, sz, &q);
2722 case SD_BUS_TYPE_BYTE:
2723 *(uint8_t*) p = *(uint8_t*) q;
2726 case SD_BUS_TYPE_BOOLEAN:
2727 *(int*) p = !!*(uint32_t*) q;
2730 case SD_BUS_TYPE_INT16:
2731 case SD_BUS_TYPE_UINT16:
2732 *(uint16_t*) p = BUS_MESSAGE_BSWAP16(m, *(uint16_t*) q);
2735 case SD_BUS_TYPE_INT32:
2736 case SD_BUS_TYPE_UINT32:
2737 *(uint32_t*) p = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2740 case SD_BUS_TYPE_INT64:
2741 case SD_BUS_TYPE_UINT64:
2742 case SD_BUS_TYPE_DOUBLE:
2743 *(uint64_t*) p = BUS_MESSAGE_BSWAP64(m, *(uint64_t*) q);
2746 case SD_BUS_TYPE_UNIX_FD: {
2749 j = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2753 *(int*) p = m->fds[j];
2758 assert_not_reached("Unknown basic type...");
2767 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2773 static int bus_message_enter_array(
2775 struct bus_container *c,
2776 const char *contents,
2777 uint32_t **array_size) {
2788 if (!signature_is_single(contents, true))
2791 alignment = bus_type_get_alignment(contents[0]);
2795 if (!c->signature || c->signature[c->index] == 0)
2798 if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
2801 if (!startswith(c->signature + c->index + 1, contents))
2805 r = message_peek_body(m, &rindex, 4, 4, &q);
2809 if (BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q) > BUS_ARRAY_MAX_SIZE)
2812 r = message_peek_body(m, &rindex, alignment, 0, NULL);
2818 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2819 c->index += 1 + strlen(contents);
2823 *array_size = (uint32_t*) q;
2828 static int bus_message_enter_variant(
2830 struct bus_container *c,
2831 const char *contents) {
2842 if (!signature_is_single(contents, false))
2845 if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
2848 if (!c->signature || c->signature[c->index] == 0)
2851 if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
2855 r = message_peek_body(m, &rindex, 1, 1, &q);
2860 r = message_peek_body(m, &rindex, 1, l+1, &q);
2866 if (!validate_signature(q, l))
2869 if (!streq(q, contents))
2872 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2880 static int bus_message_enter_struct(
2882 struct bus_container *c,
2883 const char *contents) {
2892 if (!signature_is_valid(contents, false))
2895 if (!c->signature || c->signature[c->index] == 0)
2898 l = strlen(contents);
2900 if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
2901 !startswith(c->signature + c->index + 1, contents) ||
2902 c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
2905 r = message_peek_body(m, &m->rindex, 8, 0, NULL);
2909 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2910 c->index += 1 + l + 1;
2915 static int bus_message_enter_dict_entry(
2917 struct bus_container *c,
2918 const char *contents) {
2927 if (!signature_is_pair(contents))
2930 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2933 if (!c->signature || c->signature[c->index] == 0)
2936 l = strlen(contents);
2938 if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
2939 !startswith(c->signature + c->index + 1, contents) ||
2940 c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
2943 r = message_peek_body(m, &m->rindex, 8, 0, NULL);
2947 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2948 c->index += 1 + l + 1;
2953 int sd_bus_message_enter_container(sd_bus_message *m, char type, const char *contents) {
2954 struct bus_container *c, *w;
2955 uint32_t *array_size = NULL;
2968 * We enforce a global limit on container depth, that is much
2969 * higher than the 32 structs and 32 arrays the specification
2970 * mandates. This is simpler to implement for us, and we need
2971 * this only to ensure our container array doesn't grow
2972 * without bounds. We are happy to return any data from a
2973 * message as long as the data itself is valid, even if the
2974 * overall message might be not.
2976 * Note that the message signature is validated when
2977 * parsing the headers, and that validation does check the
2980 * Note that the specification defines no limits on the depth
2981 * of stacked variants, but we do.
2983 if (m->n_containers >= BUS_CONTAINER_DEPTH)
2986 w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
2991 c = message_get_container(m);
2993 if (!c->signature || c->signature[c->index] == 0)
2996 signature = strdup(contents);
3000 c->saved_index = c->index;
3003 if (type == SD_BUS_TYPE_ARRAY)
3004 r = bus_message_enter_array(m, c, contents, &array_size);
3005 else if (type == SD_BUS_TYPE_VARIANT)
3006 r = bus_message_enter_variant(m, c, contents);
3007 else if (type == SD_BUS_TYPE_STRUCT)
3008 r = bus_message_enter_struct(m, c, contents);
3009 else if (type == SD_BUS_TYPE_DICT_ENTRY)
3010 r = bus_message_enter_dict_entry(m, c, contents);
3019 /* OK, let's fill it in */
3020 w += m->n_containers++;
3021 w->enclosing = type;
3022 w->signature = signature;
3024 w->array_size = array_size;
3026 w->begin = m->rindex;
3031 int sd_bus_message_exit_container(sd_bus_message *m) {
3032 struct bus_container *c;
3038 if (m->n_containers <= 0)
3041 c = message_get_container(m);
3042 if (c->enclosing == SD_BUS_TYPE_ARRAY) {
3045 l = BUS_MESSAGE_BSWAP32(m, *c->array_size);
3046 if (c->begin + l != m->rindex)
3050 if (c->signature && c->signature[c->index] != 0)
3060 static void message_quit_container(sd_bus_message *m) {
3061 struct bus_container *c;
3065 assert(m->n_containers > 0);
3067 c = message_get_container(m);
3070 assert(m->rindex >= c->before);
3071 m->rindex = c->before;
3073 /* Free container */
3077 /* Correct index of new top-level container */
3078 c = message_get_container(m);
3079 c->index = c->saved_index;
3082 int sd_bus_message_peek_type(sd_bus_message *m, char *type, const char **contents) {
3083 struct bus_container *c;
3091 c = message_get_container(m);
3093 if (!c->signature || c->signature[c->index] == 0)
3096 if (message_end_of_array(m, m->rindex))
3099 if (bus_type_is_basic(c->signature[c->index])) {
3103 *type = c->signature[c->index];
3107 if (c->signature[c->index] == SD_BUS_TYPE_ARRAY) {
3113 r = signature_element_length(c->signature+c->index+1, &l);
3119 sig = strndup(c->signature + c->index + 1, l);
3123 free(m->peeked_signature);
3124 m->peeked_signature = sig;
3130 *type = SD_BUS_TYPE_ARRAY;
3135 if (c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ||
3136 c->signature[c->index] == SD_BUS_TYPE_DICT_ENTRY_BEGIN) {
3142 r = signature_element_length(c->signature+c->index, &l);
3147 sig = strndup(c->signature + c->index + 1, l - 2);
3151 free(m->peeked_signature);
3152 m->peeked_signature = sig;
3158 *type = c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY;
3163 if (c->signature[c->index] == SD_BUS_TYPE_VARIANT) {
3169 r = message_peek_body(m, &rindex, 1, 1, &q);
3176 r = message_peek_body(m, &rindex, 1, l+1, &q);
3182 if (!validate_signature(q, l))
3189 *type = SD_BUS_TYPE_VARIANT;
3198 *type = c->enclosing;
3204 int sd_bus_message_rewind(sd_bus_message *m, int complete) {
3205 struct bus_container *c;
3213 message_reset_containers(m);
3215 m->root_container.index = 0;
3217 c = message_get_container(m);
3219 c = message_get_container(m);
3222 m->rindex = c->begin;
3225 return !isempty(c->signature);
3227 static int message_read_ap(
3232 unsigned n_array, n_struct;
3233 TypeStack stack[BUS_CONTAINER_DEPTH];
3234 unsigned stack_ptr = 0;
3242 /* Ideally, we'd just call ourselves recursively on every
3243 * complex type. However, the state of a va_list that is
3244 * passed to a function is undefined after that function
3245 * returns. This means we need to docode the va_list linearly
3246 * in a single stackframe. We hence implement our own
3247 * home-grown stack in an array. */
3249 n_array = (unsigned) -1;
3250 n_struct = strlen(types);
3255 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
3256 r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
3262 r = sd_bus_message_exit_container(m);
3270 if (n_array != (unsigned) -1)
3279 case SD_BUS_TYPE_BYTE:
3280 case SD_BUS_TYPE_BOOLEAN:
3281 case SD_BUS_TYPE_INT16:
3282 case SD_BUS_TYPE_UINT16:
3283 case SD_BUS_TYPE_INT32:
3284 case SD_BUS_TYPE_UINT32:
3285 case SD_BUS_TYPE_INT64:
3286 case SD_BUS_TYPE_UINT64:
3287 case SD_BUS_TYPE_DOUBLE:
3288 case SD_BUS_TYPE_STRING:
3289 case SD_BUS_TYPE_OBJECT_PATH:
3290 case SD_BUS_TYPE_SIGNATURE:
3291 case SD_BUS_TYPE_UNIX_FD: {
3294 p = va_arg(ap, void*);
3295 r = sd_bus_message_read_basic(m, *t, p);
3304 case SD_BUS_TYPE_ARRAY: {
3307 r = signature_element_length(t + 1, &k);
3313 memcpy(s, t + 1, k);
3316 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, s);
3323 if (n_array == (unsigned) -1) {
3328 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
3334 n_array = va_arg(ap, unsigned);
3339 case SD_BUS_TYPE_VARIANT: {
3342 s = va_arg(ap, const char *);
3346 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, s);
3352 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
3357 n_struct = strlen(s);
3358 n_array = (unsigned) -1;
3363 case SD_BUS_TYPE_STRUCT_BEGIN:
3364 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
3367 r = signature_element_length(t, &k);
3373 memcpy(s, t + 1, k - 2);
3376 r = sd_bus_message_enter_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
3383 if (n_array == (unsigned) -1) {
3388 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
3394 n_array = (unsigned) -1;
3407 int sd_bus_message_read(sd_bus_message *m, const char *types, ...) {
3418 va_start(ap, types);
3419 r = message_read_ap(m, types, ap);
3425 int sd_bus_message_read_array(sd_bus_message *m, char type, const void **ptr, size_t *size) {
3426 struct bus_container *c;
3436 if (!bus_type_is_trivial(type))
3442 if (BUS_MESSAGE_NEED_BSWAP(m))
3445 align = bus_type_get_alignment(type);
3449 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
3453 c = message_get_container(m);
3454 sz = BUS_MESSAGE_BSWAP32(m, *c->array_size);
3456 r = message_peek_body(m, &m->rindex, align, sz, &p);
3464 r = sd_bus_message_exit_container(m);
3468 *ptr = (const void*) p;
3474 message_quit_container(m);
3478 static int message_peek_fields(
3489 return buffer_peek(BUS_MESSAGE_FIELDS(m), BUS_MESSAGE_FIELDS_SIZE(m), rindex, align, nbytes, ret);
3492 static int message_peek_field_uint32(
3503 r = message_peek_fields(m, ri, 4, 4, &q);
3508 *ret = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
3513 static int message_peek_field_string(
3515 bool (*validate)(const char *p),
3526 r = message_peek_field_uint32(m, ri, &l);
3530 r = message_peek_fields(m, ri, 1, l+1, &q);
3535 if (!validate_nul(q, l))
3541 if (!validate_string(q, l))
3551 static int message_peek_field_signature(
3563 r = message_peek_fields(m, ri, 1, 1, &q);
3568 r = message_peek_fields(m, ri, 1, l+1, &q);
3572 if (!validate_signature(q, l))
3581 static int message_skip_fields(
3584 uint32_t array_size,
3585 const char **signature) {
3587 size_t original_index;
3594 original_index = *ri;
3600 if (array_size != (uint32_t) -1 &&
3601 array_size <= *ri - original_index)
3608 if (t == SD_BUS_TYPE_STRING) {
3610 r = message_peek_field_string(m, NULL, ri, NULL);
3616 } else if (t == SD_BUS_TYPE_OBJECT_PATH) {
3618 r = message_peek_field_string(m, object_path_is_valid, ri, NULL);
3624 } else if (t == SD_BUS_TYPE_SIGNATURE) {
3626 r = message_peek_field_signature(m, ri, NULL);
3632 } else if (bus_type_is_basic(t)) {
3635 align = bus_type_get_alignment(t);
3636 k = bus_type_get_size(t);
3637 assert(align > 0 && k > 0);
3639 r = message_peek_fields(m, ri, align, k, NULL);
3645 } else if (t == SD_BUS_TYPE_ARRAY) {
3647 r = signature_element_length(*signature+1, &l);
3657 strncpy(sig, *signature + 1, l-1);
3660 alignment = bus_type_get_alignment(sig[0]);
3664 r = message_peek_field_uint32(m, ri, &nas);
3667 if (nas > BUS_ARRAY_MAX_SIZE)
3670 r = message_peek_fields(m, ri, alignment, 0, NULL);
3674 r = message_skip_fields(m, ri, nas, (const char**) &s);
3679 (*signature) += 1 + l;
3681 } else if (t == SD_BUS_TYPE_VARIANT) {
3684 r = message_peek_field_signature(m, ri, &s);
3688 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
3694 } else if (t == SD_BUS_TYPE_STRUCT ||
3695 t == SD_BUS_TYPE_DICT_ENTRY) {
3697 r = signature_element_length(*signature, &l);
3704 strncpy(sig, *signature + 1, l-1);
3707 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
3718 int bus_message_parse_fields(sd_bus_message *m) {
3721 uint32_t unix_fds = 0;
3725 for (ri = 0; ri < BUS_MESSAGE_FIELDS_SIZE(m); ) {
3726 const char *signature;
3729 r = message_peek_fields(m, &ri, 8, 1, (void**) &header);
3733 r = message_peek_field_signature(m, &ri, &signature);
3738 case _SD_BUS_MESSAGE_HEADER_INVALID:
3741 case SD_BUS_MESSAGE_HEADER_PATH:
3746 if (!streq(signature, "o"))
3749 r = message_peek_field_string(m, object_path_is_valid, &ri, &m->path);
3752 case SD_BUS_MESSAGE_HEADER_INTERFACE:
3757 if (!streq(signature, "s"))
3760 r = message_peek_field_string(m, interface_name_is_valid, &ri, &m->interface);
3763 case SD_BUS_MESSAGE_HEADER_MEMBER:
3768 if (!streq(signature, "s"))
3771 r = message_peek_field_string(m, member_name_is_valid, &ri, &m->member);
3774 case SD_BUS_MESSAGE_HEADER_ERROR_NAME:
3779 if (!streq(signature, "s"))
3782 r = message_peek_field_string(m, error_name_is_valid, &ri, &m->error.name);
3785 case SD_BUS_MESSAGE_HEADER_DESTINATION:
3790 if (!streq(signature, "s"))
3793 r = message_peek_field_string(m, service_name_is_valid, &ri, &m->destination);
3796 case SD_BUS_MESSAGE_HEADER_SENDER:
3801 if (!streq(signature, "s"))
3804 r = message_peek_field_string(m, service_name_is_valid, &ri, &m->sender);
3808 case SD_BUS_MESSAGE_HEADER_SIGNATURE: {
3812 if (m->root_container.signature)
3815 if (!streq(signature, "g"))
3818 r = message_peek_field_signature(m, &ri, &s);
3826 free(m->root_container.signature);
3827 m->root_container.signature = c;
3831 case SD_BUS_MESSAGE_HEADER_REPLY_SERIAL:
3832 if (m->reply_serial != 0)
3835 if (!streq(signature, "u"))
3838 r = message_peek_field_uint32(m, &ri, &m->reply_serial);
3842 if (m->reply_serial == 0)
3847 case SD_BUS_MESSAGE_HEADER_UNIX_FDS:
3851 if (!streq(signature, "u"))
3854 r = message_peek_field_uint32(m, &ri, &unix_fds);
3864 r = message_skip_fields(m, &ri, (uint32_t) -1, (const char **) &signature);
3871 if (m->n_fds != unix_fds)
3874 if (isempty(m->root_container.signature) != (BUS_MESSAGE_BODY_SIZE(m) == 0))
3877 switch (m->header->type) {
3879 case SD_BUS_MESSAGE_TYPE_SIGNAL:
3880 if (!m->path || !m->interface || !m->member)
3884 case SD_BUS_MESSAGE_TYPE_METHOD_CALL:
3886 if (!m->path || !m->member)
3891 case SD_BUS_MESSAGE_TYPE_METHOD_RETURN:
3893 if (m->reply_serial == 0)
3897 case SD_BUS_MESSAGE_TYPE_METHOD_ERROR:
3899 if (m->reply_serial == 0 || !m->error.name)
3904 /* Try to read the error message, but if we can't it's a non-issue */
3905 if (m->header->type == SD_BUS_MESSAGE_TYPE_METHOD_ERROR)
3906 sd_bus_message_read(m, "s", &m->error.message);
3911 int bus_message_seal(sd_bus_message *m, uint64_t serial) {
3912 struct bus_body_part *part;
3922 if (m->n_containers > 0)
3928 /* If there's a non-trivial signature set, then add it in here */
3929 if (!isempty(m->root_container.signature)) {
3930 r = message_append_field_signature(m, SD_BUS_MESSAGE_HEADER_SIGNATURE, m->root_container.signature, NULL);
3936 r = message_append_field_uint32(m, SD_BUS_MESSAGE_HEADER_UNIX_FDS, m->n_fds);
3941 /* Add padding at the end of the fields part, since we know
3942 * the body needs to start at an 8 byte alignment. We made
3943 * sure we allocated enough space for this, so all we need to
3944 * do here is to zero it out. */
3945 l = BUS_MESSAGE_FIELDS_SIZE(m);
3948 memset((uint8_t*) BUS_MESSAGE_FIELDS(m) + l, 0, a);
3950 /* If this is something we can send as memfd, then let's seal
3951 the memfd now. Note that we can send memfds as payload only
3952 for directed messages, and not for broadcasts. */
3953 if (m->destination && m->bus && m->bus->use_memfd) {
3954 MESSAGE_FOREACH_PART(part, i, m)
3955 if (part->memfd >= 0 && !part->sealed && (part->size > MEMFD_MIN_SIZE || m->bus->use_memfd < 0)) {
3956 bus_body_part_unmap(part);
3958 if (ioctl(part->memfd, KDBUS_CMD_MEMFD_SEAL_SET, 1) >= 0)
3959 part->sealed = true;
3963 m->header->serial = serial;
3969 int sd_bus_message_set_destination(sd_bus_message *m, const char *destination) {
3979 return message_append_field_string(m, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &m->destination);
3982 int bus_message_dump(sd_bus_message *m) {
3983 const char *u = NULL, *uu = NULL, *s = NULL;
3984 char **cmdline = NULL;
3987 uid_t owner, audit_loginuid;
3988 uint32_t audit_sessionid;
3992 printf("Message %p\n"
3999 "\tfields_size=%u\n"
4004 "\tdestination=%s\n"
4007 "\treply_serial=%u\n"
4009 "\terror.message=%s\n"
4011 "\tn_body_parts=%u\n",
4018 BUS_MESSAGE_SERIAL(m),
4019 BUS_MESSAGE_FIELDS_SIZE(m),
4020 BUS_MESSAGE_BODY_SIZE(m),
4022 strna(m->interface),
4024 strna(m->destination),
4026 strna(m->root_container.signature),
4028 strna(m->error.name),
4029 strna(m->error.message),
4034 printf("\tpid=%lu\n", (unsigned long) m->pid);
4036 printf("\ttid=%lu\n", (unsigned long) m->tid);
4038 printf("\tuid=%lu\n", (unsigned long) m->uid);
4040 printf("\tgid=%lu\n", (unsigned long) m->gid);
4041 if (m->pid_starttime != 0)
4042 printf("\tpid_starttime=%llu\n", (unsigned long long) m->pid_starttime);
4043 if (m->monotonic != 0)
4044 printf("\tmonotonic=%llu\n", (unsigned long long) m->monotonic);
4045 if (m->realtime != 0)
4046 printf("\trealtime=%llu\n", (unsigned long long) m->realtime);
4048 printf("\texe=[%s]\n", m->exe);
4050 printf("\tcomm=[%s]\n", m->comm);
4052 printf("\ttid_comm=[%s]\n", m->tid_comm);
4054 printf("\tlabel=[%s]\n", m->label);
4056 printf("\tcgroup=[%s]\n", m->cgroup);
4058 sd_bus_message_get_unit(m, &u);
4060 printf("\tunit=[%s]\n", u);
4061 sd_bus_message_get_user_unit(m, &uu);
4063 printf("\tuser_unit=[%s]\n", uu);
4064 sd_bus_message_get_session(m, &s);
4066 printf("\tsession=[%s]\n", s);
4067 if (sd_bus_message_get_owner_uid(m, &owner) >= 0)
4068 printf("\towner_uid=%lu\n", (unsigned long) owner);
4069 if (sd_bus_message_get_audit_loginuid(m, &audit_loginuid) >= 0)
4070 printf("\taudit_loginuid=%lu\n", (unsigned long) audit_loginuid);
4071 if (sd_bus_message_get_audit_sessionid(m, &audit_sessionid) >= 0)
4072 printf("\taudit_sessionid=%lu\n", (unsigned long) audit_sessionid);
4074 printf("\tCAP_KILL=%i\n", sd_bus_message_has_effective_cap(m, 5));
4076 if (sd_bus_message_get_cmdline(m, &cmdline) >= 0) {
4079 fputs("\tcmdline=[", stdout);
4080 STRV_FOREACH(c, cmdline) {
4087 fputs("]\n", stdout);
4090 r = sd_bus_message_rewind(m, true);
4092 log_error("Failed to rewind: %s", strerror(-r));
4096 printf("BEGIN_MESSAGE \"%s\" {\n", strempty(m->root_container.signature));
4099 _cleanup_free_ char *prefix = NULL;
4100 const char *contents = NULL;
4115 r = sd_bus_message_peek_type(m, &type, &contents);
4117 log_error("Failed to peek type: %s", strerror(-r));
4124 r = sd_bus_message_exit_container(m);
4126 log_error("Failed to exit container: %s", strerror(-r));
4132 prefix = strrep("\t", level);
4136 if (type == SD_BUS_TYPE_ARRAY)
4137 printf("%s} END_ARRAY \n", prefix);
4138 else if (type == SD_BUS_TYPE_VARIANT)
4139 printf("%s} END_VARIANT\n", prefix);
4140 else if (type == SD_BUS_TYPE_STRUCT)
4141 printf("%s} END_STRUCT\n", prefix);
4142 else if (type == SD_BUS_TYPE_DICT_ENTRY)
4143 printf("%s} END_DICT_ENTRY\n", prefix);
4148 prefix = strrep("\t", level);
4152 if (bus_type_is_container(type) > 0) {
4153 r = sd_bus_message_enter_container(m, type, contents);
4155 log_error("Failed to enter container: %s", strerror(-r));
4159 if (type == SD_BUS_TYPE_ARRAY)
4160 printf("%sBEGIN_ARRAY \"%s\" {\n", prefix, contents);
4161 else if (type == SD_BUS_TYPE_VARIANT)
4162 printf("%sBEGIN_VARIANT \"%s\" {\n", prefix, contents);
4163 else if (type == SD_BUS_TYPE_STRUCT)
4164 printf("%sBEGIN_STRUCT \"%s\" {\n", prefix, contents);
4165 else if (type == SD_BUS_TYPE_DICT_ENTRY)
4166 printf("%sBEGIN_DICT_ENTRY \"%s\" {\n", prefix, contents);
4173 r = sd_bus_message_read_basic(m, type, &basic);
4175 log_error("Failed to get basic: %s", strerror(-r));
4181 case SD_BUS_TYPE_BYTE:
4182 printf("%sBYTE: %u\n", prefix, basic.u8);
4185 case SD_BUS_TYPE_BOOLEAN:
4186 printf("%sBOOLEAN: %s\n", prefix, yes_no(basic.i));
4189 case SD_BUS_TYPE_INT16:
4190 printf("%sINT16: %i\n", prefix, basic.s16);
4193 case SD_BUS_TYPE_UINT16:
4194 printf("%sUINT16: %u\n", prefix, basic.u16);
4197 case SD_BUS_TYPE_INT32:
4198 printf("%sINT32: %i\n", prefix, basic.s32);
4201 case SD_BUS_TYPE_UINT32:
4202 printf("%sUINT32: %u\n", prefix, basic.u32);
4205 case SD_BUS_TYPE_INT64:
4206 printf("%sINT64: %lli\n", prefix, (long long) basic.s64);
4209 case SD_BUS_TYPE_UINT64:
4210 printf("%sUINT64: %llu\n", prefix, (unsigned long long) basic.u64);
4213 case SD_BUS_TYPE_DOUBLE:
4214 printf("%sDOUBLE: %g\n", prefix, basic.d64);
4217 case SD_BUS_TYPE_STRING:
4218 printf("%sSTRING: \"%s\"\n", prefix, basic.string);
4221 case SD_BUS_TYPE_OBJECT_PATH:
4222 printf("%sOBJECT_PATH: \"%s\"\n", prefix, basic.string);
4225 case SD_BUS_TYPE_SIGNATURE:
4226 printf("%sSIGNATURE: \"%s\"\n", prefix, basic.string);
4229 case SD_BUS_TYPE_UNIX_FD:
4230 printf("%sUNIX_FD: %i\n", prefix, basic.i);
4234 assert_not_reached("Unknown basic type.");
4238 printf("} END_MESSAGE\n");
4242 int bus_message_get_blob(sd_bus_message *m, void **buffer, size_t *sz) {
4246 struct bus_body_part *part;
4252 total = BUS_MESSAGE_SIZE(m);
4258 e = mempcpy(p, m->header, BUS_MESSAGE_BODY_BEGIN(m));
4259 MESSAGE_FOREACH_PART(part, i, m)
4260 e = mempcpy(e, part->data, part->size);
4262 assert(total == (size_t) ((uint8_t*) e - (uint8_t*) p));
4270 int bus_message_read_strv_extend(sd_bus_message *m, char ***l) {
4276 r = sd_bus_message_enter_container(m, 'a', "s");
4283 r = sd_bus_message_read_basic(m, 's', &s);
4289 r = strv_extend(l, s);
4294 r = sd_bus_message_exit_container(m);
4301 const char* bus_message_get_arg(sd_bus_message *m, unsigned i) {
4303 const char *t = NULL;
4308 r = sd_bus_message_rewind(m, true);
4312 for (j = 0; j <= i; j++) {
4315 r = sd_bus_message_peek_type(m, &type, NULL);
4319 if (type != SD_BUS_TYPE_STRING &&
4320 type != SD_BUS_TYPE_OBJECT_PATH &&
4321 type != SD_BUS_TYPE_SIGNATURE)
4324 r = sd_bus_message_read_basic(m, type, &t);
4332 bool bus_header_is_complete(struct bus_header *h, size_t size) {
4338 if (size < sizeof(struct bus_header))
4341 full = sizeof(struct bus_header) +
4342 (h->endian == SD_BUS_NATIVE_ENDIAN ? h->fields_size : bswap_32(h->fields_size));
4344 return size >= full;
4347 int bus_header_message_size(struct bus_header *h, size_t *sum) {
4353 if (h->endian == SD_BUS_NATIVE_ENDIAN) {
4354 fs = h->fields_size;
4356 } else if (h->endian == SD_BUS_REVERSE_ENDIAN) {
4357 fs = bswap_32(h->fields_size);
4358 bs = bswap_32(h->body_size);
4362 *sum = sizeof(struct bus_header) + ALIGN8(fs) + bs;
4366 int bus_message_to_errno(sd_bus_message *m) {
4369 if (m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_ERROR)
4372 return bus_error_to_errno(&m->error);
4375 int sd_bus_message_get_signature(sd_bus_message *m, int complete, const char **signature) {
4376 struct bus_container *c;
4383 c = complete ? &m->root_container : message_get_container(m);
4384 *signature = c->signature ?: "";