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, PAGE_ALIGN(part->size)) == 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)
129 ioctl(m->bus->input_fd, KDBUS_CMD_MSG_RELEASE, m->kdbus);
132 close_many(m->fds, m->n_fds);
137 sd_bus_unref(m->bus);
139 if (m->iovec != m->iovec_fixed)
142 free(m->cmdline_array);
144 message_reset_containers(m);
145 free(m->root_container.signature);
147 free(m->peeked_signature);
155 static void *message_extend_fields(sd_bus_message *m, size_t align, size_t sz) {
157 size_t old_size, new_size, start;
164 old_size = sizeof(struct bus_header) + m->header->fields_size;
165 start = ALIGN_TO(old_size, align);
166 new_size = start + sz;
168 if (old_size == new_size)
169 return (uint8_t*) m->header + old_size;
171 if (new_size > (size_t) ((uint32_t) -1))
174 if (m->free_header) {
175 np = realloc(m->header, ALIGN8(new_size));
179 /* Initially, the header is allocated as part of of
180 * the sd_bus_message itself, let's replace it by
183 np = malloc(ALIGN8(new_size));
187 memcpy(np, m->header, sizeof(struct bus_header));
190 /* Zero out padding */
191 if (start > old_size)
192 memset((uint8_t*) np + old_size, 0, start - old_size);
196 m->header->fields_size = new_size - sizeof(struct bus_header);
198 /* Adjust quick access pointers */
199 m->path = adjust_pointer(m->path, op, old_size, m->header);
200 m->interface = adjust_pointer(m->interface, op, old_size, m->header);
201 m->member = adjust_pointer(m->member, op, old_size, m->header);
202 m->destination = adjust_pointer(m->destination, op, old_size, m->header);
203 m->sender = adjust_pointer(m->sender, op, old_size, m->header);
204 m->error.name = adjust_pointer(m->error.name, op, old_size, m->header);
206 m->free_header = true;
208 return (uint8_t*) np + start;
215 static int message_append_field_string(
228 if (l > (size_t) (uint32_t) -1)
231 /* field id byte + signature length + signature 's' + NUL + string length + string + NUL */
232 p = message_extend_fields(m, 8, 4 + 4 + l + 1);
241 ((uint32_t*) p)[1] = l;
242 memcpy(p + 8, s, l + 1);
245 *ret = (char*) p + 8;
250 static int message_append_field_signature(
265 /* field id byte + signature length + signature 'g' + NUL + string length + string + NUL */
266 p = message_extend_fields(m, 8, 4 + 1 + l + 1);
272 p[2] = SD_BUS_TYPE_SIGNATURE;
275 memcpy(p + 5, s, l + 1);
278 *ret = (const char*) p + 5;
283 static int message_append_field_uint32(sd_bus_message *m, uint8_t h, uint32_t x) {
288 /* field id byte + signature length + signature 'u' + NUL + value */
289 p = message_extend_fields(m, 8, 4 + 4);
295 p[2] = SD_BUS_TYPE_UINT32;
298 ((uint32_t*) p)[1] = x;
303 int bus_message_from_header(
308 const struct ucred *ucred,
311 sd_bus_message **ret) {
314 struct bus_header *h;
317 assert(buffer || length <= 0);
318 assert(fds || n_fds <= 0);
321 if (length < sizeof(struct bus_header))
331 if (h->type == _SD_BUS_MESSAGE_TYPE_INVALID)
334 if (h->endian != SD_BUS_LITTLE_ENDIAN &&
335 h->endian != SD_BUS_BIG_ENDIAN)
338 a = ALIGN(sizeof(sd_bus_message)) + ALIGN(extra);
341 label_sz = strlen(label);
359 m->uid_valid = m->gid_valid = true;
363 m->label = (char*) m + ALIGN(sizeof(sd_bus_message)) + ALIGN(extra);
364 memcpy(m->label, label, label_sz + 1);
371 int bus_message_from_malloc(
376 const struct ucred *ucred,
378 sd_bus_message **ret) {
383 r = bus_message_from_header(buffer, length, fds, n_fds, ucred, label, 0, &m);
387 if (length != BUS_MESSAGE_SIZE(m)) {
393 m->body.data = (uint8_t*) buffer + sizeof(struct bus_header) + ALIGN8(BUS_MESSAGE_FIELDS_SIZE(m));
394 m->body.size = length - sizeof(struct bus_header) - ALIGN8(BUS_MESSAGE_FIELDS_SIZE(m));
395 m->body.sealed = true;
399 m->iovec = m->iovec_fixed;
400 m->iovec[0].iov_base = buffer;
401 m->iovec[0].iov_len = length;
403 r = bus_message_parse_fields(m);
407 /* We take possession of the memory and fds now */
408 m->free_header = true;
419 static sd_bus_message *message_new(sd_bus *bus, uint8_t type) {
422 m = malloc0(ALIGN(sizeof(sd_bus_message)) + sizeof(struct bus_header));
427 m->header = (struct bus_header*) ((uint8_t*) m + ALIGN(sizeof(struct sd_bus_message)));
428 m->header->endian = SD_BUS_NATIVE_ENDIAN;
429 m->header->type = type;
430 m->header->version = bus ? bus->message_version : 1;
431 m->allow_fds = !bus || bus->can_fds || (bus->state != BUS_HELLO && bus->state != BUS_RUNNING);
434 m->bus = sd_bus_ref(bus);
439 int sd_bus_message_new_signal(
442 const char *interface,
444 sd_bus_message **m) {
457 if (bus && bus->state == BUS_UNSET)
460 t = message_new(bus, SD_BUS_MESSAGE_TYPE_SIGNAL);
464 t->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
466 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_PATH, SD_BUS_TYPE_OBJECT_PATH, path, &t->path);
469 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_INTERFACE, SD_BUS_TYPE_STRING, interface, &t->interface);
472 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_MEMBER, SD_BUS_TYPE_STRING, member, &t->member);
480 sd_bus_message_unref(t);
484 int sd_bus_message_new_method_call(
486 const char *destination,
488 const char *interface,
490 sd_bus_message **m) {
501 if (bus && bus->state == BUS_UNSET)
504 t = message_new(bus, SD_BUS_MESSAGE_TYPE_METHOD_CALL);
508 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_PATH, SD_BUS_TYPE_OBJECT_PATH, path, &t->path);
511 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_MEMBER, SD_BUS_TYPE_STRING, member, &t->member);
516 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_INTERFACE, SD_BUS_TYPE_STRING, interface, &t->interface);
522 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &t->destination);
535 static int message_new_reply(
537 sd_bus_message *call,
539 sd_bus_message **m) {
548 if (call->header->type != SD_BUS_MESSAGE_TYPE_METHOD_CALL)
552 if (bus && bus->state == BUS_UNSET)
555 t = message_new(bus, type);
559 t->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
560 t->reply_serial = BUS_MESSAGE_SERIAL(call);
562 r = message_append_field_uint32(t, SD_BUS_MESSAGE_HEADER_REPLY_SERIAL, t->reply_serial);
567 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, call->sender, &t->sender);
572 t->dont_send = !!(call->header->flags & SD_BUS_MESSAGE_NO_REPLY_EXPECTED);
582 int sd_bus_message_new_method_return(
584 sd_bus_message *call,
585 sd_bus_message **m) {
587 return message_new_reply(bus, call, SD_BUS_MESSAGE_TYPE_METHOD_RETURN, m);
590 int sd_bus_message_new_method_error(
592 sd_bus_message *call,
593 const sd_bus_error *e,
594 sd_bus_message **m) {
599 if (!sd_bus_error_is_set(e))
604 r = message_new_reply(bus, call, SD_BUS_MESSAGE_TYPE_METHOD_ERROR, &t);
608 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_ERROR_NAME, SD_BUS_TYPE_STRING, e->name, &t->error.name);
613 r = message_append_basic(t, SD_BUS_TYPE_STRING, e->message, (const void**) &t->error.message);
626 sd_bus_message* sd_bus_message_ref(sd_bus_message *m) {
630 assert(m->n_ref > 0);
636 sd_bus_message* sd_bus_message_unref(sd_bus_message *m) {
640 assert(m->n_ref > 0);
649 int sd_bus_message_get_type(sd_bus_message *m, uint8_t *type) {
655 *type = m->header->type;
659 int sd_bus_message_get_serial(sd_bus_message *m, uint64_t *serial) {
664 if (m->header->serial == 0)
667 *serial = BUS_MESSAGE_SERIAL(m);
671 int sd_bus_message_get_reply_serial(sd_bus_message *m, uint64_t *serial) {
676 if (m->reply_serial == 0)
679 *serial = m->reply_serial;
683 int sd_bus_message_get_no_reply(sd_bus_message *m) {
687 return m->header->type == SD_BUS_MESSAGE_TYPE_METHOD_CALL ? !!(m->header->flags & SD_BUS_MESSAGE_NO_REPLY_EXPECTED) : 0;
690 const char *sd_bus_message_get_path(sd_bus_message *m) {
697 const char *sd_bus_message_get_interface(sd_bus_message *m) {
704 const char *sd_bus_message_get_member(sd_bus_message *m) {
710 const char *sd_bus_message_get_destination(sd_bus_message *m) {
714 return m->destination;
717 const char *sd_bus_message_get_sender(sd_bus_message *m) {
724 const sd_bus_error *sd_bus_message_get_error(sd_bus_message *m) {
728 if (!sd_bus_error_is_set(&m->error))
734 int sd_bus_message_get_uid(sd_bus_message *m, uid_t *uid) {
746 int sd_bus_message_get_gid(sd_bus_message *m, gid_t *gid) {
758 int sd_bus_message_get_pid(sd_bus_message *m, pid_t *pid) {
770 int sd_bus_message_get_tid(sd_bus_message *m, pid_t *tid) {
782 int sd_bus_message_get_pid_starttime(sd_bus_message *m, uint64_t *usec) {
787 if (m->pid_starttime <= 0)
790 *usec = m->pid_starttime;
794 int sd_bus_message_get_selinux_context(sd_bus_message *m, const char **ret) {
804 int sd_bus_message_get_monotonic_timestamp(sd_bus_message *m, uint64_t *usec) {
809 if (m->monotonic <= 0)
812 *usec = m->monotonic;
816 int sd_bus_message_get_realtime_timestamp(sd_bus_message *m, uint64_t *usec) {
821 if (m->realtime <= 0)
828 int sd_bus_message_get_comm(sd_bus_message *m, const char **ret) {
840 int sd_bus_message_get_tid_comm(sd_bus_message *m, const char **ret) {
852 int sd_bus_message_get_exe(sd_bus_message *m, const char **ret) {
864 int sd_bus_message_get_cgroup(sd_bus_message *m, const char **ret) {
876 int sd_bus_message_get_unit(sd_bus_message *m, const char **ret) {
887 r = cg_path_get_unit(m->cgroup, &m->unit);
896 int sd_bus_message_get_user_unit(sd_bus_message *m, const char **ret) {
907 r = cg_path_get_user_unit(m->cgroup, &m->user_unit);
916 int sd_bus_message_get_session(sd_bus_message *m, const char **ret) {
927 r = cg_path_get_session(m->cgroup, &m->session);
936 int sd_bus_message_get_owner_uid(sd_bus_message *m, uid_t *uid) {
944 return cg_path_get_owner_uid(m->cgroup, uid);
947 int sd_bus_message_get_cmdline(sd_bus_message *m, char ***cmdline) {
958 for (p = m->cmdline, n = 0; p < m->cmdline + m->cmdline_length; p++)
962 m->cmdline_array = new(char*, n + 1);
963 if (!m->cmdline_array)
966 for (p = m->cmdline, i = 0, first = true; p < m->cmdline + m->cmdline_length; p++) {
968 m->cmdline_array[i++] = (char*) p;
973 m->cmdline_array[i] = NULL;
974 *cmdline = m->cmdline_array;
979 int sd_bus_message_get_audit_sessionid(sd_bus_message *m, uint32_t *sessionid) {
987 *sessionid = m->audit->sessionid;
991 int sd_bus_message_get_audit_loginuid(sd_bus_message *m, uid_t *uid) {
999 *uid = m->audit->loginuid;
1003 int sd_bus_message_has_effective_cap(sd_bus_message *m, int capability) {
1013 sz = m->capability_size / 4;
1014 if ((unsigned) capability >= sz*8)
1017 return !!(m->capability[2 * sz + (capability / 8)] & (1 << (capability % 8)));
1020 int sd_bus_message_is_signal(sd_bus_message *m, const char *interface, const char *member) {
1024 if (m->header->type != SD_BUS_MESSAGE_TYPE_SIGNAL)
1027 if (interface && (!m->interface || !streq(m->interface, interface)))
1030 if (member && (!m->member || !streq(m->member, member)))
1036 int sd_bus_message_is_method_call(sd_bus_message *m, const char *interface, const char *member) {
1040 if (m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_CALL)
1043 if (interface && (!m->interface || !streq(m->interface, interface)))
1046 if (member && (!m->member || !streq(m->member, member)))
1052 int sd_bus_message_is_method_error(sd_bus_message *m, const char *name) {
1056 if (m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_ERROR)
1059 if (name && (!m->error.name || !streq(m->error.name, name)))
1065 int sd_bus_message_set_no_reply(sd_bus_message *m, int b) {
1070 if (m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_CALL)
1074 m->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
1076 m->header->flags &= ~SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
1081 static struct bus_container *message_get_container(sd_bus_message *m) {
1084 if (m->n_containers == 0)
1085 return &m->root_container;
1087 assert(m->containers);
1088 return m->containers + m->n_containers - 1;
1091 struct bus_body_part *message_append_part(sd_bus_message *m) {
1092 struct bus_body_part *part;
1099 if (m->n_body_parts <= 0) {
1103 assert(m->body_end);
1105 part = new0(struct bus_body_part, 1);
1111 m->body_end->next = part;
1121 static void part_zero(struct bus_body_part *part, size_t sz) {
1126 /* All other fields can be left in their defaults */
1127 assert(!part->data);
1128 assert(part->memfd < 0);
1131 part->is_zero = true;
1132 part->sealed = true;
1135 static int part_make_space(
1136 struct sd_bus_message *m,
1137 struct bus_body_part *part,
1146 assert(!part->sealed);
1151 if (!part->data && part->memfd < 0)
1152 part->memfd = bus_kernel_pop_memfd(m->bus, &part->data, &part->mapped);
1154 if (part->memfd >= 0) {
1157 r = ioctl(part->memfd, KDBUS_CMD_MEMFD_SIZE_SET, &u);
1163 if (!part->data || sz > part->mapped) {
1164 size_t psz = PAGE_ALIGN(sz > 0 ? sz : 1);
1166 if (part->mapped <= 0)
1167 n = mmap(NULL, psz, PROT_READ|PROT_WRITE, MAP_SHARED, part->memfd, 0);
1169 n = mremap(part->data, part->mapped, psz, MREMAP_MAYMOVE);
1171 if (n == MAP_FAILED) {
1178 part->munmap_this = true;
1181 n = realloc(part->data, sz);
1188 part->free_this = true;
1192 *q = part->data ? (uint8_t*) part->data + part->size : NULL;
1198 static void message_extend_containers(sd_bus_message *m, size_t expand) {
1199 struct bus_container *c;
1206 /* Update counters */
1207 for (c = m->containers; c < m->containers + m->n_containers; c++)
1209 *c->array_size += expand;
1213 static void *message_extend_body(sd_bus_message *m, size_t align, size_t sz) {
1214 struct bus_body_part *part = NULL;
1215 size_t start_body, end_body, padding, start_part, end_part, added;
1227 start_body = ALIGN_TO((size_t) m->header->body_size, align);
1228 end_body = start_body + sz;
1230 padding = start_body - m->header->body_size;
1231 added = padding + sz;
1233 /* Check for 32bit overflows */
1234 if (end_body > (size_t) ((uint32_t) -1)) {
1240 m->n_body_parts <= 0 ||
1241 m->body_end->sealed ||
1242 padding != ALIGN_TO(m->body_end->size, align) - m->body_end->size;
1246 part = message_append_part(m);
1250 part_zero(part, padding);
1253 part = message_append_part(m);
1257 r = part_make_space(m, part, sz, &p);
1261 struct bus_container *c;
1269 start_part = ALIGN_TO(part->size, align);
1270 end_part = start_part + sz;
1272 r = part_make_space(m, part, end_part, &p);
1277 memset(p, 0, padding);
1278 p = (uint8_t*) p + padding;
1281 /* Readjust pointers */
1282 for (c = m->containers; c < m->containers + m->n_containers; c++)
1283 c->array_size = adjust_pointer(c->array_size, op, os, part->data);
1285 m->error.message = (const char*) adjust_pointer(m->error.message, op, os, part->data);
1288 m->header->body_size = end_body;
1289 message_extend_containers(m, added);
1294 int message_append_basic(sd_bus_message *m, char type, const void *p, const void **stored) {
1295 struct bus_container *c;
1309 if (!bus_type_is_basic(type))
1314 c = message_get_container(m);
1316 if (c->signature && c->signature[c->index]) {
1317 /* Container signature is already set */
1319 if (c->signature[c->index] != type)
1324 /* Maybe we can append to the signature? But only if this is the top-level container*/
1325 if (c->enclosing != 0)
1328 e = strextend(&c->signature, CHAR_TO_STR(type), NULL);
1337 case SD_BUS_TYPE_STRING:
1338 case SD_BUS_TYPE_OBJECT_PATH:
1341 sz = 4 + strlen(p) + 1;
1344 case SD_BUS_TYPE_SIGNATURE:
1347 sz = 1 + strlen(p) + 1;
1350 case SD_BUS_TYPE_BOOLEAN:
1353 assert_cc(sizeof(int) == sizeof(uint32_t));
1359 case SD_BUS_TYPE_UNIX_FD: {
1362 if (!m->allow_fds) {
1375 fd = fcntl(z, F_DUPFD_CLOEXEC, 3);
1381 f = realloc(m->fds, sizeof(int) * (m->n_fds + 1));
1396 align = bus_type_get_alignment(type);
1397 sz = bus_type_get_size(type);
1404 a = message_extend_body(m, align, sz);
1410 if (type == SD_BUS_TYPE_STRING || type == SD_BUS_TYPE_OBJECT_PATH) {
1411 *(uint32_t*) a = sz - 5;
1412 memcpy((uint8_t*) a + 4, p, sz - 4);
1415 *stored = (const uint8_t*) a + 4;
1417 } else if (type == SD_BUS_TYPE_SIGNATURE) {
1418 *(uint8_t*) a = sz - 1;
1419 memcpy((uint8_t*) a + 1, p, sz - 1);
1422 *stored = (const uint8_t*) a + 1;
1423 } else if (type == SD_BUS_TYPE_UNIX_FD) {
1424 *(uint32_t*) a = fdi;
1438 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1445 close_nointr_nofail(fd);
1450 int sd_bus_message_append_basic(sd_bus_message *m, char type, const void *p) {
1451 return message_append_basic(m, type, p, NULL);
1454 int sd_bus_message_append_string_space(sd_bus_message *m, size_t size, char **s) {
1455 struct bus_container *c;
1467 c = message_get_container(m);
1469 if (c->signature && c->signature[c->index]) {
1470 /* Container signature is already set */
1472 if (c->signature[c->index] != SD_BUS_TYPE_STRING)
1477 /* Maybe we can append to the signature? But only if this is the top-level container*/
1478 if (c->enclosing != 0)
1481 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRING), NULL);
1488 a = message_extend_body(m, 4, 4 + size + 1);
1492 *(uint32_t*) a = size;
1497 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1503 static int bus_message_open_array(
1505 struct bus_container *c,
1506 const char *contents,
1507 uint32_t **array_size) {
1513 struct bus_body_part *o;
1520 if (!signature_is_single(contents))
1523 alignment = bus_type_get_alignment(contents[0]);
1527 if (c->signature && c->signature[c->index]) {
1529 /* Verify the existing signature */
1531 if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
1534 if (!startswith(c->signature + c->index + 1, contents))
1537 nindex = c->index + 1 + strlen(contents);
1541 if (c->enclosing != 0)
1544 /* Extend the existing signature */
1546 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_ARRAY), contents, NULL);
1552 nindex = e - c->signature;
1555 a = message_extend_body(m, 4, 4);
1560 op = m->body_end->data;
1561 os = m->body_end->size;
1563 /* Add alignment between size and first element */
1564 if (!message_extend_body(m, alignment, 0))
1567 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1570 /* location of array size might have changed so let's readjust a */
1571 if (o == m->body_end)
1572 a = adjust_pointer(a, op, os, m->body_end->data);
1579 static int bus_message_open_variant(
1581 struct bus_container *c,
1582 const char *contents) {
1591 if (!signature_is_single(contents))
1594 if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
1597 if (c->signature && c->signature[c->index]) {
1599 if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
1605 if (c->enclosing != 0)
1608 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_VARIANT), NULL);
1615 l = strlen(contents);
1616 a = message_extend_body(m, 1, 1 + l + 1);
1621 memcpy((uint8_t*) a + 1, contents, l + 1);
1623 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1629 static int bus_message_open_struct(
1631 struct bus_container *c,
1632 const char *contents) {
1640 if (!signature_is_valid(contents, false))
1643 if (c->signature && c->signature[c->index]) {
1646 l = strlen(contents);
1648 if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
1649 !startswith(c->signature + c->index + 1, contents) ||
1650 c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
1653 nindex = c->index + 1 + l + 1;
1657 if (c->enclosing != 0)
1660 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_BEGIN), contents, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_END), NULL);
1666 nindex = e - c->signature;
1669 /* Align contents to 8 byte boundary */
1670 if (!message_extend_body(m, 8, 0))
1673 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1679 static int bus_message_open_dict_entry(
1681 struct bus_container *c,
1682 const char *contents) {
1690 if (!signature_is_pair(contents))
1693 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1696 if (c->signature && c->signature[c->index]) {
1699 l = strlen(contents);
1701 if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
1702 !startswith(c->signature + c->index + 1, contents) ||
1703 c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
1706 nindex = c->index + 1 + l + 1;
1710 /* Align contents to 8 byte boundary */
1711 if (!message_extend_body(m, 8, 0))
1714 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1720 int sd_bus_message_open_container(
1723 const char *contents) {
1725 struct bus_container *c, *w;
1726 uint32_t *array_size = NULL;
1740 /* Make sure we have space for one more container */
1741 w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
1749 c = message_get_container(m);
1751 signature = strdup(contents);
1757 /* Save old index in the parent container, in case we have to
1758 * abort this container */
1759 c->saved_index = c->index;
1760 before = m->header->body_size;
1762 if (type == SD_BUS_TYPE_ARRAY)
1763 r = bus_message_open_array(m, c, contents, &array_size);
1764 else if (type == SD_BUS_TYPE_VARIANT)
1765 r = bus_message_open_variant(m, c, contents);
1766 else if (type == SD_BUS_TYPE_STRUCT)
1767 r = bus_message_open_struct(m, c, contents);
1768 else if (type == SD_BUS_TYPE_DICT_ENTRY)
1769 r = bus_message_open_dict_entry(m, c, contents);
1778 /* OK, let's fill it in */
1779 w += m->n_containers++;
1780 w->enclosing = type;
1781 w->signature = signature;
1783 w->array_size = array_size;
1785 w->begin = m->rindex;
1790 int sd_bus_message_close_container(sd_bus_message *m) {
1791 struct bus_container *c;
1797 if (m->n_containers <= 0)
1802 c = message_get_container(m);
1803 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1804 if (c->signature && c->signature[c->index] != 0)
1819 static int type_stack_push(TypeStack *stack, unsigned max, unsigned *i, const char *types, unsigned n_struct, unsigned n_array) {
1826 stack[*i].types = types;
1827 stack[*i].n_struct = n_struct;
1828 stack[*i].n_array = n_array;
1834 static int type_stack_pop(TypeStack *stack, unsigned max, unsigned *i, const char **types, unsigned *n_struct, unsigned *n_array) {
1845 *types = stack[*i].types;
1846 *n_struct = stack[*i].n_struct;
1847 *n_array = stack[*i].n_array;
1852 int bus_message_append_ap(
1857 unsigned n_array, n_struct;
1858 TypeStack stack[BUS_CONTAINER_DEPTH];
1859 unsigned stack_ptr = 0;
1867 n_array = (unsigned) -1;
1868 n_struct = strlen(types);
1873 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
1874 r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
1880 r = sd_bus_message_close_container(m);
1888 if (n_array != (unsigned) -1)
1897 case SD_BUS_TYPE_BYTE: {
1900 x = (uint8_t) va_arg(ap, int);
1901 r = sd_bus_message_append_basic(m, *t, &x);
1905 case SD_BUS_TYPE_BOOLEAN:
1906 case SD_BUS_TYPE_INT32:
1907 case SD_BUS_TYPE_UINT32:
1908 case SD_BUS_TYPE_UNIX_FD: {
1911 /* We assume a boolean is the same as int32_t */
1912 assert_cc(sizeof(int32_t) == sizeof(int));
1914 x = va_arg(ap, uint32_t);
1915 r = sd_bus_message_append_basic(m, *t, &x);
1919 case SD_BUS_TYPE_INT16:
1920 case SD_BUS_TYPE_UINT16: {
1923 x = (uint16_t) va_arg(ap, int);
1924 r = sd_bus_message_append_basic(m, *t, &x);
1928 case SD_BUS_TYPE_INT64:
1929 case SD_BUS_TYPE_UINT64:
1930 case SD_BUS_TYPE_DOUBLE: {
1933 x = va_arg(ap, uint64_t);
1934 r = sd_bus_message_append_basic(m, *t, &x);
1938 case SD_BUS_TYPE_STRING:
1939 case SD_BUS_TYPE_OBJECT_PATH:
1940 case SD_BUS_TYPE_SIGNATURE: {
1943 x = va_arg(ap, const char*);
1944 r = sd_bus_message_append_basic(m, *t, x);
1948 case SD_BUS_TYPE_ARRAY: {
1951 r = signature_element_length(t + 1, &k);
1957 memcpy(s, t + 1, k);
1960 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, s);
1965 if (n_array == (unsigned) -1) {
1970 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
1976 n_array = va_arg(ap, unsigned);
1981 case SD_BUS_TYPE_VARIANT: {
1984 s = va_arg(ap, const char*);
1988 r = sd_bus_message_open_container(m, SD_BUS_TYPE_VARIANT, s);
1992 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
1997 n_struct = strlen(s);
1998 n_array = (unsigned) -1;
2003 case SD_BUS_TYPE_STRUCT_BEGIN:
2004 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
2007 r = signature_element_length(t, &k);
2014 memcpy(s, t + 1, k - 2);
2017 r = sd_bus_message_open_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
2022 if (n_array == (unsigned) -1) {
2027 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2033 n_array = (unsigned) -1;
2049 int sd_bus_message_append(sd_bus_message *m, const char *types, ...) {
2062 va_start(ap, types);
2063 r = bus_message_append_ap(m, types, ap);
2069 int sd_bus_message_append_array_space(sd_bus_message *m, char type, size_t size, void **ptr) {
2078 if (!bus_type_is_trivial(type))
2080 if (!ptr && size > 0)
2085 align = bus_type_get_alignment(type);
2086 sz = bus_type_get_size(type);
2088 assert_se(align > 0);
2094 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
2098 a = message_extend_body(m, align, size);
2102 r = sd_bus_message_close_container(m);
2110 int sd_bus_message_append_array(sd_bus_message *m, char type, const void *ptr, size_t size) {
2114 if (!ptr && size > 0)
2117 r = sd_bus_message_append_array_space(m, type, size, &p);
2122 memcpy(p, ptr, size);
2127 int sd_bus_message_append_array_memfd(sd_bus_message *m, char type, sd_memfd *memfd) {
2128 _cleanup_close_ int copy_fd = -1;
2129 struct bus_body_part *part;
2141 if (!bus_type_is_trivial(type))
2146 r = sd_memfd_set_sealed(memfd, true);
2150 copy_fd = sd_memfd_dup_fd(memfd);
2154 r = sd_memfd_get_size(memfd, &size);
2158 align = bus_type_get_alignment(type);
2159 sz = bus_type_get_size(type);
2161 assert_se(align > 0);
2167 if (size > (uint64_t) (uint32_t) -1)
2170 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
2174 a = message_extend_body(m, align, 0);
2178 part = message_append_part(m);
2182 part->memfd = copy_fd;
2183 part->sealed = true;
2187 message_extend_containers(m, size);
2188 m->header->body_size += size;
2190 return sd_bus_message_close_container(m);
2193 int sd_bus_message_append_string_memfd(sd_bus_message *m, sd_memfd *memfd) {
2194 _cleanup_close_ int copy_fd = -1;
2195 struct bus_body_part *part;
2196 struct bus_container *c;
2210 r = sd_memfd_set_sealed(memfd, true);
2214 copy_fd = sd_memfd_dup_fd(memfd);
2218 r = sd_memfd_get_size(memfd, &size);
2222 /* We require this to be NUL terminated */
2226 if (size > (uint64_t) (uint32_t) -1)
2229 c = message_get_container(m);
2230 if (c->signature && c->signature[c->index]) {
2231 /* Container signature is already set */
2233 if (c->signature[c->index] != SD_BUS_TYPE_STRING)
2238 /* Maybe we can append to the signature? But only if this is the top-level container*/
2239 if (c->enclosing != 0)
2242 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRING), NULL);
2249 a = message_extend_body(m, 4, 4);
2253 *(uint32_t*) a = size - 1;
2255 part = message_append_part(m);
2259 part->memfd = copy_fd;
2260 part->sealed = true;
2264 message_extend_containers(m, size);
2265 m->header->body_size += size;
2267 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2273 int bus_body_part_map(struct bus_body_part *part) {
2282 if (part->size <= 0)
2285 /* For smaller zero parts (as used for padding) we don't need to map anything... */
2286 if (part->memfd < 0 && part->is_zero && part->size < 8) {
2287 static const uint8_t zeroes[7] = { };
2288 part->data = (void*) zeroes;
2292 psz = PAGE_ALIGN(part->size);
2294 if (part->memfd >= 0)
2295 p = mmap(NULL, psz, PROT_READ, MAP_SHARED, part->memfd, 0);
2296 else if (part->is_zero)
2297 p = mmap(NULL, psz, PROT_READ, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
2301 if (p == MAP_FAILED)
2306 part->munmap_this = true;
2311 void bus_body_part_unmap(struct bus_body_part *part) {
2315 if (part->memfd < 0)
2321 if (!part->munmap_this)
2324 assert_se(munmap(part->data, part->mapped) == 0);
2328 part->munmap_this = false;
2333 static int buffer_peek(const void *p, uint32_t sz, size_t *rindex, size_t align, size_t nbytes, void **r) {
2334 size_t k, start, end;
2339 start = ALIGN_TO((size_t) *rindex, align);
2340 end = start + nbytes;
2345 /* Verify that padding is 0 */
2346 for (k = *rindex; k < start; k++)
2347 if (((const uint8_t*) p)[k] != 0)
2351 *r = (uint8_t*) p + start;
2358 static bool message_end_of_array(sd_bus_message *m, size_t index) {
2359 struct bus_container *c;
2363 c = message_get_container(m);
2367 return index >= c->begin + BUS_MESSAGE_BSWAP32(m, *c->array_size);
2370 static struct bus_body_part* find_part(sd_bus_message *m, size_t index, size_t sz, void **p) {
2371 struct bus_body_part *part;
2377 if (m->cached_rindex_part && index >= m->cached_rindex_part_begin) {
2378 part = m->cached_rindex_part;
2379 begin = m->cached_rindex_part_begin;
2389 if (index + sz <= begin + part->size) {
2391 r = bus_body_part_map(part);
2396 *p = (uint8_t*) part->data + index - begin;
2398 m->cached_rindex_part = part;
2399 m->cached_rindex_part_begin = begin;
2404 begin += part->size;
2411 static int message_peek_body(
2418 size_t k, start, end, padding;
2419 struct bus_body_part *part;
2426 if (message_end_of_array(m, *rindex))
2429 start = ALIGN_TO((size_t) *rindex, align);
2430 padding = start - *rindex;
2431 end = start + nbytes;
2433 if (end > BUS_MESSAGE_BODY_SIZE(m))
2436 part = find_part(m, *rindex, padding, (void**) &q);
2441 /* Verify padding */
2442 for (k = 0; k < padding; k++)
2447 part = find_part(m, start, nbytes, (void**) &q);
2459 static bool validate_nul(const char *s, size_t l) {
2461 /* Check for NUL chars in the string */
2462 if (memchr(s, 0, l))
2465 /* Check for NUL termination */
2472 static bool validate_string(const char *s, size_t l) {
2474 if (!validate_nul(s, l))
2477 /* Check if valid UTF8 */
2478 if (!utf8_is_valid(s))
2484 static bool validate_signature(const char *s, size_t l) {
2486 if (!validate_nul(s, l))
2489 /* Check if valid signature */
2490 if (!signature_is_valid(s, true))
2496 static bool validate_object_path(const char *s, size_t l) {
2498 if (!validate_nul(s, l))
2501 if (!object_path_is_valid(s))
2507 int sd_bus_message_read_basic(sd_bus_message *m, char type, void *p) {
2508 struct bus_container *c;
2516 if (!bus_type_is_basic(type))
2521 c = message_get_container(m);
2523 if (!c->signature || c->signature[c->index] == 0)
2526 if (c->signature[c->index] != type)
2531 case SD_BUS_TYPE_STRING:
2532 case SD_BUS_TYPE_OBJECT_PATH: {
2537 r = message_peek_body(m, &rindex, 4, 4, &q);
2541 l = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2542 r = message_peek_body(m, &rindex, 1, l+1, &q);
2548 if (type == SD_BUS_TYPE_OBJECT_PATH) {
2549 if (!validate_object_path(q, l))
2552 if (!validate_string(q, l))
2557 *(const char**) p = q;
2561 case SD_BUS_TYPE_SIGNATURE: {
2566 r = message_peek_body(m, &rindex, 1, 1, &q);
2571 r = message_peek_body(m, &rindex, 1, l+1, &q);
2577 if (!validate_signature(q, l))
2581 *(const char**) p = q;
2589 align = bus_type_get_alignment(type);
2590 sz = bus_type_get_size(type);
2591 assert(align > 0 && sz > 0);
2594 r = message_peek_body(m, &rindex, align, sz, &q);
2600 case SD_BUS_TYPE_BYTE:
2601 *(uint8_t*) p = *(uint8_t*) q;
2604 case SD_BUS_TYPE_BOOLEAN:
2605 *(int*) p = !!*(uint32_t*) q;
2608 case SD_BUS_TYPE_INT16:
2609 case SD_BUS_TYPE_UINT16:
2610 *(uint16_t*) p = BUS_MESSAGE_BSWAP16(m, *(uint16_t*) q);
2613 case SD_BUS_TYPE_INT32:
2614 case SD_BUS_TYPE_UINT32:
2615 *(uint32_t*) p = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2618 case SD_BUS_TYPE_INT64:
2619 case SD_BUS_TYPE_UINT64:
2620 case SD_BUS_TYPE_DOUBLE:
2621 *(uint64_t*) p = BUS_MESSAGE_BSWAP64(m, *(uint64_t*) q);
2624 case SD_BUS_TYPE_UNIX_FD: {
2627 j = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2631 *(int*) p = m->fds[j];
2636 assert_not_reached("Unknown basic type...");
2645 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2651 static int bus_message_enter_array(
2653 struct bus_container *c,
2654 const char *contents,
2655 uint32_t **array_size) {
2666 if (!signature_is_single(contents))
2669 alignment = bus_type_get_alignment(contents[0]);
2673 if (!c->signature || c->signature[c->index] == 0)
2676 if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
2679 if (!startswith(c->signature + c->index + 1, contents))
2683 r = message_peek_body(m, &rindex, 4, 4, &q);
2687 if (BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q) > BUS_ARRAY_MAX_SIZE)
2690 r = message_peek_body(m, &rindex, alignment, 0, NULL);
2696 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2697 c->index += 1 + strlen(contents);
2701 *array_size = (uint32_t*) q;
2706 static int bus_message_enter_variant(
2708 struct bus_container *c,
2709 const char *contents) {
2720 if (!signature_is_single(contents))
2723 if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
2726 if (!c->signature || c->signature[c->index] == 0)
2729 if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
2733 r = message_peek_body(m, &rindex, 1, 1, &q);
2738 r = message_peek_body(m, &rindex, 1, l+1, &q);
2744 if (!validate_signature(q, l))
2747 if (!streq(q, contents))
2750 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2758 static int bus_message_enter_struct(
2760 struct bus_container *c,
2761 const char *contents) {
2770 if (!signature_is_valid(contents, false))
2773 if (!c->signature || c->signature[c->index] == 0)
2776 l = strlen(contents);
2778 if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
2779 !startswith(c->signature + c->index + 1, contents) ||
2780 c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
2783 r = message_peek_body(m, &m->rindex, 8, 0, NULL);
2787 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2788 c->index += 1 + l + 1;
2793 static int bus_message_enter_dict_entry(
2795 struct bus_container *c,
2796 const char *contents) {
2805 if (!signature_is_pair(contents))
2808 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2811 if (!c->signature || c->signature[c->index] == 0)
2814 l = strlen(contents);
2816 if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
2817 !startswith(c->signature + c->index + 1, contents) ||
2818 c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
2821 r = message_peek_body(m, &m->rindex, 8, 0, NULL);
2825 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2826 c->index += 1 + l + 1;
2831 int sd_bus_message_enter_container(sd_bus_message *m, char type, const char *contents) {
2832 struct bus_container *c, *w;
2833 uint32_t *array_size = NULL;
2846 * We enforce a global limit on container depth, that is much
2847 * higher than the 32 structs and 32 arrays the specification
2848 * mandates. This is simpler to implement for us, and we need
2849 * this only to ensure our container array doesn't grow
2850 * without bounds. We are happy to return any data from a
2851 * message as long as the data itself is valid, even if the
2852 * overall message might be not.
2854 * Note that the message signature is validated when
2855 * parsing the headers, and that validation does check the
2858 * Note that the specification defines no limits on the depth
2859 * of stacked variants, but we do.
2861 if (m->n_containers >= BUS_CONTAINER_DEPTH)
2864 w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
2869 c = message_get_container(m);
2871 if (!c->signature || c->signature[c->index] == 0)
2874 signature = strdup(contents);
2878 c->saved_index = c->index;
2881 if (type == SD_BUS_TYPE_ARRAY)
2882 r = bus_message_enter_array(m, c, contents, &array_size);
2883 else if (type == SD_BUS_TYPE_VARIANT)
2884 r = bus_message_enter_variant(m, c, contents);
2885 else if (type == SD_BUS_TYPE_STRUCT)
2886 r = bus_message_enter_struct(m, c, contents);
2887 else if (type == SD_BUS_TYPE_DICT_ENTRY)
2888 r = bus_message_enter_dict_entry(m, c, contents);
2897 /* OK, let's fill it in */
2898 w += m->n_containers++;
2899 w->enclosing = type;
2900 w->signature = signature;
2902 w->array_size = array_size;
2904 w->begin = m->rindex;
2909 int sd_bus_message_exit_container(sd_bus_message *m) {
2910 struct bus_container *c;
2916 if (m->n_containers <= 0)
2919 c = message_get_container(m);
2920 if (c->enclosing == SD_BUS_TYPE_ARRAY) {
2923 l = BUS_MESSAGE_BSWAP32(m, *c->array_size);
2924 if (c->begin + l != m->rindex)
2928 if (c->signature && c->signature[c->index] != 0)
2938 static void message_quit_container(sd_bus_message *m) {
2939 struct bus_container *c;
2943 assert(m->n_containers > 0);
2945 c = message_get_container(m);
2948 assert(m->rindex >= c->before);
2949 m->rindex = c->before;
2951 /* Free container */
2955 /* Correct index of new top-level container */
2956 c = message_get_container(m);
2957 c->index = c->saved_index;
2960 int sd_bus_message_peek_type(sd_bus_message *m, char *type, const char **contents) {
2961 struct bus_container *c;
2969 c = message_get_container(m);
2971 if (!c->signature || c->signature[c->index] == 0)
2974 if (message_end_of_array(m, m->rindex))
2977 if (bus_type_is_basic(c->signature[c->index])) {
2981 *type = c->signature[c->index];
2985 if (c->signature[c->index] == SD_BUS_TYPE_ARRAY) {
2991 r = signature_element_length(c->signature+c->index+1, &l);
2997 sig = strndup(c->signature + c->index + 1, l);
3001 free(m->peeked_signature);
3002 m->peeked_signature = sig;
3008 *type = SD_BUS_TYPE_ARRAY;
3013 if (c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ||
3014 c->signature[c->index] == SD_BUS_TYPE_DICT_ENTRY_BEGIN) {
3020 r = signature_element_length(c->signature+c->index, &l);
3025 sig = strndup(c->signature + c->index + 1, l - 2);
3029 free(m->peeked_signature);
3030 m->peeked_signature = sig;
3036 *type = c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY;
3041 if (c->signature[c->index] == SD_BUS_TYPE_VARIANT) {
3047 r = message_peek_body(m, &rindex, 1, 1, &q);
3054 r = message_peek_body(m, &rindex, 1, l+1, &q);
3060 if (!validate_signature(q, l))
3067 *type = SD_BUS_TYPE_VARIANT;
3076 *type = c->enclosing;
3082 int sd_bus_message_rewind(sd_bus_message *m, int complete) {
3083 struct bus_container *c;
3091 message_reset_containers(m);
3093 m->root_container.index = 0;
3095 c = message_get_container(m);
3097 c = message_get_container(m);
3100 m->rindex = c->begin;
3103 return !isempty(c->signature);
3105 static int message_read_ap(
3110 unsigned n_array, n_struct;
3111 TypeStack stack[BUS_CONTAINER_DEPTH];
3112 unsigned stack_ptr = 0;
3120 /* Ideally, we'd just call ourselves recursively on every
3121 * complex type. However, the state of a va_list that is
3122 * passed to a function is undefined after that function
3123 * returns. This means we need to docode the va_list linearly
3124 * in a single stackframe. We hence implement our own
3125 * home-grown stack in an array. */
3127 n_array = (unsigned) -1;
3128 n_struct = strlen(types);
3133 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
3134 r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
3140 r = sd_bus_message_exit_container(m);
3148 if (n_array != (unsigned) -1)
3157 case SD_BUS_TYPE_BYTE:
3158 case SD_BUS_TYPE_BOOLEAN:
3159 case SD_BUS_TYPE_INT16:
3160 case SD_BUS_TYPE_UINT16:
3161 case SD_BUS_TYPE_INT32:
3162 case SD_BUS_TYPE_UINT32:
3163 case SD_BUS_TYPE_INT64:
3164 case SD_BUS_TYPE_UINT64:
3165 case SD_BUS_TYPE_DOUBLE:
3166 case SD_BUS_TYPE_STRING:
3167 case SD_BUS_TYPE_OBJECT_PATH:
3168 case SD_BUS_TYPE_SIGNATURE:
3169 case SD_BUS_TYPE_UNIX_FD: {
3172 p = va_arg(ap, void*);
3173 r = sd_bus_message_read_basic(m, *t, p);
3182 case SD_BUS_TYPE_ARRAY: {
3185 r = signature_element_length(t + 1, &k);
3191 memcpy(s, t + 1, k);
3194 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, s);
3201 if (n_array == (unsigned) -1) {
3206 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
3212 n_array = va_arg(ap, unsigned);
3217 case SD_BUS_TYPE_VARIANT: {
3220 s = va_arg(ap, const char *);
3224 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, s);
3230 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
3235 n_struct = strlen(s);
3236 n_array = (unsigned) -1;
3241 case SD_BUS_TYPE_STRUCT_BEGIN:
3242 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
3245 r = signature_element_length(t, &k);
3251 memcpy(s, t + 1, k - 2);
3254 r = sd_bus_message_enter_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
3261 if (n_array == (unsigned) -1) {
3266 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
3272 n_array = (unsigned) -1;
3285 int sd_bus_message_read(sd_bus_message *m, const char *types, ...) {
3296 va_start(ap, types);
3297 r = message_read_ap(m, types, ap);
3303 int sd_bus_message_read_array(sd_bus_message *m, char type, const void **ptr, size_t *size) {
3304 struct bus_container *c;
3314 if (!bus_type_is_trivial(type))
3320 if (BUS_MESSAGE_NEED_BSWAP(m))
3323 align = bus_type_get_alignment(type);
3327 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
3331 c = message_get_container(m);
3332 sz = BUS_MESSAGE_BSWAP32(m, *c->array_size);
3334 r = message_peek_body(m, &m->rindex, align, sz, &p);
3342 r = sd_bus_message_exit_container(m);
3346 *ptr = (const void*) p;
3352 message_quit_container(m);
3356 static int message_peek_fields(
3367 return buffer_peek(BUS_MESSAGE_FIELDS(m), BUS_MESSAGE_FIELDS_SIZE(m), rindex, align, nbytes, ret);
3370 static int message_peek_field_uint32(
3381 r = message_peek_fields(m, ri, 4, 4, &q);
3386 *ret = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
3391 static int message_peek_field_string(
3393 bool (*validate)(const char *p),
3404 r = message_peek_field_uint32(m, ri, &l);
3408 r = message_peek_fields(m, ri, 1, l+1, &q);
3413 if (!validate_nul(q, l))
3419 if (!validate_string(q, l))
3429 static int message_peek_field_signature(
3441 r = message_peek_fields(m, ri, 1, 1, &q);
3446 r = message_peek_fields(m, ri, 1, l+1, &q);
3450 if (!validate_signature(q, l))
3459 static int message_skip_fields(
3462 uint32_t array_size,
3463 const char **signature) {
3465 size_t original_index;
3472 original_index = *ri;
3478 if (array_size != (uint32_t) -1 &&
3479 array_size <= *ri - original_index)
3486 if (t == SD_BUS_TYPE_STRING) {
3488 r = message_peek_field_string(m, NULL, ri, NULL);
3494 } else if (t == SD_BUS_TYPE_OBJECT_PATH) {
3496 r = message_peek_field_string(m, object_path_is_valid, ri, NULL);
3502 } else if (t == SD_BUS_TYPE_SIGNATURE) {
3504 r = message_peek_field_signature(m, ri, NULL);
3510 } else if (bus_type_is_basic(t)) {
3513 align = bus_type_get_alignment(t);
3514 k = bus_type_get_size(t);
3515 assert(align > 0 && k > 0);
3517 r = message_peek_fields(m, ri, align, k, NULL);
3523 } else if (t == SD_BUS_TYPE_ARRAY) {
3525 r = signature_element_length(*signature+1, &l);
3535 strncpy(sig, *signature + 1, l-1);
3538 alignment = bus_type_get_alignment(sig[0]);
3542 r = message_peek_field_uint32(m, ri, &nas);
3545 if (nas > BUS_ARRAY_MAX_SIZE)
3548 r = message_peek_fields(m, ri, alignment, 0, NULL);
3552 r = message_skip_fields(m, ri, nas, (const char**) &s);
3557 (*signature) += 1 + l;
3559 } else if (t == SD_BUS_TYPE_VARIANT) {
3562 r = message_peek_field_signature(m, ri, &s);
3566 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
3572 } else if (t == SD_BUS_TYPE_STRUCT ||
3573 t == SD_BUS_TYPE_DICT_ENTRY) {
3575 r = signature_element_length(*signature, &l);
3582 strncpy(sig, *signature + 1, l-1);
3585 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
3596 int bus_message_parse_fields(sd_bus_message *m) {
3599 uint32_t unix_fds = 0;
3603 for (ri = 0; ri < BUS_MESSAGE_FIELDS_SIZE(m); ) {
3604 const char *signature;
3607 r = message_peek_fields(m, &ri, 8, 1, (void**) &header);
3611 r = message_peek_field_signature(m, &ri, &signature);
3616 case _SD_BUS_MESSAGE_HEADER_INVALID:
3619 case SD_BUS_MESSAGE_HEADER_PATH:
3624 if (!streq(signature, "o"))
3627 r = message_peek_field_string(m, object_path_is_valid, &ri, &m->path);
3630 case SD_BUS_MESSAGE_HEADER_INTERFACE:
3635 if (!streq(signature, "s"))
3638 r = message_peek_field_string(m, interface_name_is_valid, &ri, &m->interface);
3641 case SD_BUS_MESSAGE_HEADER_MEMBER:
3646 if (!streq(signature, "s"))
3649 r = message_peek_field_string(m, member_name_is_valid, &ri, &m->member);
3652 case SD_BUS_MESSAGE_HEADER_ERROR_NAME:
3657 if (!streq(signature, "s"))
3660 r = message_peek_field_string(m, error_name_is_valid, &ri, &m->error.name);
3663 case SD_BUS_MESSAGE_HEADER_DESTINATION:
3668 if (!streq(signature, "s"))
3671 r = message_peek_field_string(m, service_name_is_valid, &ri, &m->destination);
3674 case SD_BUS_MESSAGE_HEADER_SENDER:
3679 if (!streq(signature, "s"))
3682 r = message_peek_field_string(m, service_name_is_valid, &ri, &m->sender);
3686 case SD_BUS_MESSAGE_HEADER_SIGNATURE: {
3690 if (m->root_container.signature)
3693 if (!streq(signature, "g"))
3696 r = message_peek_field_signature(m, &ri, &s);
3704 free(m->root_container.signature);
3705 m->root_container.signature = c;
3709 case SD_BUS_MESSAGE_HEADER_REPLY_SERIAL:
3710 if (m->reply_serial != 0)
3713 if (!streq(signature, "u"))
3716 r = message_peek_field_uint32(m, &ri, &m->reply_serial);
3720 if (m->reply_serial == 0)
3725 case SD_BUS_MESSAGE_HEADER_UNIX_FDS:
3729 if (!streq(signature, "u"))
3732 r = message_peek_field_uint32(m, &ri, &unix_fds);
3742 r = message_skip_fields(m, &ri, (uint32_t) -1, (const char **) &signature);
3749 if (m->n_fds != unix_fds)
3752 if (isempty(m->root_container.signature) != (BUS_MESSAGE_BODY_SIZE(m) == 0))
3755 switch (m->header->type) {
3757 case SD_BUS_MESSAGE_TYPE_SIGNAL:
3758 if (!m->path || !m->interface || !m->member)
3762 case SD_BUS_MESSAGE_TYPE_METHOD_CALL:
3764 if (!m->path || !m->member)
3769 case SD_BUS_MESSAGE_TYPE_METHOD_RETURN:
3771 if (m->reply_serial == 0)
3775 case SD_BUS_MESSAGE_TYPE_METHOD_ERROR:
3777 if (m->reply_serial == 0 || !m->error.name)
3782 /* Try to read the error message, but if we can't it's a non-issue */
3783 if (m->header->type == SD_BUS_MESSAGE_TYPE_METHOD_ERROR)
3784 sd_bus_message_read(m, "s", &m->error.message);
3789 int bus_message_seal(sd_bus_message *m, uint64_t serial) {
3790 struct bus_body_part *part;
3800 if (m->n_containers > 0)
3806 /* If there's a non-trivial signature set, then add it in here */
3807 if (!isempty(m->root_container.signature)) {
3808 r = message_append_field_signature(m, SD_BUS_MESSAGE_HEADER_SIGNATURE, m->root_container.signature, NULL);
3814 r = message_append_field_uint32(m, SD_BUS_MESSAGE_HEADER_UNIX_FDS, m->n_fds);
3819 /* Add padding at the end of the fields part, since we know
3820 * the body needs to start at an 8 byte alignment. We made
3821 * sure we allocated enough space for this, so all we need to
3822 * do here is to zero it out. */
3823 l = BUS_MESSAGE_FIELDS_SIZE(m);
3826 memset((uint8_t*) BUS_MESSAGE_FIELDS(m) + l, 0, a);
3828 /* If this is something we can send as memfd, then let's seal
3829 the memfd now. Note that we can send memfds as payload only
3830 for directed messages, and not for broadcasts. */
3831 if (m->destination) {
3832 MESSAGE_FOREACH_PART(part, i, m)
3833 if (part->memfd >= 0 && !part->sealed && part->size > MEMFD_MIN_SIZE) {
3834 bus_body_part_unmap(part);
3836 if (ioctl(part->memfd, KDBUS_CMD_MEMFD_SEAL_SET, 1) >= 0)
3837 part->sealed = true;
3841 m->header->serial = serial;
3847 int sd_bus_message_set_destination(sd_bus_message *m, const char *destination) {
3857 return message_append_field_string(m, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &m->destination);
3860 int bus_message_dump(sd_bus_message *m) {
3861 const char *u = NULL, *uu = NULL, *s = NULL;
3862 char **cmdline = NULL;
3865 uid_t owner, audit_loginuid;
3866 uint32_t audit_sessionid;
3870 printf("Message %p\n"
3877 "\tfields_size=%u\n"
3882 "\tdestination=%s\n"
3885 "\treply_serial=%u\n"
3887 "\terror.message=%s\n"
3889 "\tn_body_parts=%u\n",
3896 BUS_MESSAGE_SERIAL(m),
3897 BUS_MESSAGE_FIELDS_SIZE(m),
3898 BUS_MESSAGE_BODY_SIZE(m),
3900 strna(m->interface),
3902 strna(m->destination),
3904 strna(m->root_container.signature),
3906 strna(m->error.name),
3907 strna(m->error.message),
3912 printf("\tpid=%lu\n", (unsigned long) m->pid);
3914 printf("\ttid=%lu\n", (unsigned long) m->tid);
3916 printf("\tuid=%lu\n", (unsigned long) m->uid);
3918 printf("\tgid=%lu\n", (unsigned long) m->gid);
3919 if (m->pid_starttime != 0)
3920 printf("\tpid_starttime=%llu\n", (unsigned long long) m->pid_starttime);
3921 if (m->monotonic != 0)
3922 printf("\tmonotonic=%llu\n", (unsigned long long) m->monotonic);
3923 if (m->realtime != 0)
3924 printf("\trealtime=%llu\n", (unsigned long long) m->realtime);
3926 printf("\texe=[%s]\n", m->exe);
3928 printf("\tcomm=[%s]\n", m->comm);
3930 printf("\ttid_comm=[%s]\n", m->tid_comm);
3932 printf("\tlabel=[%s]\n", m->label);
3934 printf("\tcgroup=[%s]\n", m->cgroup);
3936 sd_bus_message_get_unit(m, &u);
3938 printf("\tunit=[%s]\n", u);
3939 sd_bus_message_get_user_unit(m, &uu);
3941 printf("\tuser_unit=[%s]\n", uu);
3942 sd_bus_message_get_session(m, &s);
3944 printf("\tsession=[%s]\n", s);
3945 if (sd_bus_message_get_owner_uid(m, &owner) >= 0)
3946 printf("\towner_uid=%lu\n", (unsigned long) owner);
3947 if (sd_bus_message_get_audit_loginuid(m, &audit_loginuid) >= 0)
3948 printf("\taudit_loginuid=%lu\n", (unsigned long) audit_loginuid);
3949 if (sd_bus_message_get_audit_sessionid(m, &audit_sessionid) >= 0)
3950 printf("\taudit_sessionid=%lu\n", (unsigned long) audit_sessionid);
3952 printf("\tCAP_KILL=%i\n", sd_bus_message_has_effective_cap(m, 5));
3954 if (sd_bus_message_get_cmdline(m, &cmdline) >= 0) {
3957 fputs("\tcmdline=[", stdout);
3958 STRV_FOREACH(c, cmdline) {
3965 fputs("]\n", stdout);
3968 r = sd_bus_message_rewind(m, true);
3970 log_error("Failed to rewind: %s", strerror(-r));
3974 printf("BEGIN_MESSAGE \"%s\" {\n", strempty(m->root_container.signature));
3977 _cleanup_free_ char *prefix = NULL;
3978 const char *contents = NULL;
3993 r = sd_bus_message_peek_type(m, &type, &contents);
3995 log_error("Failed to peek type: %s", strerror(-r));
4002 r = sd_bus_message_exit_container(m);
4004 log_error("Failed to exit container: %s", strerror(-r));
4010 prefix = strrep("\t", level);
4014 if (type == SD_BUS_TYPE_ARRAY)
4015 printf("%s} END_ARRAY \n", prefix);
4016 else if (type == SD_BUS_TYPE_VARIANT)
4017 printf("%s} END_VARIANT\n", prefix);
4018 else if (type == SD_BUS_TYPE_STRUCT)
4019 printf("%s} END_STRUCT\n", prefix);
4020 else if (type == SD_BUS_TYPE_DICT_ENTRY)
4021 printf("%s} END_DICT_ENTRY\n", prefix);
4026 prefix = strrep("\t", level);
4030 if (bus_type_is_container(type) > 0) {
4031 r = sd_bus_message_enter_container(m, type, contents);
4033 log_error("Failed to enter container: %s", strerror(-r));
4037 if (type == SD_BUS_TYPE_ARRAY)
4038 printf("%sBEGIN_ARRAY \"%s\" {\n", prefix, contents);
4039 else if (type == SD_BUS_TYPE_VARIANT)
4040 printf("%sBEGIN_VARIANT \"%s\" {\n", prefix, contents);
4041 else if (type == SD_BUS_TYPE_STRUCT)
4042 printf("%sBEGIN_STRUCT \"%s\" {\n", prefix, contents);
4043 else if (type == SD_BUS_TYPE_DICT_ENTRY)
4044 printf("%sBEGIN_DICT_ENTRY \"%s\" {\n", prefix, contents);
4051 r = sd_bus_message_read_basic(m, type, &basic);
4053 log_error("Failed to get basic: %s", strerror(-r));
4059 case SD_BUS_TYPE_BYTE:
4060 printf("%sBYTE: %u\n", prefix, basic.u8);
4063 case SD_BUS_TYPE_BOOLEAN:
4064 printf("%sBOOLEAN: %s\n", prefix, yes_no(basic.i));
4067 case SD_BUS_TYPE_INT16:
4068 printf("%sINT16: %i\n", prefix, basic.s16);
4071 case SD_BUS_TYPE_UINT16:
4072 printf("%sUINT16: %u\n", prefix, basic.u16);
4075 case SD_BUS_TYPE_INT32:
4076 printf("%sINT32: %i\n", prefix, basic.s32);
4079 case SD_BUS_TYPE_UINT32:
4080 printf("%sUINT32: %u\n", prefix, basic.u32);
4083 case SD_BUS_TYPE_INT64:
4084 printf("%sINT64: %lli\n", prefix, (long long) basic.s64);
4087 case SD_BUS_TYPE_UINT64:
4088 printf("%sUINT64: %llu\n", prefix, (unsigned long long) basic.u64);
4091 case SD_BUS_TYPE_DOUBLE:
4092 printf("%sDOUBLE: %g\n", prefix, basic.d64);
4095 case SD_BUS_TYPE_STRING:
4096 printf("%sSTRING: \"%s\"\n", prefix, basic.string);
4099 case SD_BUS_TYPE_OBJECT_PATH:
4100 printf("%sOBJECT_PATH: \"%s\"\n", prefix, basic.string);
4103 case SD_BUS_TYPE_SIGNATURE:
4104 printf("%sSIGNATURE: \"%s\"\n", prefix, basic.string);
4107 case SD_BUS_TYPE_UNIX_FD:
4108 printf("%sUNIX_FD: %i\n", prefix, basic.i);
4112 assert_not_reached("Unknown basic type.");
4116 printf("} END_MESSAGE\n");
4120 int bus_message_get_blob(sd_bus_message *m, void **buffer, size_t *sz) {
4124 struct bus_body_part *part;
4130 total = BUS_MESSAGE_SIZE(m);
4136 e = mempcpy(p, m->header, BUS_MESSAGE_BODY_BEGIN(m));
4137 MESSAGE_FOREACH_PART(part, i, m)
4138 e = mempcpy(e, part->data, part->size);
4140 assert(total == (size_t) ((uint8_t*) e - (uint8_t*) p));
4148 int bus_message_read_strv_extend(sd_bus_message *m, char ***l) {
4154 r = sd_bus_message_enter_container(m, 'a', "s");
4161 r = sd_bus_message_read_basic(m, 's', &s);
4167 r = strv_extend(l, s);
4172 r = sd_bus_message_exit_container(m);
4179 const char* bus_message_get_arg(sd_bus_message *m, unsigned i) {
4181 const char *t = NULL;
4186 r = sd_bus_message_rewind(m, true);
4190 for (j = 0; j <= i; j++) {
4193 r = sd_bus_message_peek_type(m, &type, NULL);
4197 if (type != SD_BUS_TYPE_STRING &&
4198 type != SD_BUS_TYPE_OBJECT_PATH &&
4199 type != SD_BUS_TYPE_SIGNATURE)
4202 r = sd_bus_message_read_basic(m, type, &t);
4210 bool bus_header_is_complete(struct bus_header *h, size_t size) {
4216 if (size < sizeof(struct bus_header))
4219 full = sizeof(struct bus_header) +
4220 (h->endian == SD_BUS_NATIVE_ENDIAN ? h->fields_size : bswap_32(h->fields_size));
4222 return size >= full;
4225 int bus_header_message_size(struct bus_header *h, size_t *sum) {
4231 if (h->endian == SD_BUS_NATIVE_ENDIAN) {
4232 fs = h->fields_size;
4234 } else if (h->endian == SD_BUS_REVERSE_ENDIAN) {
4235 fs = bswap_32(h->fields_size);
4236 bs = bswap_32(h->body_size);
4240 *sum = sizeof(struct bus_header) + ALIGN8(fs) + bs;