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 sd_bus_unref(m->bus);
135 close_many(m->fds, m->n_fds);
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 int bus_message_new_synthetic_error(
629 const sd_bus_error *e,
630 sd_bus_message **m) {
635 assert(sd_bus_error_is_set(e));
638 t = message_new(bus, SD_BUS_MESSAGE_TYPE_METHOD_ERROR);
642 t->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
643 t->reply_serial = serial;
645 r = message_append_field_uint32(t, SD_BUS_MESSAGE_HEADER_REPLY_SERIAL, t->reply_serial);
649 if (bus && bus->unique_name) {
650 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, bus->unique_name, &t->destination);
663 sd_bus_message* sd_bus_message_ref(sd_bus_message *m) {
667 assert(m->n_ref > 0);
673 sd_bus_message* sd_bus_message_unref(sd_bus_message *m) {
677 assert(m->n_ref > 0);
686 int sd_bus_message_get_type(sd_bus_message *m, uint8_t *type) {
692 *type = m->header->type;
696 int sd_bus_message_get_serial(sd_bus_message *m, uint64_t *serial) {
701 if (m->header->serial == 0)
704 *serial = BUS_MESSAGE_SERIAL(m);
708 int sd_bus_message_get_reply_serial(sd_bus_message *m, uint64_t *serial) {
713 if (m->reply_serial == 0)
716 *serial = m->reply_serial;
720 int sd_bus_message_get_no_reply(sd_bus_message *m) {
724 return m->header->type == SD_BUS_MESSAGE_TYPE_METHOD_CALL ? !!(m->header->flags & SD_BUS_MESSAGE_NO_REPLY_EXPECTED) : 0;
727 const char *sd_bus_message_get_path(sd_bus_message *m) {
734 const char *sd_bus_message_get_interface(sd_bus_message *m) {
741 const char *sd_bus_message_get_member(sd_bus_message *m) {
747 const char *sd_bus_message_get_destination(sd_bus_message *m) {
751 return m->destination;
754 const char *sd_bus_message_get_sender(sd_bus_message *m) {
761 const sd_bus_error *sd_bus_message_get_error(sd_bus_message *m) {
765 if (!sd_bus_error_is_set(&m->error))
771 int sd_bus_message_get_uid(sd_bus_message *m, uid_t *uid) {
783 int sd_bus_message_get_gid(sd_bus_message *m, gid_t *gid) {
795 int sd_bus_message_get_pid(sd_bus_message *m, pid_t *pid) {
807 int sd_bus_message_get_tid(sd_bus_message *m, pid_t *tid) {
819 int sd_bus_message_get_pid_starttime(sd_bus_message *m, uint64_t *usec) {
824 if (m->pid_starttime <= 0)
827 *usec = m->pid_starttime;
831 int sd_bus_message_get_selinux_context(sd_bus_message *m, const char **ret) {
841 int sd_bus_message_get_monotonic_timestamp(sd_bus_message *m, uint64_t *usec) {
846 if (m->monotonic <= 0)
849 *usec = m->monotonic;
853 int sd_bus_message_get_realtime_timestamp(sd_bus_message *m, uint64_t *usec) {
858 if (m->realtime <= 0)
865 int sd_bus_message_get_comm(sd_bus_message *m, const char **ret) {
877 int sd_bus_message_get_tid_comm(sd_bus_message *m, const char **ret) {
889 int sd_bus_message_get_exe(sd_bus_message *m, const char **ret) {
901 int sd_bus_message_get_cgroup(sd_bus_message *m, const char **ret) {
913 int sd_bus_message_get_unit(sd_bus_message *m, const char **ret) {
924 r = cg_path_get_unit(m->cgroup, &m->unit);
933 int sd_bus_message_get_user_unit(sd_bus_message *m, const char **ret) {
944 r = cg_path_get_user_unit(m->cgroup, &m->user_unit);
953 int sd_bus_message_get_session(sd_bus_message *m, const char **ret) {
964 r = cg_path_get_session(m->cgroup, &m->session);
973 int sd_bus_message_get_owner_uid(sd_bus_message *m, uid_t *uid) {
981 return cg_path_get_owner_uid(m->cgroup, uid);
984 int sd_bus_message_get_cmdline(sd_bus_message *m, char ***cmdline) {
995 for (p = m->cmdline, n = 0; p < m->cmdline + m->cmdline_length; p++)
999 m->cmdline_array = new(char*, n + 1);
1000 if (!m->cmdline_array)
1003 for (p = m->cmdline, i = 0, first = true; p < m->cmdline + m->cmdline_length; p++) {
1005 m->cmdline_array[i++] = (char*) p;
1010 m->cmdline_array[i] = NULL;
1011 *cmdline = m->cmdline_array;
1016 int sd_bus_message_get_audit_sessionid(sd_bus_message *m, uint32_t *sessionid) {
1024 *sessionid = m->audit->sessionid;
1028 int sd_bus_message_get_audit_loginuid(sd_bus_message *m, uid_t *uid) {
1036 *uid = m->audit->loginuid;
1040 int sd_bus_message_has_effective_cap(sd_bus_message *m, int capability) {
1050 sz = m->capability_size / 4;
1051 if ((unsigned) capability >= sz*8)
1054 return !!(m->capability[2 * sz + (capability / 8)] & (1 << (capability % 8)));
1057 int sd_bus_message_is_signal(sd_bus_message *m, const char *interface, const char *member) {
1061 if (m->header->type != SD_BUS_MESSAGE_TYPE_SIGNAL)
1064 if (interface && (!m->interface || !streq(m->interface, interface)))
1067 if (member && (!m->member || !streq(m->member, member)))
1073 int sd_bus_message_is_method_call(sd_bus_message *m, const char *interface, const char *member) {
1077 if (m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_CALL)
1080 if (interface && (!m->interface || !streq(m->interface, interface)))
1083 if (member && (!m->member || !streq(m->member, member)))
1089 int sd_bus_message_is_method_error(sd_bus_message *m, const char *name) {
1093 if (m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_ERROR)
1096 if (name && (!m->error.name || !streq(m->error.name, name)))
1102 int sd_bus_message_set_no_reply(sd_bus_message *m, int b) {
1107 if (m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_CALL)
1111 m->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
1113 m->header->flags &= ~SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
1118 static struct bus_container *message_get_container(sd_bus_message *m) {
1121 if (m->n_containers == 0)
1122 return &m->root_container;
1124 assert(m->containers);
1125 return m->containers + m->n_containers - 1;
1128 struct bus_body_part *message_append_part(sd_bus_message *m) {
1129 struct bus_body_part *part;
1136 if (m->n_body_parts <= 0) {
1140 assert(m->body_end);
1142 part = new0(struct bus_body_part, 1);
1148 m->body_end->next = part;
1158 static void part_zero(struct bus_body_part *part, size_t sz) {
1163 /* All other fields can be left in their defaults */
1164 assert(!part->data);
1165 assert(part->memfd < 0);
1168 part->is_zero = true;
1169 part->sealed = true;
1172 static int part_make_space(
1173 struct sd_bus_message *m,
1174 struct bus_body_part *part,
1183 assert(!part->sealed);
1188 if (!part->data && part->memfd < 0)
1189 part->memfd = bus_kernel_pop_memfd(m->bus, &part->data, &part->mapped);
1191 if (part->memfd >= 0) {
1194 r = ioctl(part->memfd, KDBUS_CMD_MEMFD_SIZE_SET, &u);
1200 if (!part->data || sz > part->mapped) {
1201 size_t psz = PAGE_ALIGN(sz > 0 ? sz : 1);
1203 if (part->mapped <= 0)
1204 n = mmap(NULL, psz, PROT_READ|PROT_WRITE, MAP_SHARED, part->memfd, 0);
1206 n = mremap(part->data, part->mapped, psz, MREMAP_MAYMOVE);
1208 if (n == MAP_FAILED) {
1215 part->munmap_this = true;
1218 n = realloc(part->data, sz);
1225 part->free_this = true;
1229 *q = part->data ? (uint8_t*) part->data + part->size : NULL;
1235 static void message_extend_containers(sd_bus_message *m, size_t expand) {
1236 struct bus_container *c;
1243 /* Update counters */
1244 for (c = m->containers; c < m->containers + m->n_containers; c++)
1246 *c->array_size += expand;
1250 static void *message_extend_body(sd_bus_message *m, size_t align, size_t sz) {
1251 struct bus_body_part *part = NULL;
1252 size_t start_body, end_body, padding, start_part, end_part, added;
1264 start_body = ALIGN_TO((size_t) m->header->body_size, align);
1265 end_body = start_body + sz;
1267 padding = start_body - m->header->body_size;
1268 added = padding + sz;
1270 /* Check for 32bit overflows */
1271 if (end_body > (size_t) ((uint32_t) -1)) {
1277 m->n_body_parts <= 0 ||
1278 m->body_end->sealed ||
1279 padding != ALIGN_TO(m->body_end->size, align) - m->body_end->size;
1283 part = message_append_part(m);
1287 part_zero(part, padding);
1290 part = message_append_part(m);
1294 r = part_make_space(m, part, sz, &p);
1298 struct bus_container *c;
1306 start_part = ALIGN_TO(part->size, align);
1307 end_part = start_part + sz;
1309 r = part_make_space(m, part, end_part, &p);
1314 memset(p, 0, padding);
1315 p = (uint8_t*) p + padding;
1318 /* Readjust pointers */
1319 for (c = m->containers; c < m->containers + m->n_containers; c++)
1320 c->array_size = adjust_pointer(c->array_size, op, os, part->data);
1322 m->error.message = (const char*) adjust_pointer(m->error.message, op, os, part->data);
1325 m->header->body_size = end_body;
1326 message_extend_containers(m, added);
1331 int message_append_basic(sd_bus_message *m, char type, const void *p, const void **stored) {
1332 struct bus_container *c;
1346 if (!bus_type_is_basic(type))
1351 c = message_get_container(m);
1353 if (c->signature && c->signature[c->index]) {
1354 /* Container signature is already set */
1356 if (c->signature[c->index] != type)
1361 /* Maybe we can append to the signature? But only if this is the top-level container*/
1362 if (c->enclosing != 0)
1365 e = strextend(&c->signature, CHAR_TO_STR(type), NULL);
1374 case SD_BUS_TYPE_STRING:
1375 case SD_BUS_TYPE_OBJECT_PATH:
1378 sz = 4 + strlen(p) + 1;
1381 case SD_BUS_TYPE_SIGNATURE:
1384 sz = 1 + strlen(p) + 1;
1387 case SD_BUS_TYPE_BOOLEAN:
1390 assert_cc(sizeof(int) == sizeof(uint32_t));
1396 case SD_BUS_TYPE_UNIX_FD: {
1399 if (!m->allow_fds) {
1412 fd = fcntl(z, F_DUPFD_CLOEXEC, 3);
1418 f = realloc(m->fds, sizeof(int) * (m->n_fds + 1));
1433 align = bus_type_get_alignment(type);
1434 sz = bus_type_get_size(type);
1441 a = message_extend_body(m, align, sz);
1447 if (type == SD_BUS_TYPE_STRING || type == SD_BUS_TYPE_OBJECT_PATH) {
1448 *(uint32_t*) a = sz - 5;
1449 memcpy((uint8_t*) a + 4, p, sz - 4);
1452 *stored = (const uint8_t*) a + 4;
1454 } else if (type == SD_BUS_TYPE_SIGNATURE) {
1455 *(uint8_t*) a = sz - 1;
1456 memcpy((uint8_t*) a + 1, p, sz - 1);
1459 *stored = (const uint8_t*) a + 1;
1460 } else if (type == SD_BUS_TYPE_UNIX_FD) {
1461 *(uint32_t*) a = fdi;
1475 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1482 close_nointr_nofail(fd);
1487 int sd_bus_message_append_basic(sd_bus_message *m, char type, const void *p) {
1488 return message_append_basic(m, type, p, NULL);
1491 int sd_bus_message_append_string_space(sd_bus_message *m, size_t size, char **s) {
1492 struct bus_container *c;
1504 c = message_get_container(m);
1506 if (c->signature && c->signature[c->index]) {
1507 /* Container signature is already set */
1509 if (c->signature[c->index] != SD_BUS_TYPE_STRING)
1514 /* Maybe we can append to the signature? But only if this is the top-level container*/
1515 if (c->enclosing != 0)
1518 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRING), NULL);
1525 a = message_extend_body(m, 4, 4 + size + 1);
1529 *(uint32_t*) a = size;
1534 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1540 static int bus_message_open_array(
1542 struct bus_container *c,
1543 const char *contents,
1544 uint32_t **array_size) {
1550 struct bus_body_part *o;
1557 if (!signature_is_single(contents))
1560 alignment = bus_type_get_alignment(contents[0]);
1564 if (c->signature && c->signature[c->index]) {
1566 /* Verify the existing signature */
1568 if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
1571 if (!startswith(c->signature + c->index + 1, contents))
1574 nindex = c->index + 1 + strlen(contents);
1578 if (c->enclosing != 0)
1581 /* Extend the existing signature */
1583 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_ARRAY), contents, NULL);
1589 nindex = e - c->signature;
1592 a = message_extend_body(m, 4, 4);
1597 op = m->body_end->data;
1598 os = m->body_end->size;
1600 /* Add alignment between size and first element */
1601 if (!message_extend_body(m, alignment, 0))
1604 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1607 /* location of array size might have changed so let's readjust a */
1608 if (o == m->body_end)
1609 a = adjust_pointer(a, op, os, m->body_end->data);
1616 static int bus_message_open_variant(
1618 struct bus_container *c,
1619 const char *contents) {
1628 if (!signature_is_single(contents))
1631 if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
1634 if (c->signature && c->signature[c->index]) {
1636 if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
1642 if (c->enclosing != 0)
1645 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_VARIANT), NULL);
1652 l = strlen(contents);
1653 a = message_extend_body(m, 1, 1 + l + 1);
1658 memcpy((uint8_t*) a + 1, contents, l + 1);
1660 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1666 static int bus_message_open_struct(
1668 struct bus_container *c,
1669 const char *contents) {
1677 if (!signature_is_valid(contents, false))
1680 if (c->signature && c->signature[c->index]) {
1683 l = strlen(contents);
1685 if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
1686 !startswith(c->signature + c->index + 1, contents) ||
1687 c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
1690 nindex = c->index + 1 + l + 1;
1694 if (c->enclosing != 0)
1697 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_BEGIN), contents, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_END), NULL);
1703 nindex = e - c->signature;
1706 /* Align contents to 8 byte boundary */
1707 if (!message_extend_body(m, 8, 0))
1710 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1716 static int bus_message_open_dict_entry(
1718 struct bus_container *c,
1719 const char *contents) {
1727 if (!signature_is_pair(contents))
1730 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1733 if (c->signature && c->signature[c->index]) {
1736 l = strlen(contents);
1738 if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
1739 !startswith(c->signature + c->index + 1, contents) ||
1740 c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
1743 nindex = c->index + 1 + l + 1;
1747 /* Align contents to 8 byte boundary */
1748 if (!message_extend_body(m, 8, 0))
1751 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1757 int sd_bus_message_open_container(
1760 const char *contents) {
1762 struct bus_container *c, *w;
1763 uint32_t *array_size = NULL;
1777 /* Make sure we have space for one more container */
1778 w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
1786 c = message_get_container(m);
1788 signature = strdup(contents);
1794 /* Save old index in the parent container, in case we have to
1795 * abort this container */
1796 c->saved_index = c->index;
1797 before = m->header->body_size;
1799 if (type == SD_BUS_TYPE_ARRAY)
1800 r = bus_message_open_array(m, c, contents, &array_size);
1801 else if (type == SD_BUS_TYPE_VARIANT)
1802 r = bus_message_open_variant(m, c, contents);
1803 else if (type == SD_BUS_TYPE_STRUCT)
1804 r = bus_message_open_struct(m, c, contents);
1805 else if (type == SD_BUS_TYPE_DICT_ENTRY)
1806 r = bus_message_open_dict_entry(m, c, contents);
1815 /* OK, let's fill it in */
1816 w += m->n_containers++;
1817 w->enclosing = type;
1818 w->signature = signature;
1820 w->array_size = array_size;
1822 w->begin = m->rindex;
1827 int sd_bus_message_close_container(sd_bus_message *m) {
1828 struct bus_container *c;
1834 if (m->n_containers <= 0)
1839 c = message_get_container(m);
1840 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1841 if (c->signature && c->signature[c->index] != 0)
1856 static int type_stack_push(TypeStack *stack, unsigned max, unsigned *i, const char *types, unsigned n_struct, unsigned n_array) {
1863 stack[*i].types = types;
1864 stack[*i].n_struct = n_struct;
1865 stack[*i].n_array = n_array;
1871 static int type_stack_pop(TypeStack *stack, unsigned max, unsigned *i, const char **types, unsigned *n_struct, unsigned *n_array) {
1882 *types = stack[*i].types;
1883 *n_struct = stack[*i].n_struct;
1884 *n_array = stack[*i].n_array;
1889 int bus_message_append_ap(
1894 unsigned n_array, n_struct;
1895 TypeStack stack[BUS_CONTAINER_DEPTH];
1896 unsigned stack_ptr = 0;
1904 n_array = (unsigned) -1;
1905 n_struct = strlen(types);
1910 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
1911 r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
1917 r = sd_bus_message_close_container(m);
1925 if (n_array != (unsigned) -1)
1934 case SD_BUS_TYPE_BYTE: {
1937 x = (uint8_t) va_arg(ap, int);
1938 r = sd_bus_message_append_basic(m, *t, &x);
1942 case SD_BUS_TYPE_BOOLEAN:
1943 case SD_BUS_TYPE_INT32:
1944 case SD_BUS_TYPE_UINT32:
1945 case SD_BUS_TYPE_UNIX_FD: {
1948 /* We assume a boolean is the same as int32_t */
1949 assert_cc(sizeof(int32_t) == sizeof(int));
1951 x = va_arg(ap, uint32_t);
1952 r = sd_bus_message_append_basic(m, *t, &x);
1956 case SD_BUS_TYPE_INT16:
1957 case SD_BUS_TYPE_UINT16: {
1960 x = (uint16_t) va_arg(ap, int);
1961 r = sd_bus_message_append_basic(m, *t, &x);
1965 case SD_BUS_TYPE_INT64:
1966 case SD_BUS_TYPE_UINT64:
1967 case SD_BUS_TYPE_DOUBLE: {
1970 x = va_arg(ap, uint64_t);
1971 r = sd_bus_message_append_basic(m, *t, &x);
1975 case SD_BUS_TYPE_STRING:
1976 case SD_BUS_TYPE_OBJECT_PATH:
1977 case SD_BUS_TYPE_SIGNATURE: {
1980 x = va_arg(ap, const char*);
1981 r = sd_bus_message_append_basic(m, *t, x);
1985 case SD_BUS_TYPE_ARRAY: {
1988 r = signature_element_length(t + 1, &k);
1994 memcpy(s, t + 1, k);
1997 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, s);
2002 if (n_array == (unsigned) -1) {
2007 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2013 n_array = va_arg(ap, unsigned);
2018 case SD_BUS_TYPE_VARIANT: {
2021 s = va_arg(ap, const char*);
2025 r = sd_bus_message_open_container(m, SD_BUS_TYPE_VARIANT, s);
2029 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2034 n_struct = strlen(s);
2035 n_array = (unsigned) -1;
2040 case SD_BUS_TYPE_STRUCT_BEGIN:
2041 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
2044 r = signature_element_length(t, &k);
2051 memcpy(s, t + 1, k - 2);
2054 r = sd_bus_message_open_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
2059 if (n_array == (unsigned) -1) {
2064 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2070 n_array = (unsigned) -1;
2086 int sd_bus_message_append(sd_bus_message *m, const char *types, ...) {
2099 va_start(ap, types);
2100 r = bus_message_append_ap(m, types, ap);
2106 int sd_bus_message_append_array_space(sd_bus_message *m, char type, size_t size, void **ptr) {
2115 if (!bus_type_is_trivial(type))
2117 if (!ptr && size > 0)
2122 align = bus_type_get_alignment(type);
2123 sz = bus_type_get_size(type);
2125 assert_se(align > 0);
2131 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
2135 a = message_extend_body(m, align, size);
2139 r = sd_bus_message_close_container(m);
2147 int sd_bus_message_append_array(sd_bus_message *m, char type, const void *ptr, size_t size) {
2151 if (!ptr && size > 0)
2154 r = sd_bus_message_append_array_space(m, type, size, &p);
2159 memcpy(p, ptr, size);
2164 int sd_bus_message_append_array_memfd(sd_bus_message *m, char type, sd_memfd *memfd) {
2165 _cleanup_close_ int copy_fd = -1;
2166 struct bus_body_part *part;
2178 if (!bus_type_is_trivial(type))
2183 r = sd_memfd_set_sealed(memfd, true);
2187 copy_fd = sd_memfd_dup_fd(memfd);
2191 r = sd_memfd_get_size(memfd, &size);
2195 align = bus_type_get_alignment(type);
2196 sz = bus_type_get_size(type);
2198 assert_se(align > 0);
2204 if (size > (uint64_t) (uint32_t) -1)
2207 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
2211 a = message_extend_body(m, align, 0);
2215 part = message_append_part(m);
2219 part->memfd = copy_fd;
2220 part->sealed = true;
2224 message_extend_containers(m, size);
2225 m->header->body_size += size;
2227 return sd_bus_message_close_container(m);
2230 int sd_bus_message_append_string_memfd(sd_bus_message *m, sd_memfd *memfd) {
2231 _cleanup_close_ int copy_fd = -1;
2232 struct bus_body_part *part;
2233 struct bus_container *c;
2247 r = sd_memfd_set_sealed(memfd, true);
2251 copy_fd = sd_memfd_dup_fd(memfd);
2255 r = sd_memfd_get_size(memfd, &size);
2259 /* We require this to be NUL terminated */
2263 if (size > (uint64_t) (uint32_t) -1)
2266 c = message_get_container(m);
2267 if (c->signature && c->signature[c->index]) {
2268 /* Container signature is already set */
2270 if (c->signature[c->index] != SD_BUS_TYPE_STRING)
2275 /* Maybe we can append to the signature? But only if this is the top-level container*/
2276 if (c->enclosing != 0)
2279 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRING), NULL);
2286 a = message_extend_body(m, 4, 4);
2290 *(uint32_t*) a = size - 1;
2292 part = message_append_part(m);
2296 part->memfd = copy_fd;
2297 part->sealed = true;
2301 message_extend_containers(m, size);
2302 m->header->body_size += size;
2304 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2310 int bus_body_part_map(struct bus_body_part *part) {
2319 if (part->size <= 0)
2322 /* For smaller zero parts (as used for padding) we don't need to map anything... */
2323 if (part->memfd < 0 && part->is_zero && part->size < 8) {
2324 static const uint8_t zeroes[7] = { };
2325 part->data = (void*) zeroes;
2329 psz = PAGE_ALIGN(part->size);
2331 if (part->memfd >= 0)
2332 p = mmap(NULL, psz, PROT_READ, MAP_SHARED, part->memfd, 0);
2333 else if (part->is_zero)
2334 p = mmap(NULL, psz, PROT_READ, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
2338 if (p == MAP_FAILED)
2343 part->munmap_this = true;
2348 void bus_body_part_unmap(struct bus_body_part *part) {
2352 if (part->memfd < 0)
2358 if (!part->munmap_this)
2361 assert_se(munmap(part->data, part->mapped) == 0);
2365 part->munmap_this = false;
2370 static int buffer_peek(const void *p, uint32_t sz, size_t *rindex, size_t align, size_t nbytes, void **r) {
2371 size_t k, start, end;
2376 start = ALIGN_TO((size_t) *rindex, align);
2377 end = start + nbytes;
2382 /* Verify that padding is 0 */
2383 for (k = *rindex; k < start; k++)
2384 if (((const uint8_t*) p)[k] != 0)
2388 *r = (uint8_t*) p + start;
2395 static bool message_end_of_array(sd_bus_message *m, size_t index) {
2396 struct bus_container *c;
2400 c = message_get_container(m);
2404 return index >= c->begin + BUS_MESSAGE_BSWAP32(m, *c->array_size);
2407 static struct bus_body_part* find_part(sd_bus_message *m, size_t index, size_t sz, void **p) {
2408 struct bus_body_part *part;
2414 if (m->cached_rindex_part && index >= m->cached_rindex_part_begin) {
2415 part = m->cached_rindex_part;
2416 begin = m->cached_rindex_part_begin;
2426 if (index + sz <= begin + part->size) {
2428 r = bus_body_part_map(part);
2433 *p = (uint8_t*) part->data + index - begin;
2435 m->cached_rindex_part = part;
2436 m->cached_rindex_part_begin = begin;
2441 begin += part->size;
2448 static int message_peek_body(
2455 size_t k, start, end, padding;
2456 struct bus_body_part *part;
2463 if (message_end_of_array(m, *rindex))
2466 start = ALIGN_TO((size_t) *rindex, align);
2467 padding = start - *rindex;
2468 end = start + nbytes;
2470 if (end > BUS_MESSAGE_BODY_SIZE(m))
2473 part = find_part(m, *rindex, padding, (void**) &q);
2478 /* Verify padding */
2479 for (k = 0; k < padding; k++)
2484 part = find_part(m, start, nbytes, (void**) &q);
2496 static bool validate_nul(const char *s, size_t l) {
2498 /* Check for NUL chars in the string */
2499 if (memchr(s, 0, l))
2502 /* Check for NUL termination */
2509 static bool validate_string(const char *s, size_t l) {
2511 if (!validate_nul(s, l))
2514 /* Check if valid UTF8 */
2515 if (!utf8_is_valid(s))
2521 static bool validate_signature(const char *s, size_t l) {
2523 if (!validate_nul(s, l))
2526 /* Check if valid signature */
2527 if (!signature_is_valid(s, true))
2533 static bool validate_object_path(const char *s, size_t l) {
2535 if (!validate_nul(s, l))
2538 if (!object_path_is_valid(s))
2544 int sd_bus_message_read_basic(sd_bus_message *m, char type, void *p) {
2545 struct bus_container *c;
2553 if (!bus_type_is_basic(type))
2558 c = message_get_container(m);
2560 if (!c->signature || c->signature[c->index] == 0)
2563 if (c->signature[c->index] != type)
2568 case SD_BUS_TYPE_STRING:
2569 case SD_BUS_TYPE_OBJECT_PATH: {
2574 r = message_peek_body(m, &rindex, 4, 4, &q);
2578 l = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2579 r = message_peek_body(m, &rindex, 1, l+1, &q);
2585 if (type == SD_BUS_TYPE_OBJECT_PATH) {
2586 if (!validate_object_path(q, l))
2589 if (!validate_string(q, l))
2594 *(const char**) p = q;
2598 case SD_BUS_TYPE_SIGNATURE: {
2603 r = message_peek_body(m, &rindex, 1, 1, &q);
2608 r = message_peek_body(m, &rindex, 1, l+1, &q);
2614 if (!validate_signature(q, l))
2618 *(const char**) p = q;
2626 align = bus_type_get_alignment(type);
2627 sz = bus_type_get_size(type);
2628 assert(align > 0 && sz > 0);
2631 r = message_peek_body(m, &rindex, align, sz, &q);
2637 case SD_BUS_TYPE_BYTE:
2638 *(uint8_t*) p = *(uint8_t*) q;
2641 case SD_BUS_TYPE_BOOLEAN:
2642 *(int*) p = !!*(uint32_t*) q;
2645 case SD_BUS_TYPE_INT16:
2646 case SD_BUS_TYPE_UINT16:
2647 *(uint16_t*) p = BUS_MESSAGE_BSWAP16(m, *(uint16_t*) q);
2650 case SD_BUS_TYPE_INT32:
2651 case SD_BUS_TYPE_UINT32:
2652 *(uint32_t*) p = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2655 case SD_BUS_TYPE_INT64:
2656 case SD_BUS_TYPE_UINT64:
2657 case SD_BUS_TYPE_DOUBLE:
2658 *(uint64_t*) p = BUS_MESSAGE_BSWAP64(m, *(uint64_t*) q);
2661 case SD_BUS_TYPE_UNIX_FD: {
2664 j = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2668 *(int*) p = m->fds[j];
2673 assert_not_reached("Unknown basic type...");
2682 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2688 static int bus_message_enter_array(
2690 struct bus_container *c,
2691 const char *contents,
2692 uint32_t **array_size) {
2703 if (!signature_is_single(contents))
2706 alignment = bus_type_get_alignment(contents[0]);
2710 if (!c->signature || c->signature[c->index] == 0)
2713 if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
2716 if (!startswith(c->signature + c->index + 1, contents))
2720 r = message_peek_body(m, &rindex, 4, 4, &q);
2724 if (BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q) > BUS_ARRAY_MAX_SIZE)
2727 r = message_peek_body(m, &rindex, alignment, 0, NULL);
2733 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2734 c->index += 1 + strlen(contents);
2738 *array_size = (uint32_t*) q;
2743 static int bus_message_enter_variant(
2745 struct bus_container *c,
2746 const char *contents) {
2757 if (!signature_is_single(contents))
2760 if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
2763 if (!c->signature || c->signature[c->index] == 0)
2766 if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
2770 r = message_peek_body(m, &rindex, 1, 1, &q);
2775 r = message_peek_body(m, &rindex, 1, l+1, &q);
2781 if (!validate_signature(q, l))
2784 if (!streq(q, contents))
2787 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2795 static int bus_message_enter_struct(
2797 struct bus_container *c,
2798 const char *contents) {
2807 if (!signature_is_valid(contents, false))
2810 if (!c->signature || c->signature[c->index] == 0)
2813 l = strlen(contents);
2815 if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
2816 !startswith(c->signature + c->index + 1, contents) ||
2817 c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
2820 r = message_peek_body(m, &m->rindex, 8, 0, NULL);
2824 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2825 c->index += 1 + l + 1;
2830 static int bus_message_enter_dict_entry(
2832 struct bus_container *c,
2833 const char *contents) {
2842 if (!signature_is_pair(contents))
2845 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2848 if (!c->signature || c->signature[c->index] == 0)
2851 l = strlen(contents);
2853 if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
2854 !startswith(c->signature + c->index + 1, contents) ||
2855 c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
2858 r = message_peek_body(m, &m->rindex, 8, 0, NULL);
2862 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2863 c->index += 1 + l + 1;
2868 int sd_bus_message_enter_container(sd_bus_message *m, char type, const char *contents) {
2869 struct bus_container *c, *w;
2870 uint32_t *array_size = NULL;
2883 * We enforce a global limit on container depth, that is much
2884 * higher than the 32 structs and 32 arrays the specification
2885 * mandates. This is simpler to implement for us, and we need
2886 * this only to ensure our container array doesn't grow
2887 * without bounds. We are happy to return any data from a
2888 * message as long as the data itself is valid, even if the
2889 * overall message might be not.
2891 * Note that the message signature is validated when
2892 * parsing the headers, and that validation does check the
2895 * Note that the specification defines no limits on the depth
2896 * of stacked variants, but we do.
2898 if (m->n_containers >= BUS_CONTAINER_DEPTH)
2901 w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
2906 c = message_get_container(m);
2908 if (!c->signature || c->signature[c->index] == 0)
2911 signature = strdup(contents);
2915 c->saved_index = c->index;
2918 if (type == SD_BUS_TYPE_ARRAY)
2919 r = bus_message_enter_array(m, c, contents, &array_size);
2920 else if (type == SD_BUS_TYPE_VARIANT)
2921 r = bus_message_enter_variant(m, c, contents);
2922 else if (type == SD_BUS_TYPE_STRUCT)
2923 r = bus_message_enter_struct(m, c, contents);
2924 else if (type == SD_BUS_TYPE_DICT_ENTRY)
2925 r = bus_message_enter_dict_entry(m, c, contents);
2934 /* OK, let's fill it in */
2935 w += m->n_containers++;
2936 w->enclosing = type;
2937 w->signature = signature;
2939 w->array_size = array_size;
2941 w->begin = m->rindex;
2946 int sd_bus_message_exit_container(sd_bus_message *m) {
2947 struct bus_container *c;
2953 if (m->n_containers <= 0)
2956 c = message_get_container(m);
2957 if (c->enclosing == SD_BUS_TYPE_ARRAY) {
2960 l = BUS_MESSAGE_BSWAP32(m, *c->array_size);
2961 if (c->begin + l != m->rindex)
2965 if (c->signature && c->signature[c->index] != 0)
2975 static void message_quit_container(sd_bus_message *m) {
2976 struct bus_container *c;
2980 assert(m->n_containers > 0);
2982 c = message_get_container(m);
2985 assert(m->rindex >= c->before);
2986 m->rindex = c->before;
2988 /* Free container */
2992 /* Correct index of new top-level container */
2993 c = message_get_container(m);
2994 c->index = c->saved_index;
2997 int sd_bus_message_peek_type(sd_bus_message *m, char *type, const char **contents) {
2998 struct bus_container *c;
3006 c = message_get_container(m);
3008 if (!c->signature || c->signature[c->index] == 0)
3011 if (message_end_of_array(m, m->rindex))
3014 if (bus_type_is_basic(c->signature[c->index])) {
3018 *type = c->signature[c->index];
3022 if (c->signature[c->index] == SD_BUS_TYPE_ARRAY) {
3028 r = signature_element_length(c->signature+c->index+1, &l);
3034 sig = strndup(c->signature + c->index + 1, l);
3038 free(m->peeked_signature);
3039 m->peeked_signature = sig;
3045 *type = SD_BUS_TYPE_ARRAY;
3050 if (c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ||
3051 c->signature[c->index] == SD_BUS_TYPE_DICT_ENTRY_BEGIN) {
3057 r = signature_element_length(c->signature+c->index, &l);
3062 sig = strndup(c->signature + c->index + 1, l - 2);
3066 free(m->peeked_signature);
3067 m->peeked_signature = sig;
3073 *type = c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY;
3078 if (c->signature[c->index] == SD_BUS_TYPE_VARIANT) {
3084 r = message_peek_body(m, &rindex, 1, 1, &q);
3091 r = message_peek_body(m, &rindex, 1, l+1, &q);
3097 if (!validate_signature(q, l))
3104 *type = SD_BUS_TYPE_VARIANT;
3113 *type = c->enclosing;
3119 int sd_bus_message_rewind(sd_bus_message *m, int complete) {
3120 struct bus_container *c;
3128 message_reset_containers(m);
3130 m->root_container.index = 0;
3132 c = message_get_container(m);
3134 c = message_get_container(m);
3137 m->rindex = c->begin;
3140 return !isempty(c->signature);
3142 static int message_read_ap(
3147 unsigned n_array, n_struct;
3148 TypeStack stack[BUS_CONTAINER_DEPTH];
3149 unsigned stack_ptr = 0;
3157 /* Ideally, we'd just call ourselves recursively on every
3158 * complex type. However, the state of a va_list that is
3159 * passed to a function is undefined after that function
3160 * returns. This means we need to docode the va_list linearly
3161 * in a single stackframe. We hence implement our own
3162 * home-grown stack in an array. */
3164 n_array = (unsigned) -1;
3165 n_struct = strlen(types);
3170 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
3171 r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
3177 r = sd_bus_message_exit_container(m);
3185 if (n_array != (unsigned) -1)
3194 case SD_BUS_TYPE_BYTE:
3195 case SD_BUS_TYPE_BOOLEAN:
3196 case SD_BUS_TYPE_INT16:
3197 case SD_BUS_TYPE_UINT16:
3198 case SD_BUS_TYPE_INT32:
3199 case SD_BUS_TYPE_UINT32:
3200 case SD_BUS_TYPE_INT64:
3201 case SD_BUS_TYPE_UINT64:
3202 case SD_BUS_TYPE_DOUBLE:
3203 case SD_BUS_TYPE_STRING:
3204 case SD_BUS_TYPE_OBJECT_PATH:
3205 case SD_BUS_TYPE_SIGNATURE:
3206 case SD_BUS_TYPE_UNIX_FD: {
3209 p = va_arg(ap, void*);
3210 r = sd_bus_message_read_basic(m, *t, p);
3219 case SD_BUS_TYPE_ARRAY: {
3222 r = signature_element_length(t + 1, &k);
3228 memcpy(s, t + 1, k);
3231 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, s);
3238 if (n_array == (unsigned) -1) {
3243 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
3249 n_array = va_arg(ap, unsigned);
3254 case SD_BUS_TYPE_VARIANT: {
3257 s = va_arg(ap, const char *);
3261 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, s);
3267 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
3272 n_struct = strlen(s);
3273 n_array = (unsigned) -1;
3278 case SD_BUS_TYPE_STRUCT_BEGIN:
3279 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
3282 r = signature_element_length(t, &k);
3288 memcpy(s, t + 1, k - 2);
3291 r = sd_bus_message_enter_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
3298 if (n_array == (unsigned) -1) {
3303 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
3309 n_array = (unsigned) -1;
3322 int sd_bus_message_read(sd_bus_message *m, const char *types, ...) {
3333 va_start(ap, types);
3334 r = message_read_ap(m, types, ap);
3340 int sd_bus_message_read_array(sd_bus_message *m, char type, const void **ptr, size_t *size) {
3341 struct bus_container *c;
3351 if (!bus_type_is_trivial(type))
3357 if (BUS_MESSAGE_NEED_BSWAP(m))
3360 align = bus_type_get_alignment(type);
3364 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
3368 c = message_get_container(m);
3369 sz = BUS_MESSAGE_BSWAP32(m, *c->array_size);
3371 r = message_peek_body(m, &m->rindex, align, sz, &p);
3379 r = sd_bus_message_exit_container(m);
3383 *ptr = (const void*) p;
3389 message_quit_container(m);
3393 static int message_peek_fields(
3404 return buffer_peek(BUS_MESSAGE_FIELDS(m), BUS_MESSAGE_FIELDS_SIZE(m), rindex, align, nbytes, ret);
3407 static int message_peek_field_uint32(
3418 r = message_peek_fields(m, ri, 4, 4, &q);
3423 *ret = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
3428 static int message_peek_field_string(
3430 bool (*validate)(const char *p),
3441 r = message_peek_field_uint32(m, ri, &l);
3445 r = message_peek_fields(m, ri, 1, l+1, &q);
3450 if (!validate_nul(q, l))
3456 if (!validate_string(q, l))
3466 static int message_peek_field_signature(
3478 r = message_peek_fields(m, ri, 1, 1, &q);
3483 r = message_peek_fields(m, ri, 1, l+1, &q);
3487 if (!validate_signature(q, l))
3496 static int message_skip_fields(
3499 uint32_t array_size,
3500 const char **signature) {
3502 size_t original_index;
3509 original_index = *ri;
3515 if (array_size != (uint32_t) -1 &&
3516 array_size <= *ri - original_index)
3523 if (t == SD_BUS_TYPE_STRING) {
3525 r = message_peek_field_string(m, NULL, ri, NULL);
3531 } else if (t == SD_BUS_TYPE_OBJECT_PATH) {
3533 r = message_peek_field_string(m, object_path_is_valid, ri, NULL);
3539 } else if (t == SD_BUS_TYPE_SIGNATURE) {
3541 r = message_peek_field_signature(m, ri, NULL);
3547 } else if (bus_type_is_basic(t)) {
3550 align = bus_type_get_alignment(t);
3551 k = bus_type_get_size(t);
3552 assert(align > 0 && k > 0);
3554 r = message_peek_fields(m, ri, align, k, NULL);
3560 } else if (t == SD_BUS_TYPE_ARRAY) {
3562 r = signature_element_length(*signature+1, &l);
3572 strncpy(sig, *signature + 1, l-1);
3575 alignment = bus_type_get_alignment(sig[0]);
3579 r = message_peek_field_uint32(m, ri, &nas);
3582 if (nas > BUS_ARRAY_MAX_SIZE)
3585 r = message_peek_fields(m, ri, alignment, 0, NULL);
3589 r = message_skip_fields(m, ri, nas, (const char**) &s);
3594 (*signature) += 1 + l;
3596 } else if (t == SD_BUS_TYPE_VARIANT) {
3599 r = message_peek_field_signature(m, ri, &s);
3603 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
3609 } else if (t == SD_BUS_TYPE_STRUCT ||
3610 t == SD_BUS_TYPE_DICT_ENTRY) {
3612 r = signature_element_length(*signature, &l);
3619 strncpy(sig, *signature + 1, l-1);
3622 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
3633 int bus_message_parse_fields(sd_bus_message *m) {
3636 uint32_t unix_fds = 0;
3640 for (ri = 0; ri < BUS_MESSAGE_FIELDS_SIZE(m); ) {
3641 const char *signature;
3644 r = message_peek_fields(m, &ri, 8, 1, (void**) &header);
3648 r = message_peek_field_signature(m, &ri, &signature);
3653 case _SD_BUS_MESSAGE_HEADER_INVALID:
3656 case SD_BUS_MESSAGE_HEADER_PATH:
3661 if (!streq(signature, "o"))
3664 r = message_peek_field_string(m, object_path_is_valid, &ri, &m->path);
3667 case SD_BUS_MESSAGE_HEADER_INTERFACE:
3672 if (!streq(signature, "s"))
3675 r = message_peek_field_string(m, interface_name_is_valid, &ri, &m->interface);
3678 case SD_BUS_MESSAGE_HEADER_MEMBER:
3683 if (!streq(signature, "s"))
3686 r = message_peek_field_string(m, member_name_is_valid, &ri, &m->member);
3689 case SD_BUS_MESSAGE_HEADER_ERROR_NAME:
3694 if (!streq(signature, "s"))
3697 r = message_peek_field_string(m, error_name_is_valid, &ri, &m->error.name);
3700 case SD_BUS_MESSAGE_HEADER_DESTINATION:
3705 if (!streq(signature, "s"))
3708 r = message_peek_field_string(m, service_name_is_valid, &ri, &m->destination);
3711 case SD_BUS_MESSAGE_HEADER_SENDER:
3716 if (!streq(signature, "s"))
3719 r = message_peek_field_string(m, service_name_is_valid, &ri, &m->sender);
3723 case SD_BUS_MESSAGE_HEADER_SIGNATURE: {
3727 if (m->root_container.signature)
3730 if (!streq(signature, "g"))
3733 r = message_peek_field_signature(m, &ri, &s);
3741 free(m->root_container.signature);
3742 m->root_container.signature = c;
3746 case SD_BUS_MESSAGE_HEADER_REPLY_SERIAL:
3747 if (m->reply_serial != 0)
3750 if (!streq(signature, "u"))
3753 r = message_peek_field_uint32(m, &ri, &m->reply_serial);
3757 if (m->reply_serial == 0)
3762 case SD_BUS_MESSAGE_HEADER_UNIX_FDS:
3766 if (!streq(signature, "u"))
3769 r = message_peek_field_uint32(m, &ri, &unix_fds);
3779 r = message_skip_fields(m, &ri, (uint32_t) -1, (const char **) &signature);
3786 if (m->n_fds != unix_fds)
3789 if (isempty(m->root_container.signature) != (BUS_MESSAGE_BODY_SIZE(m) == 0))
3792 switch (m->header->type) {
3794 case SD_BUS_MESSAGE_TYPE_SIGNAL:
3795 if (!m->path || !m->interface || !m->member)
3799 case SD_BUS_MESSAGE_TYPE_METHOD_CALL:
3801 if (!m->path || !m->member)
3806 case SD_BUS_MESSAGE_TYPE_METHOD_RETURN:
3808 if (m->reply_serial == 0)
3812 case SD_BUS_MESSAGE_TYPE_METHOD_ERROR:
3814 if (m->reply_serial == 0 || !m->error.name)
3819 /* Try to read the error message, but if we can't it's a non-issue */
3820 if (m->header->type == SD_BUS_MESSAGE_TYPE_METHOD_ERROR)
3821 sd_bus_message_read(m, "s", &m->error.message);
3826 int bus_message_seal(sd_bus_message *m, uint64_t serial) {
3827 struct bus_body_part *part;
3837 if (m->n_containers > 0)
3843 /* If there's a non-trivial signature set, then add it in here */
3844 if (!isempty(m->root_container.signature)) {
3845 r = message_append_field_signature(m, SD_BUS_MESSAGE_HEADER_SIGNATURE, m->root_container.signature, NULL);
3851 r = message_append_field_uint32(m, SD_BUS_MESSAGE_HEADER_UNIX_FDS, m->n_fds);
3856 /* Add padding at the end of the fields part, since we know
3857 * the body needs to start at an 8 byte alignment. We made
3858 * sure we allocated enough space for this, so all we need to
3859 * do here is to zero it out. */
3860 l = BUS_MESSAGE_FIELDS_SIZE(m);
3863 memset((uint8_t*) BUS_MESSAGE_FIELDS(m) + l, 0, a);
3865 /* If this is something we can send as memfd, then let's seal
3866 the memfd now. Note that we can send memfds as payload only
3867 for directed messages, and not for broadcasts. */
3868 if (m->destination) {
3869 MESSAGE_FOREACH_PART(part, i, m)
3870 if (part->memfd >= 0 && !part->sealed && part->size > MEMFD_MIN_SIZE) {
3871 bus_body_part_unmap(part);
3873 if (ioctl(part->memfd, KDBUS_CMD_MEMFD_SEAL_SET, 1) >= 0)
3874 part->sealed = true;
3878 m->header->serial = serial;
3884 int sd_bus_message_set_destination(sd_bus_message *m, const char *destination) {
3894 return message_append_field_string(m, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &m->destination);
3897 int bus_message_dump(sd_bus_message *m) {
3898 const char *u = NULL, *uu = NULL, *s = NULL;
3899 char **cmdline = NULL;
3902 uid_t owner, audit_loginuid;
3903 uint32_t audit_sessionid;
3907 printf("Message %p\n"
3914 "\tfields_size=%u\n"
3919 "\tdestination=%s\n"
3922 "\treply_serial=%u\n"
3924 "\terror.message=%s\n"
3926 "\tn_body_parts=%u\n",
3933 BUS_MESSAGE_SERIAL(m),
3934 BUS_MESSAGE_FIELDS_SIZE(m),
3935 BUS_MESSAGE_BODY_SIZE(m),
3937 strna(m->interface),
3939 strna(m->destination),
3941 strna(m->root_container.signature),
3943 strna(m->error.name),
3944 strna(m->error.message),
3949 printf("\tpid=%lu\n", (unsigned long) m->pid);
3951 printf("\ttid=%lu\n", (unsigned long) m->tid);
3953 printf("\tuid=%lu\n", (unsigned long) m->uid);
3955 printf("\tgid=%lu\n", (unsigned long) m->gid);
3956 if (m->pid_starttime != 0)
3957 printf("\tpid_starttime=%llu\n", (unsigned long long) m->pid_starttime);
3958 if (m->monotonic != 0)
3959 printf("\tmonotonic=%llu\n", (unsigned long long) m->monotonic);
3960 if (m->realtime != 0)
3961 printf("\trealtime=%llu\n", (unsigned long long) m->realtime);
3963 printf("\texe=[%s]\n", m->exe);
3965 printf("\tcomm=[%s]\n", m->comm);
3967 printf("\ttid_comm=[%s]\n", m->tid_comm);
3969 printf("\tlabel=[%s]\n", m->label);
3971 printf("\tcgroup=[%s]\n", m->cgroup);
3973 sd_bus_message_get_unit(m, &u);
3975 printf("\tunit=[%s]\n", u);
3976 sd_bus_message_get_user_unit(m, &uu);
3978 printf("\tuser_unit=[%s]\n", uu);
3979 sd_bus_message_get_session(m, &s);
3981 printf("\tsession=[%s]\n", s);
3982 if (sd_bus_message_get_owner_uid(m, &owner) >= 0)
3983 printf("\towner_uid=%lu\n", (unsigned long) owner);
3984 if (sd_bus_message_get_audit_loginuid(m, &audit_loginuid) >= 0)
3985 printf("\taudit_loginuid=%lu\n", (unsigned long) audit_loginuid);
3986 if (sd_bus_message_get_audit_sessionid(m, &audit_sessionid) >= 0)
3987 printf("\taudit_sessionid=%lu\n", (unsigned long) audit_sessionid);
3989 printf("\tCAP_KILL=%i\n", sd_bus_message_has_effective_cap(m, 5));
3991 if (sd_bus_message_get_cmdline(m, &cmdline) >= 0) {
3994 fputs("\tcmdline=[", stdout);
3995 STRV_FOREACH(c, cmdline) {
4002 fputs("]\n", stdout);
4005 r = sd_bus_message_rewind(m, true);
4007 log_error("Failed to rewind: %s", strerror(-r));
4011 printf("BEGIN_MESSAGE \"%s\" {\n", strempty(m->root_container.signature));
4014 _cleanup_free_ char *prefix = NULL;
4015 const char *contents = NULL;
4030 r = sd_bus_message_peek_type(m, &type, &contents);
4032 log_error("Failed to peek type: %s", strerror(-r));
4039 r = sd_bus_message_exit_container(m);
4041 log_error("Failed to exit container: %s", strerror(-r));
4047 prefix = strrep("\t", level);
4051 if (type == SD_BUS_TYPE_ARRAY)
4052 printf("%s} END_ARRAY \n", prefix);
4053 else if (type == SD_BUS_TYPE_VARIANT)
4054 printf("%s} END_VARIANT\n", prefix);
4055 else if (type == SD_BUS_TYPE_STRUCT)
4056 printf("%s} END_STRUCT\n", prefix);
4057 else if (type == SD_BUS_TYPE_DICT_ENTRY)
4058 printf("%s} END_DICT_ENTRY\n", prefix);
4063 prefix = strrep("\t", level);
4067 if (bus_type_is_container(type) > 0) {
4068 r = sd_bus_message_enter_container(m, type, contents);
4070 log_error("Failed to enter container: %s", strerror(-r));
4074 if (type == SD_BUS_TYPE_ARRAY)
4075 printf("%sBEGIN_ARRAY \"%s\" {\n", prefix, contents);
4076 else if (type == SD_BUS_TYPE_VARIANT)
4077 printf("%sBEGIN_VARIANT \"%s\" {\n", prefix, contents);
4078 else if (type == SD_BUS_TYPE_STRUCT)
4079 printf("%sBEGIN_STRUCT \"%s\" {\n", prefix, contents);
4080 else if (type == SD_BUS_TYPE_DICT_ENTRY)
4081 printf("%sBEGIN_DICT_ENTRY \"%s\" {\n", prefix, contents);
4088 r = sd_bus_message_read_basic(m, type, &basic);
4090 log_error("Failed to get basic: %s", strerror(-r));
4096 case SD_BUS_TYPE_BYTE:
4097 printf("%sBYTE: %u\n", prefix, basic.u8);
4100 case SD_BUS_TYPE_BOOLEAN:
4101 printf("%sBOOLEAN: %s\n", prefix, yes_no(basic.i));
4104 case SD_BUS_TYPE_INT16:
4105 printf("%sINT16: %i\n", prefix, basic.s16);
4108 case SD_BUS_TYPE_UINT16:
4109 printf("%sUINT16: %u\n", prefix, basic.u16);
4112 case SD_BUS_TYPE_INT32:
4113 printf("%sINT32: %i\n", prefix, basic.s32);
4116 case SD_BUS_TYPE_UINT32:
4117 printf("%sUINT32: %u\n", prefix, basic.u32);
4120 case SD_BUS_TYPE_INT64:
4121 printf("%sINT64: %lli\n", prefix, (long long) basic.s64);
4124 case SD_BUS_TYPE_UINT64:
4125 printf("%sUINT64: %llu\n", prefix, (unsigned long long) basic.u64);
4128 case SD_BUS_TYPE_DOUBLE:
4129 printf("%sDOUBLE: %g\n", prefix, basic.d64);
4132 case SD_BUS_TYPE_STRING:
4133 printf("%sSTRING: \"%s\"\n", prefix, basic.string);
4136 case SD_BUS_TYPE_OBJECT_PATH:
4137 printf("%sOBJECT_PATH: \"%s\"\n", prefix, basic.string);
4140 case SD_BUS_TYPE_SIGNATURE:
4141 printf("%sSIGNATURE: \"%s\"\n", prefix, basic.string);
4144 case SD_BUS_TYPE_UNIX_FD:
4145 printf("%sUNIX_FD: %i\n", prefix, basic.i);
4149 assert_not_reached("Unknown basic type.");
4153 printf("} END_MESSAGE\n");
4157 int bus_message_get_blob(sd_bus_message *m, void **buffer, size_t *sz) {
4161 struct bus_body_part *part;
4167 total = BUS_MESSAGE_SIZE(m);
4173 e = mempcpy(p, m->header, BUS_MESSAGE_BODY_BEGIN(m));
4174 MESSAGE_FOREACH_PART(part, i, m)
4175 e = mempcpy(e, part->data, part->size);
4177 assert(total == (size_t) ((uint8_t*) e - (uint8_t*) p));
4185 int bus_message_read_strv_extend(sd_bus_message *m, char ***l) {
4191 r = sd_bus_message_enter_container(m, 'a', "s");
4198 r = sd_bus_message_read_basic(m, 's', &s);
4204 r = strv_extend(l, s);
4209 r = sd_bus_message_exit_container(m);
4216 const char* bus_message_get_arg(sd_bus_message *m, unsigned i) {
4218 const char *t = NULL;
4223 r = sd_bus_message_rewind(m, true);
4227 for (j = 0; j <= i; j++) {
4230 r = sd_bus_message_peek_type(m, &type, NULL);
4234 if (type != SD_BUS_TYPE_STRING &&
4235 type != SD_BUS_TYPE_OBJECT_PATH &&
4236 type != SD_BUS_TYPE_SIGNATURE)
4239 r = sd_bus_message_read_basic(m, type, &t);
4247 bool bus_header_is_complete(struct bus_header *h, size_t size) {
4253 if (size < sizeof(struct bus_header))
4256 full = sizeof(struct bus_header) +
4257 (h->endian == SD_BUS_NATIVE_ENDIAN ? h->fields_size : bswap_32(h->fields_size));
4259 return size >= full;
4262 int bus_header_message_size(struct bus_header *h, size_t *sum) {
4268 if (h->endian == SD_BUS_NATIVE_ENDIAN) {
4269 fs = h->fields_size;
4271 } else if (h->endian == SD_BUS_REVERSE_ENDIAN) {
4272 fs = bswap_32(h->fields_size);
4273 bs = bswap_32(h->body_size);
4277 *sum = sizeof(struct bus_header) + ALIGN8(fs) + bs;
4281 int bus_message_to_errno(sd_bus_message *m) {
4284 if (m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_ERROR)
4287 return bus_error_to_errno(&m->error);