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;
1310 if (!bus_type_is_basic(type))
1315 c = message_get_container(m);
1317 if (c->signature && c->signature[c->index]) {
1318 /* Container signature is already set */
1320 if (c->signature[c->index] != type)
1323 /* Maybe we can append to the signature? But only if this is the top-level container*/
1324 if (c->enclosing != 0)
1327 e = strextend(&c->signature, CHAR_TO_STR(type), NULL);
1336 case SD_BUS_TYPE_STRING:
1337 case SD_BUS_TYPE_OBJECT_PATH:
1340 sz = 4 + strlen(p) + 1;
1343 case SD_BUS_TYPE_SIGNATURE:
1346 sz = 1 + strlen(p) + 1;
1349 case SD_BUS_TYPE_BOOLEAN:
1352 assert_cc(sizeof(int) == sizeof(uint32_t));
1358 case SD_BUS_TYPE_UNIX_FD: {
1361 if (!m->allow_fds) {
1374 fd = fcntl(z, F_DUPFD_CLOEXEC, 3);
1380 f = realloc(m->fds, sizeof(int) * (m->n_fds + 1));
1395 align = bus_type_get_alignment(type);
1396 sz = bus_type_get_size(type);
1403 a = message_extend_body(m, align, sz);
1409 if (type == SD_BUS_TYPE_STRING || type == SD_BUS_TYPE_OBJECT_PATH) {
1410 *(uint32_t*) a = sz - 5;
1411 memcpy((uint8_t*) a + 4, p, sz - 4);
1414 *stored = (const uint8_t*) a + 4;
1416 } else if (type == SD_BUS_TYPE_SIGNATURE) {
1417 *(uint8_t*) a = sz - 1;
1418 memcpy((uint8_t*) a + 1, p, sz - 1);
1421 *stored = (const uint8_t*) a + 1;
1422 } else if (type == SD_BUS_TYPE_UNIX_FD) {
1423 *(uint32_t*) a = fdi;
1437 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1444 close_nointr_nofail(fd);
1449 int sd_bus_message_append_basic(sd_bus_message *m, char type, const void *p) {
1450 return message_append_basic(m, type, p, NULL);
1453 int sd_bus_message_append_string_space(sd_bus_message *m, size_t size, char **s) {
1454 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)
1475 /* Maybe we can append to the signature? But only if this is the top-level container*/
1476 if (c->enclosing != 0)
1479 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRING), NULL);
1487 a = message_extend_body(m, 4, 4 + size + 1);
1491 *(uint32_t*) a = size;
1496 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1502 static int bus_message_open_array(
1504 struct bus_container *c,
1505 const char *contents,
1506 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);
1539 if (c->enclosing != 0)
1542 /* Extend the existing signature */
1544 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_ARRAY), contents, NULL);
1550 nindex = e - c->signature;
1553 a = message_extend_body(m, 4, 4);
1558 op = m->body_end->data;
1559 os = m->body_end->size;
1561 /* Add alignment between size and first element */
1562 if (!message_extend_body(m, alignment, 0))
1565 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1568 /* location of array size might have changed so let's readjust a */
1569 if (o == m->body_end)
1570 a = adjust_pointer(a, op, os, m->body_end->data);
1577 static int bus_message_open_variant(
1579 struct bus_container *c,
1580 const char *contents) {
1590 if (!signature_is_single(contents))
1593 if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
1596 if (c->signature && c->signature[c->index]) {
1598 if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
1602 if (c->enclosing != 0)
1605 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_VARIANT), NULL);
1612 l = strlen(contents);
1613 a = message_extend_body(m, 1, 1 + l + 1);
1618 memcpy((uint8_t*) a + 1, contents, l + 1);
1620 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1626 static int bus_message_open_struct(
1628 struct bus_container *c,
1629 const char *contents) {
1638 if (!signature_is_valid(contents, false))
1641 if (c->signature && c->signature[c->index]) {
1644 l = strlen(contents);
1646 if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
1647 !startswith(c->signature + c->index + 1, contents) ||
1648 c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
1651 nindex = c->index + 1 + l + 1;
1653 if (c->enclosing != 0)
1656 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_BEGIN), contents, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_END), NULL);
1662 nindex = e - c->signature;
1665 /* Align contents to 8 byte boundary */
1666 if (!message_extend_body(m, 8, 0))
1669 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1675 static int bus_message_open_dict_entry(
1677 struct bus_container *c,
1678 const char *contents) {
1686 if (!signature_is_pair(contents))
1689 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1692 if (c->signature && c->signature[c->index]) {
1695 l = strlen(contents);
1697 if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
1698 !startswith(c->signature + c->index + 1, contents) ||
1699 c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
1702 nindex = c->index + 1 + l + 1;
1706 /* Align contents to 8 byte boundary */
1707 if (!message_extend_body(m, 8, 0))
1710 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1716 int sd_bus_message_open_container(
1719 const char *contents) {
1721 struct bus_container *c, *w;
1722 uint32_t *array_size = NULL;
1736 /* Make sure we have space for one more container */
1737 w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
1745 c = message_get_container(m);
1747 signature = strdup(contents);
1753 /* Save old index in the parent container, in case we have to
1754 * abort this container */
1755 c->saved_index = c->index;
1756 before = m->header->body_size;
1758 if (type == SD_BUS_TYPE_ARRAY)
1759 r = bus_message_open_array(m, c, contents, &array_size);
1760 else if (type == SD_BUS_TYPE_VARIANT)
1761 r = bus_message_open_variant(m, c, contents);
1762 else if (type == SD_BUS_TYPE_STRUCT)
1763 r = bus_message_open_struct(m, c, contents);
1764 else if (type == SD_BUS_TYPE_DICT_ENTRY)
1765 r = bus_message_open_dict_entry(m, c, contents);
1774 /* OK, let's fill it in */
1775 w += m->n_containers++;
1776 w->enclosing = type;
1777 w->signature = signature;
1779 w->array_size = array_size;
1781 w->begin = m->rindex;
1786 int sd_bus_message_close_container(sd_bus_message *m) {
1787 struct bus_container *c;
1793 if (m->n_containers <= 0)
1798 c = message_get_container(m);
1799 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1800 if (c->signature && c->signature[c->index] != 0)
1815 static int type_stack_push(TypeStack *stack, unsigned max, unsigned *i, const char *types, unsigned n_struct, unsigned n_array) {
1822 stack[*i].types = types;
1823 stack[*i].n_struct = n_struct;
1824 stack[*i].n_array = n_array;
1830 static int type_stack_pop(TypeStack *stack, unsigned max, unsigned *i, const char **types, unsigned *n_struct, unsigned *n_array) {
1841 *types = stack[*i].types;
1842 *n_struct = stack[*i].n_struct;
1843 *n_array = stack[*i].n_array;
1848 int bus_message_append_ap(
1853 unsigned n_array, n_struct;
1854 TypeStack stack[BUS_CONTAINER_DEPTH];
1855 unsigned stack_ptr = 0;
1863 n_array = (unsigned) -1;
1864 n_struct = strlen(types);
1869 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
1870 r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
1876 r = sd_bus_message_close_container(m);
1884 if (n_array != (unsigned) -1)
1893 case SD_BUS_TYPE_BYTE: {
1896 x = (uint8_t) va_arg(ap, int);
1897 r = sd_bus_message_append_basic(m, *t, &x);
1901 case SD_BUS_TYPE_BOOLEAN:
1902 case SD_BUS_TYPE_INT32:
1903 case SD_BUS_TYPE_UINT32:
1904 case SD_BUS_TYPE_UNIX_FD: {
1907 /* We assume a boolean is the same as int32_t */
1908 assert_cc(sizeof(int32_t) == sizeof(int));
1910 x = va_arg(ap, uint32_t);
1911 r = sd_bus_message_append_basic(m, *t, &x);
1915 case SD_BUS_TYPE_INT16:
1916 case SD_BUS_TYPE_UINT16: {
1919 x = (uint16_t) va_arg(ap, int);
1920 r = sd_bus_message_append_basic(m, *t, &x);
1924 case SD_BUS_TYPE_INT64:
1925 case SD_BUS_TYPE_UINT64:
1926 case SD_BUS_TYPE_DOUBLE: {
1929 x = va_arg(ap, uint64_t);
1930 r = sd_bus_message_append_basic(m, *t, &x);
1934 case SD_BUS_TYPE_STRING:
1935 case SD_BUS_TYPE_OBJECT_PATH:
1936 case SD_BUS_TYPE_SIGNATURE: {
1939 x = va_arg(ap, const char*);
1940 r = sd_bus_message_append_basic(m, *t, x);
1944 case SD_BUS_TYPE_ARRAY: {
1947 r = signature_element_length(t + 1, &k);
1953 memcpy(s, t + 1, k);
1956 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, s);
1961 if (n_array == (unsigned) -1) {
1966 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
1972 n_array = va_arg(ap, unsigned);
1977 case SD_BUS_TYPE_VARIANT: {
1980 s = va_arg(ap, const char*);
1984 r = sd_bus_message_open_container(m, SD_BUS_TYPE_VARIANT, s);
1988 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
1993 n_struct = strlen(s);
1994 n_array = (unsigned) -1;
1999 case SD_BUS_TYPE_STRUCT_BEGIN:
2000 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
2003 r = signature_element_length(t, &k);
2010 memcpy(s, t + 1, k - 2);
2013 r = sd_bus_message_open_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
2018 if (n_array == (unsigned) -1) {
2023 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2029 n_array = (unsigned) -1;
2045 int sd_bus_message_append(sd_bus_message *m, const char *types, ...) {
2058 va_start(ap, types);
2059 r = bus_message_append_ap(m, types, ap);
2065 int sd_bus_message_append_array_space(sd_bus_message *m, char type, size_t size, void **ptr) {
2074 if (!bus_type_is_trivial(type))
2076 if (!ptr && size > 0)
2081 align = bus_type_get_alignment(type);
2082 sz = bus_type_get_size(type);
2084 assert_se(align > 0);
2090 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
2094 a = message_extend_body(m, align, size);
2098 r = sd_bus_message_close_container(m);
2106 int sd_bus_message_append_array(sd_bus_message *m, char type, const void *ptr, size_t size) {
2110 if (!ptr && size > 0)
2113 r = sd_bus_message_append_array_space(m, type, size, &p);
2118 memcpy(p, ptr, size);
2123 int sd_bus_message_append_array_memfd(sd_bus_message *m, char type, sd_memfd *memfd) {
2124 _cleanup_close_ int copy_fd = -1;
2125 struct bus_body_part *part;
2137 if (!bus_type_is_trivial(type))
2142 r = sd_memfd_set_sealed(memfd, true);
2146 copy_fd = sd_memfd_dup_fd(memfd);
2150 r = sd_memfd_get_size(memfd, &size);
2154 align = bus_type_get_alignment(type);
2155 sz = bus_type_get_size(type);
2157 assert_se(align > 0);
2163 if (size > (size_t) (uint32_t) -1)
2166 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
2170 a = message_extend_body(m, align, 0);
2174 part = message_append_part(m);
2178 part->memfd = copy_fd;
2179 part->sealed = true;
2183 message_extend_containers(m, size);
2184 m->header->body_size += size;
2186 return sd_bus_message_close_container(m);
2189 int bus_body_part_map(struct bus_body_part *part) {
2198 if (part->size <= 0)
2201 /* For smaller zero parts (as used for padding) we don't need to map anything... */
2202 if (part->memfd < 0 && part->is_zero && part->size < 8) {
2203 static const uint8_t zeroes[7] = { };
2204 part->data = (void*) zeroes;
2208 psz = PAGE_ALIGN(part->size);
2210 if (part->memfd >= 0)
2211 p = mmap(NULL, psz, PROT_READ, MAP_SHARED, part->memfd, 0);
2212 else if (part->is_zero)
2213 p = mmap(NULL, psz, PROT_READ, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
2217 if (p == MAP_FAILED)
2222 part->munmap_this = true;
2227 void bus_body_part_unmap(struct bus_body_part *part) {
2231 if (part->memfd < 0)
2237 if (!part->munmap_this)
2240 assert_se(munmap(part->data, part->mapped) == 0);
2244 part->munmap_this = false;
2249 static int buffer_peek(const void *p, uint32_t sz, size_t *rindex, size_t align, size_t nbytes, void **r) {
2250 size_t k, start, end;
2255 start = ALIGN_TO((size_t) *rindex, align);
2256 end = start + nbytes;
2261 /* Verify that padding is 0 */
2262 for (k = *rindex; k < start; k++)
2263 if (((const uint8_t*) p)[k] != 0)
2267 *r = (uint8_t*) p + start;
2274 static bool message_end_of_array(sd_bus_message *m, size_t index) {
2275 struct bus_container *c;
2279 c = message_get_container(m);
2283 return index >= c->begin + BUS_MESSAGE_BSWAP32(m, *c->array_size);
2286 static struct bus_body_part* find_part(sd_bus_message *m, size_t index, size_t sz, void **p) {
2287 struct bus_body_part *part;
2293 if (m->cached_rindex_part && index >= m->cached_rindex_part_begin) {
2294 part = m->cached_rindex_part;
2295 begin = m->cached_rindex_part_begin;
2305 if (index + sz <= begin + part->size) {
2307 r = bus_body_part_map(part);
2312 *p = (uint8_t*) part->data + index - begin;
2314 m->cached_rindex_part = part;
2315 m->cached_rindex_part_begin = begin;
2320 begin += part->size;
2327 static int message_peek_body(
2334 size_t k, start, end, padding;
2335 struct bus_body_part *part;
2342 if (message_end_of_array(m, *rindex))
2345 start = ALIGN_TO((size_t) *rindex, align);
2346 padding = start - *rindex;
2347 end = start + nbytes;
2349 if (end > BUS_MESSAGE_BODY_SIZE(m))
2352 part = find_part(m, *rindex, padding, (void**) &q);
2357 /* Verify padding */
2358 for (k = 0; k < padding; k++)
2363 part = find_part(m, start, nbytes, (void**) &q);
2375 static bool validate_nul(const char *s, size_t l) {
2377 /* Check for NUL chars in the string */
2378 if (memchr(s, 0, l))
2381 /* Check for NUL termination */
2388 static bool validate_string(const char *s, size_t l) {
2390 if (!validate_nul(s, l))
2393 /* Check if valid UTF8 */
2394 if (!utf8_is_valid(s))
2400 static bool validate_signature(const char *s, size_t l) {
2402 if (!validate_nul(s, l))
2405 /* Check if valid signature */
2406 if (!signature_is_valid(s, true))
2412 static bool validate_object_path(const char *s, size_t l) {
2414 if (!validate_nul(s, l))
2417 if (!object_path_is_valid(s))
2423 int sd_bus_message_read_basic(sd_bus_message *m, char type, void *p) {
2424 struct bus_container *c;
2432 if (!bus_type_is_basic(type))
2437 c = message_get_container(m);
2439 if (!c->signature || c->signature[c->index] == 0)
2442 if (c->signature[c->index] != type)
2447 case SD_BUS_TYPE_STRING:
2448 case SD_BUS_TYPE_OBJECT_PATH: {
2453 r = message_peek_body(m, &rindex, 4, 4, &q);
2457 l = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2458 r = message_peek_body(m, &rindex, 1, l+1, &q);
2464 if (type == SD_BUS_TYPE_OBJECT_PATH) {
2465 if (!validate_object_path(q, l))
2468 if (!validate_string(q, l))
2473 *(const char**) p = q;
2477 case SD_BUS_TYPE_SIGNATURE: {
2482 r = message_peek_body(m, &rindex, 1, 1, &q);
2487 r = message_peek_body(m, &rindex, 1, l+1, &q);
2493 if (!validate_signature(q, l))
2497 *(const char**) p = q;
2505 align = bus_type_get_alignment(type);
2506 sz = bus_type_get_size(type);
2507 assert(align > 0 && sz > 0);
2510 r = message_peek_body(m, &rindex, align, sz, &q);
2516 case SD_BUS_TYPE_BYTE:
2517 *(uint8_t*) p = *(uint8_t*) q;
2520 case SD_BUS_TYPE_BOOLEAN:
2521 *(int*) p = !!*(uint32_t*) q;
2524 case SD_BUS_TYPE_INT16:
2525 case SD_BUS_TYPE_UINT16:
2526 *(uint16_t*) p = BUS_MESSAGE_BSWAP16(m, *(uint16_t*) q);
2529 case SD_BUS_TYPE_INT32:
2530 case SD_BUS_TYPE_UINT32:
2531 *(uint32_t*) p = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2534 case SD_BUS_TYPE_INT64:
2535 case SD_BUS_TYPE_UINT64:
2536 case SD_BUS_TYPE_DOUBLE:
2537 *(uint64_t*) p = BUS_MESSAGE_BSWAP64(m, *(uint64_t*) q);
2540 case SD_BUS_TYPE_UNIX_FD: {
2543 j = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2547 *(int*) p = m->fds[j];
2552 assert_not_reached("Unknown basic type...");
2561 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2567 static int bus_message_enter_array(
2569 struct bus_container *c,
2570 const char *contents,
2571 uint32_t **array_size) {
2582 if (!signature_is_single(contents))
2585 alignment = bus_type_get_alignment(contents[0]);
2589 if (!c->signature || c->signature[c->index] == 0)
2592 if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
2595 if (!startswith(c->signature + c->index + 1, contents))
2599 r = message_peek_body(m, &rindex, 4, 4, &q);
2603 if (BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q) > BUS_ARRAY_MAX_SIZE)
2606 r = message_peek_body(m, &rindex, alignment, 0, NULL);
2612 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2613 c->index += 1 + strlen(contents);
2617 *array_size = (uint32_t*) q;
2622 static int bus_message_enter_variant(
2624 struct bus_container *c,
2625 const char *contents) {
2636 if (!signature_is_single(contents))
2639 if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
2642 if (!c->signature || c->signature[c->index] == 0)
2645 if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
2649 r = message_peek_body(m, &rindex, 1, 1, &q);
2654 r = message_peek_body(m, &rindex, 1, l+1, &q);
2660 if (!validate_signature(q, l))
2663 if (!streq(q, contents))
2666 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2674 static int bus_message_enter_struct(
2676 struct bus_container *c,
2677 const char *contents) {
2686 if (!signature_is_valid(contents, false))
2689 if (!c->signature || c->signature[c->index] == 0)
2692 l = strlen(contents);
2694 if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
2695 !startswith(c->signature + c->index + 1, contents) ||
2696 c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
2699 r = message_peek_body(m, &m->rindex, 8, 0, NULL);
2703 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2704 c->index += 1 + l + 1;
2709 static int bus_message_enter_dict_entry(
2711 struct bus_container *c,
2712 const char *contents) {
2721 if (!signature_is_pair(contents))
2724 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2727 if (!c->signature || c->signature[c->index] == 0)
2730 l = strlen(contents);
2732 if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
2733 !startswith(c->signature + c->index + 1, contents) ||
2734 c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
2737 r = message_peek_body(m, &m->rindex, 8, 0, NULL);
2741 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2742 c->index += 1 + l + 1;
2747 int sd_bus_message_enter_container(sd_bus_message *m, char type, const char *contents) {
2748 struct bus_container *c, *w;
2749 uint32_t *array_size = NULL;
2762 * We enforce a global limit on container depth, that is much
2763 * higher than the 32 structs and 32 arrays the specification
2764 * mandates. This is simpler to implement for us, and we need
2765 * this only to ensure our container array doesn't grow
2766 * without bounds. We are happy to return any data from a
2767 * message as long as the data itself is valid, even if the
2768 * overall message might be not.
2770 * Note that the message signature is validated when
2771 * parsing the headers, and that validation does check the
2774 * Note that the specification defines no limits on the depth
2775 * of stacked variants, but we do.
2777 if (m->n_containers >= BUS_CONTAINER_DEPTH)
2780 w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
2785 c = message_get_container(m);
2787 if (!c->signature || c->signature[c->index] == 0)
2790 signature = strdup(contents);
2794 c->saved_index = c->index;
2797 if (type == SD_BUS_TYPE_ARRAY)
2798 r = bus_message_enter_array(m, c, contents, &array_size);
2799 else if (type == SD_BUS_TYPE_VARIANT)
2800 r = bus_message_enter_variant(m, c, contents);
2801 else if (type == SD_BUS_TYPE_STRUCT)
2802 r = bus_message_enter_struct(m, c, contents);
2803 else if (type == SD_BUS_TYPE_DICT_ENTRY)
2804 r = bus_message_enter_dict_entry(m, c, contents);
2813 /* OK, let's fill it in */
2814 w += m->n_containers++;
2815 w->enclosing = type;
2816 w->signature = signature;
2818 w->array_size = array_size;
2820 w->begin = m->rindex;
2825 int sd_bus_message_exit_container(sd_bus_message *m) {
2826 struct bus_container *c;
2832 if (m->n_containers <= 0)
2835 c = message_get_container(m);
2836 if (c->enclosing == SD_BUS_TYPE_ARRAY) {
2839 l = BUS_MESSAGE_BSWAP32(m, *c->array_size);
2840 if (c->begin + l != m->rindex)
2844 if (c->signature && c->signature[c->index] != 0)
2854 static void message_quit_container(sd_bus_message *m) {
2855 struct bus_container *c;
2859 assert(m->n_containers > 0);
2861 c = message_get_container(m);
2864 assert(m->rindex >= c->before);
2865 m->rindex = c->before;
2867 /* Free container */
2871 /* Correct index of new top-level container */
2872 c = message_get_container(m);
2873 c->index = c->saved_index;
2876 int sd_bus_message_peek_type(sd_bus_message *m, char *type, const char **contents) {
2877 struct bus_container *c;
2885 c = message_get_container(m);
2887 if (!c->signature || c->signature[c->index] == 0)
2890 if (message_end_of_array(m, m->rindex))
2893 if (bus_type_is_basic(c->signature[c->index])) {
2897 *type = c->signature[c->index];
2901 if (c->signature[c->index] == SD_BUS_TYPE_ARRAY) {
2907 r = signature_element_length(c->signature+c->index+1, &l);
2913 sig = strndup(c->signature + c->index + 1, l);
2917 free(m->peeked_signature);
2918 m->peeked_signature = sig;
2924 *type = SD_BUS_TYPE_ARRAY;
2929 if (c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ||
2930 c->signature[c->index] == SD_BUS_TYPE_DICT_ENTRY_BEGIN) {
2936 r = signature_element_length(c->signature+c->index, &l);
2941 sig = strndup(c->signature + c->index + 1, l - 2);
2945 free(m->peeked_signature);
2946 m->peeked_signature = sig;
2952 *type = c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY;
2957 if (c->signature[c->index] == SD_BUS_TYPE_VARIANT) {
2963 r = message_peek_body(m, &rindex, 1, 1, &q);
2970 r = message_peek_body(m, &rindex, 1, l+1, &q);
2976 if (!validate_signature(q, l))
2983 *type = SD_BUS_TYPE_VARIANT;
2992 *type = c->enclosing;
2998 int sd_bus_message_rewind(sd_bus_message *m, int complete) {
2999 struct bus_container *c;
3007 message_reset_containers(m);
3009 m->root_container.index = 0;
3011 c = message_get_container(m);
3013 c = message_get_container(m);
3016 m->rindex = c->begin;
3019 return !isempty(c->signature);
3021 static int message_read_ap(
3026 unsigned n_array, n_struct;
3027 TypeStack stack[BUS_CONTAINER_DEPTH];
3028 unsigned stack_ptr = 0;
3036 /* Ideally, we'd just call ourselves recursively on every
3037 * complex type. However, the state of a va_list that is
3038 * passed to a function is undefined after that function
3039 * returns. This means we need to docode the va_list linearly
3040 * in a single stackframe. We hence implement our own
3041 * home-grown stack in an array. */
3043 n_array = (unsigned) -1;
3044 n_struct = strlen(types);
3049 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
3050 r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
3056 r = sd_bus_message_exit_container(m);
3064 if (n_array != (unsigned) -1)
3073 case SD_BUS_TYPE_BYTE:
3074 case SD_BUS_TYPE_BOOLEAN:
3075 case SD_BUS_TYPE_INT16:
3076 case SD_BUS_TYPE_UINT16:
3077 case SD_BUS_TYPE_INT32:
3078 case SD_BUS_TYPE_UINT32:
3079 case SD_BUS_TYPE_INT64:
3080 case SD_BUS_TYPE_UINT64:
3081 case SD_BUS_TYPE_DOUBLE:
3082 case SD_BUS_TYPE_STRING:
3083 case SD_BUS_TYPE_OBJECT_PATH:
3084 case SD_BUS_TYPE_SIGNATURE:
3085 case SD_BUS_TYPE_UNIX_FD: {
3088 p = va_arg(ap, void*);
3089 r = sd_bus_message_read_basic(m, *t, p);
3098 case SD_BUS_TYPE_ARRAY: {
3101 r = signature_element_length(t + 1, &k);
3107 memcpy(s, t + 1, k);
3110 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, s);
3117 if (n_array == (unsigned) -1) {
3122 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
3128 n_array = va_arg(ap, unsigned);
3133 case SD_BUS_TYPE_VARIANT: {
3136 s = va_arg(ap, const char *);
3140 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, s);
3146 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
3151 n_struct = strlen(s);
3152 n_array = (unsigned) -1;
3157 case SD_BUS_TYPE_STRUCT_BEGIN:
3158 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
3161 r = signature_element_length(t, &k);
3167 memcpy(s, t + 1, k - 2);
3170 r = sd_bus_message_enter_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
3177 if (n_array == (unsigned) -1) {
3182 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
3188 n_array = (unsigned) -1;
3201 int sd_bus_message_read(sd_bus_message *m, const char *types, ...) {
3212 va_start(ap, types);
3213 r = message_read_ap(m, types, ap);
3219 int sd_bus_message_read_array(sd_bus_message *m, char type, const void **ptr, size_t *size) {
3220 struct bus_container *c;
3230 if (!bus_type_is_trivial(type))
3236 if (BUS_MESSAGE_NEED_BSWAP(m))
3239 align = bus_type_get_alignment(type);
3243 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
3247 c = message_get_container(m);
3248 sz = BUS_MESSAGE_BSWAP32(m, *c->array_size);
3250 r = message_peek_body(m, &m->rindex, align, sz, &p);
3258 r = sd_bus_message_exit_container(m);
3262 *ptr = (const void*) p;
3268 message_quit_container(m);
3272 static int message_peek_fields(
3283 return buffer_peek(BUS_MESSAGE_FIELDS(m), BUS_MESSAGE_FIELDS_SIZE(m), rindex, align, nbytes, ret);
3286 static int message_peek_field_uint32(
3297 r = message_peek_fields(m, ri, 4, 4, &q);
3302 *ret = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
3307 static int message_peek_field_string(
3309 bool (*validate)(const char *p),
3320 r = message_peek_field_uint32(m, ri, &l);
3324 r = message_peek_fields(m, ri, 1, l+1, &q);
3329 if (!validate_nul(q, l))
3335 if (!validate_string(q, l))
3345 static int message_peek_field_signature(
3357 r = message_peek_fields(m, ri, 1, 1, &q);
3362 r = message_peek_fields(m, ri, 1, l+1, &q);
3366 if (!validate_signature(q, l))
3375 static int message_skip_fields(
3378 uint32_t array_size,
3379 const char **signature) {
3381 size_t original_index;
3388 original_index = *ri;
3394 if (array_size != (uint32_t) -1 &&
3395 array_size <= *ri - original_index)
3402 if (t == SD_BUS_TYPE_STRING) {
3404 r = message_peek_field_string(m, NULL, ri, NULL);
3410 } else if (t == SD_BUS_TYPE_OBJECT_PATH) {
3412 r = message_peek_field_string(m, object_path_is_valid, ri, NULL);
3418 } else if (t == SD_BUS_TYPE_SIGNATURE) {
3420 r = message_peek_field_signature(m, ri, NULL);
3426 } else if (bus_type_is_basic(t)) {
3429 align = bus_type_get_alignment(t);
3430 k = bus_type_get_size(t);
3431 assert(align > 0 && k > 0);
3433 r = message_peek_fields(m, ri, align, k, NULL);
3439 } else if (t == SD_BUS_TYPE_ARRAY) {
3441 r = signature_element_length(*signature+1, &l);
3451 strncpy(sig, *signature + 1, l-1);
3454 alignment = bus_type_get_alignment(sig[0]);
3458 r = message_peek_field_uint32(m, ri, &nas);
3461 if (nas > BUS_ARRAY_MAX_SIZE)
3464 r = message_peek_fields(m, ri, alignment, 0, NULL);
3468 r = message_skip_fields(m, ri, nas, (const char**) &s);
3473 (*signature) += 1 + l;
3475 } else if (t == SD_BUS_TYPE_VARIANT) {
3478 r = message_peek_field_signature(m, ri, &s);
3482 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
3488 } else if (t == SD_BUS_TYPE_STRUCT ||
3489 t == SD_BUS_TYPE_DICT_ENTRY) {
3491 r = signature_element_length(*signature, &l);
3498 strncpy(sig, *signature + 1, l-1);
3501 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
3512 int bus_message_parse_fields(sd_bus_message *m) {
3515 uint32_t unix_fds = 0;
3519 for (ri = 0; ri < BUS_MESSAGE_FIELDS_SIZE(m); ) {
3520 const char *signature;
3523 r = message_peek_fields(m, &ri, 8, 1, (void**) &header);
3527 r = message_peek_field_signature(m, &ri, &signature);
3532 case _SD_BUS_MESSAGE_HEADER_INVALID:
3535 case SD_BUS_MESSAGE_HEADER_PATH:
3540 if (!streq(signature, "o"))
3543 r = message_peek_field_string(m, object_path_is_valid, &ri, &m->path);
3546 case SD_BUS_MESSAGE_HEADER_INTERFACE:
3551 if (!streq(signature, "s"))
3554 r = message_peek_field_string(m, interface_name_is_valid, &ri, &m->interface);
3557 case SD_BUS_MESSAGE_HEADER_MEMBER:
3562 if (!streq(signature, "s"))
3565 r = message_peek_field_string(m, member_name_is_valid, &ri, &m->member);
3568 case SD_BUS_MESSAGE_HEADER_ERROR_NAME:
3573 if (!streq(signature, "s"))
3576 r = message_peek_field_string(m, error_name_is_valid, &ri, &m->error.name);
3579 case SD_BUS_MESSAGE_HEADER_DESTINATION:
3584 if (!streq(signature, "s"))
3587 r = message_peek_field_string(m, service_name_is_valid, &ri, &m->destination);
3590 case SD_BUS_MESSAGE_HEADER_SENDER:
3595 if (!streq(signature, "s"))
3598 r = message_peek_field_string(m, service_name_is_valid, &ri, &m->sender);
3602 case SD_BUS_MESSAGE_HEADER_SIGNATURE: {
3606 if (m->root_container.signature)
3609 if (!streq(signature, "g"))
3612 r = message_peek_field_signature(m, &ri, &s);
3620 free(m->root_container.signature);
3621 m->root_container.signature = c;
3625 case SD_BUS_MESSAGE_HEADER_REPLY_SERIAL:
3626 if (m->reply_serial != 0)
3629 if (!streq(signature, "u"))
3632 r = message_peek_field_uint32(m, &ri, &m->reply_serial);
3636 if (m->reply_serial == 0)
3641 case SD_BUS_MESSAGE_HEADER_UNIX_FDS:
3645 if (!streq(signature, "u"))
3648 r = message_peek_field_uint32(m, &ri, &unix_fds);
3658 r = message_skip_fields(m, &ri, (uint32_t) -1, (const char **) &signature);
3665 if (m->n_fds != unix_fds)
3668 if (isempty(m->root_container.signature) != (BUS_MESSAGE_BODY_SIZE(m) == 0))
3671 switch (m->header->type) {
3673 case SD_BUS_MESSAGE_TYPE_SIGNAL:
3674 if (!m->path || !m->interface || !m->member)
3678 case SD_BUS_MESSAGE_TYPE_METHOD_CALL:
3680 if (!m->path || !m->member)
3685 case SD_BUS_MESSAGE_TYPE_METHOD_RETURN:
3687 if (m->reply_serial == 0)
3691 case SD_BUS_MESSAGE_TYPE_METHOD_ERROR:
3693 if (m->reply_serial == 0 || !m->error.name)
3698 /* Try to read the error message, but if we can't it's a non-issue */
3699 if (m->header->type == SD_BUS_MESSAGE_TYPE_METHOD_ERROR)
3700 sd_bus_message_read(m, "s", &m->error.message);
3705 int bus_message_seal(sd_bus_message *m, uint64_t serial) {
3706 struct bus_body_part *part;
3716 if (m->n_containers > 0)
3722 /* If there's a non-trivial signature set, then add it in here */
3723 if (!isempty(m->root_container.signature)) {
3724 r = message_append_field_signature(m, SD_BUS_MESSAGE_HEADER_SIGNATURE, m->root_container.signature, NULL);
3730 r = message_append_field_uint32(m, SD_BUS_MESSAGE_HEADER_UNIX_FDS, m->n_fds);
3735 /* Add padding at the end of the fields part, since we know
3736 * the body needs to start at an 8 byte alignment. We made
3737 * sure we allocated enough space for this, so all we need to
3738 * do here is to zero it out. */
3739 l = BUS_MESSAGE_FIELDS_SIZE(m);
3742 memset((uint8_t*) BUS_MESSAGE_FIELDS(m) + l, 0, a);
3744 /* If this is something we can send as memfd, then let's seal
3745 the memfd now. Note that we can send memfds as payload only
3746 for directed messages, and not for broadcasts. */
3747 if (m->destination) {
3748 MESSAGE_FOREACH_PART(part, i, m)
3749 if (part->memfd >= 0 && !part->sealed && part->size > MEMFD_MIN_SIZE) {
3750 bus_body_part_unmap(part);
3752 if (ioctl(part->memfd, KDBUS_CMD_MEMFD_SEAL_SET, 1) >= 0)
3753 part->sealed = true;
3757 m->header->serial = serial;
3763 int sd_bus_message_set_destination(sd_bus_message *m, const char *destination) {
3773 return message_append_field_string(m, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &m->destination);
3776 int bus_message_dump(sd_bus_message *m) {
3777 const char *u = NULL, *uu = NULL, *s = NULL;
3778 char **cmdline = NULL;
3781 uid_t owner, audit_loginuid;
3782 uint32_t audit_sessionid;
3786 printf("Message %p\n"
3793 "\tfields_size=%u\n"
3798 "\tdestination=%s\n"
3801 "\treply_serial=%u\n"
3803 "\terror.message=%s\n"
3805 "\tn_body_parts=%u\n",
3812 BUS_MESSAGE_SERIAL(m),
3813 BUS_MESSAGE_FIELDS_SIZE(m),
3814 BUS_MESSAGE_BODY_SIZE(m),
3816 strna(m->interface),
3818 strna(m->destination),
3820 strna(m->root_container.signature),
3822 strna(m->error.name),
3823 strna(m->error.message),
3828 printf("\tpid=%lu\n", (unsigned long) m->pid);
3830 printf("\ttid=%lu\n", (unsigned long) m->tid);
3832 printf("\tuid=%lu\n", (unsigned long) m->uid);
3834 printf("\tgid=%lu\n", (unsigned long) m->gid);
3835 if (m->pid_starttime != 0)
3836 printf("\tpid_starttime=%llu\n", (unsigned long long) m->pid_starttime);
3837 if (m->monotonic != 0)
3838 printf("\tmonotonic=%llu\n", (unsigned long long) m->monotonic);
3839 if (m->realtime != 0)
3840 printf("\trealtime=%llu\n", (unsigned long long) m->realtime);
3842 printf("\texe=[%s]\n", m->exe);
3844 printf("\tcomm=[%s]\n", m->comm);
3846 printf("\ttid_comm=[%s]\n", m->tid_comm);
3848 printf("\tlabel=[%s]\n", m->label);
3850 printf("\tcgroup=[%s]\n", m->cgroup);
3852 sd_bus_message_get_unit(m, &u);
3854 printf("\tunit=[%s]\n", u);
3855 sd_bus_message_get_user_unit(m, &uu);
3857 printf("\tuser_unit=[%s]\n", uu);
3858 sd_bus_message_get_session(m, &s);
3860 printf("\tsession=[%s]\n", s);
3861 if (sd_bus_message_get_owner_uid(m, &owner) >= 0)
3862 printf("\towner_uid=%lu\n", (unsigned long) owner);
3863 if (sd_bus_message_get_audit_loginuid(m, &audit_loginuid) >= 0)
3864 printf("\taudit_loginuid=%lu\n", (unsigned long) audit_loginuid);
3865 if (sd_bus_message_get_audit_sessionid(m, &audit_sessionid) >= 0)
3866 printf("\taudit_sessionid=%lu\n", (unsigned long) audit_sessionid);
3868 printf("\tCAP_KILL=%i\n", sd_bus_message_has_effective_cap(m, 5));
3870 if (sd_bus_message_get_cmdline(m, &cmdline) >= 0) {
3873 fputs("\tcmdline=[", stdout);
3874 STRV_FOREACH(c, cmdline) {
3881 fputs("]\n", stdout);
3884 r = sd_bus_message_rewind(m, true);
3886 log_error("Failed to rewind: %s", strerror(-r));
3890 printf("BEGIN_MESSAGE \"%s\" {\n", strempty(m->root_container.signature));
3893 _cleanup_free_ char *prefix = NULL;
3894 const char *contents = NULL;
3909 r = sd_bus_message_peek_type(m, &type, &contents);
3911 log_error("Failed to peek type: %s", strerror(-r));
3918 r = sd_bus_message_exit_container(m);
3920 log_error("Failed to exit container: %s", strerror(-r));
3926 prefix = strrep("\t", level);
3930 if (type == SD_BUS_TYPE_ARRAY)
3931 printf("%s} END_ARRAY \n", prefix);
3932 else if (type == SD_BUS_TYPE_VARIANT)
3933 printf("%s} END_VARIANT\n", prefix);
3934 else if (type == SD_BUS_TYPE_STRUCT)
3935 printf("%s} END_STRUCT\n", prefix);
3936 else if (type == SD_BUS_TYPE_DICT_ENTRY)
3937 printf("%s} END_DICT_ENTRY\n", prefix);
3942 prefix = strrep("\t", level);
3946 if (bus_type_is_container(type) > 0) {
3947 r = sd_bus_message_enter_container(m, type, contents);
3949 log_error("Failed to enter container: %s", strerror(-r));
3953 if (type == SD_BUS_TYPE_ARRAY)
3954 printf("%sBEGIN_ARRAY \"%s\" {\n", prefix, contents);
3955 else if (type == SD_BUS_TYPE_VARIANT)
3956 printf("%sBEGIN_VARIANT \"%s\" {\n", prefix, contents);
3957 else if (type == SD_BUS_TYPE_STRUCT)
3958 printf("%sBEGIN_STRUCT \"%s\" {\n", prefix, contents);
3959 else if (type == SD_BUS_TYPE_DICT_ENTRY)
3960 printf("%sBEGIN_DICT_ENTRY \"%s\" {\n", prefix, contents);
3967 r = sd_bus_message_read_basic(m, type, &basic);
3969 log_error("Failed to get basic: %s", strerror(-r));
3975 case SD_BUS_TYPE_BYTE:
3976 printf("%sBYTE: %u\n", prefix, basic.u8);
3979 case SD_BUS_TYPE_BOOLEAN:
3980 printf("%sBOOLEAN: %s\n", prefix, yes_no(basic.i));
3983 case SD_BUS_TYPE_INT16:
3984 printf("%sINT16: %i\n", prefix, basic.s16);
3987 case SD_BUS_TYPE_UINT16:
3988 printf("%sUINT16: %u\n", prefix, basic.u16);
3991 case SD_BUS_TYPE_INT32:
3992 printf("%sINT32: %i\n", prefix, basic.s32);
3995 case SD_BUS_TYPE_UINT32:
3996 printf("%sUINT32: %u\n", prefix, basic.u32);
3999 case SD_BUS_TYPE_INT64:
4000 printf("%sINT64: %lli\n", prefix, (long long) basic.s64);
4003 case SD_BUS_TYPE_UINT64:
4004 printf("%sUINT64: %llu\n", prefix, (unsigned long long) basic.u64);
4007 case SD_BUS_TYPE_DOUBLE:
4008 printf("%sDOUBLE: %g\n", prefix, basic.d64);
4011 case SD_BUS_TYPE_STRING:
4012 printf("%sSTRING: \"%s\"\n", prefix, basic.string);
4015 case SD_BUS_TYPE_OBJECT_PATH:
4016 printf("%sOBJECT_PATH: \"%s\"\n", prefix, basic.string);
4019 case SD_BUS_TYPE_SIGNATURE:
4020 printf("%sSIGNATURE: \"%s\"\n", prefix, basic.string);
4023 case SD_BUS_TYPE_UNIX_FD:
4024 printf("%sUNIX_FD: %i\n", prefix, basic.i);
4028 assert_not_reached("Unknown basic type.");
4032 printf("} END_MESSAGE\n");
4036 int bus_message_get_blob(sd_bus_message *m, void **buffer, size_t *sz) {
4040 struct bus_body_part *part;
4046 total = BUS_MESSAGE_SIZE(m);
4052 e = mempcpy(p, m->header, BUS_MESSAGE_BODY_BEGIN(m));
4053 MESSAGE_FOREACH_PART(part, i, m)
4054 e = mempcpy(e, part->data, part->size);
4056 assert(total == (size_t) ((uint8_t*) e - (uint8_t*) p));
4064 int bus_message_read_strv_extend(sd_bus_message *m, char ***l) {
4070 r = sd_bus_message_enter_container(m, 'a', "s");
4077 r = sd_bus_message_read_basic(m, 's', &s);
4083 r = strv_extend(l, s);
4088 r = sd_bus_message_exit_container(m);
4095 const char* bus_message_get_arg(sd_bus_message *m, unsigned i) {
4097 const char *t = NULL;
4102 r = sd_bus_message_rewind(m, true);
4106 for (j = 0; j <= i; j++) {
4109 r = sd_bus_message_peek_type(m, &type, NULL);
4113 if (type != SD_BUS_TYPE_STRING &&
4114 type != SD_BUS_TYPE_OBJECT_PATH &&
4115 type != SD_BUS_TYPE_SIGNATURE)
4118 r = sd_bus_message_read_basic(m, type, &t);
4126 bool bus_header_is_complete(struct bus_header *h, size_t size) {
4132 if (size < sizeof(struct bus_header))
4135 full = sizeof(struct bus_header) +
4136 (h->endian == SD_BUS_NATIVE_ENDIAN ? h->fields_size : bswap_32(h->fields_size));
4138 return size >= full;
4141 int bus_header_message_size(struct bus_header *h, size_t *sum) {
4147 if (h->endian == SD_BUS_NATIVE_ENDIAN) {
4148 fs = h->fields_size;
4150 } else if (h->endian == SD_BUS_REVERSE_ENDIAN) {
4151 fs = bswap_32(h->fields_size);
4152 bs = bswap_32(h->body_size);
4156 *sum = sizeof(struct bus_header) + ALIGN8(fs) + bs;