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/>.
28 #include "time-util.h"
29 #include "cgroup-util.h"
32 #include "bus-message.h"
33 #include "bus-internal.h"
35 #include "bus-signature.h"
37 static int message_append_basic(sd_bus_message *m, char type, const void *p, const void **stored);
39 static void reset_containers(sd_bus_message *m) {
44 for (i = 0; i < m->n_containers; i++)
45 free(m->containers[i].signature);
51 m->root_container.index = 0;
54 static void message_free(sd_bus_message *m) {
70 ioctl(m->bus->input_fd, KDBUS_CMD_MSG_RELEASE, m->kdbus);
73 close_many(m->fds, m->n_fds);
80 free(m->cmdline_array);
83 free(m->root_container.signature);
85 free(m->peeked_signature);
93 static void* buffer_extend(void **p, uint32_t *sz, size_t align, size_t extend) {
101 start = ALIGN_TO((size_t) *sz, align);
105 return (uint8_t*) *p + start;
107 if (n > (size_t) ((uint32_t) -1))
114 /* Zero out padding */
116 memset((uint8_t*) k + *sz, 0, start - *sz);
121 return (uint8_t*) k + start;
124 static void *message_extend_fields(sd_bus_message *m, size_t align, size_t sz) {
130 p = buffer_extend(&m->fields, &m->header->fields_size, align, sz);
134 if (o != m->fields) {
135 /* Adjust quick access pointers */
138 m->path = (const char*) m->fields + (m->path - (const char*) o);
140 m->interface = (const char*) m->fields + (m->interface - (const char*) o);
142 m->member = (const char*) m->fields + (m->member - (const char*) o);
144 m->destination = (const char*) m->fields + (m->destination - (const char*) o);
146 m->sender = (const char*) m->fields + (m->sender - (const char*) o);
148 m->error.name = (const char*) m->fields + (m->error.name - (const char*) o);
151 m->free_fields = true;
156 static int message_append_field_string(
169 if (l > (size_t) (uint32_t) -1)
172 /* field id byte + signature length + signature 's' + NUL + string length + string + NUL */
173 p = message_extend_fields(m, 8, 4 + 4 + l + 1);
182 ((uint32_t*) p)[1] = l;
183 memcpy(p + 8, s, l + 1);
186 *ret = (const char*) p + 8;
191 static int message_append_field_signature(
206 /* field id byte + signature length + signature 'g' + NUL + string length + string + NUL */
207 p = message_extend_fields(m, 8, 4 + 1 + l + 1);
213 p[2] = SD_BUS_TYPE_SIGNATURE;
216 memcpy(p + 5, s, l + 1);
219 *ret = (const char*) p + 5;
224 static int message_append_field_uint32(sd_bus_message *m, uint8_t h, uint32_t x) {
229 /* field id byte + signature length + signature 'u' + NUL + value */
230 p = message_extend_fields(m, 8, 4 + 4);
236 p[2] = SD_BUS_TYPE_UINT32;
239 ((uint32_t*) p)[1] = x;
244 int bus_message_from_header(
249 const struct ucred *ucred,
252 sd_bus_message **ret) {
255 struct bus_header *h;
258 assert(buffer || length <= 0);
259 assert(fds || n_fds <= 0);
262 if (length < sizeof(struct bus_header))
272 if (h->type == _SD_BUS_MESSAGE_TYPE_INVALID)
275 if (h->endian != SD_BUS_LITTLE_ENDIAN &&
276 h->endian != SD_BUS_BIG_ENDIAN)
279 a = ALIGN(sizeof(sd_bus_message)) + ALIGN(extra);
282 label_sz = strlen(label);
300 m->uid_valid = m->gid_valid = true;
304 m->label = (char*) m + ALIGN(sizeof(sd_bus_message)) + ALIGN(extra);
305 memcpy(m->label, label, label_sz + 1);
312 int bus_message_from_malloc(
317 const struct ucred *ucred,
319 sd_bus_message **ret) {
324 r = bus_message_from_header(buffer, length, fds, n_fds, ucred, label, 0, &m);
328 if (length != BUS_MESSAGE_SIZE(m)) {
333 m->fields = (uint8_t*) buffer + sizeof(struct bus_header);
334 m->body = (uint8_t*) buffer + sizeof(struct bus_header) + ALIGN8(BUS_MESSAGE_FIELDS_SIZE(m));
337 m->iovec[0].iov_base = buffer;
338 m->iovec[0].iov_len = length;
340 r = bus_message_parse_fields(m);
344 /* We take possession of the memory and fds now */
345 m->free_header = true;
356 static sd_bus_message *message_new(sd_bus *bus, uint8_t type) {
359 m = malloc0(ALIGN(sizeof(sd_bus_message)) + sizeof(struct bus_header));
364 m->header = (struct bus_header*) ((uint8_t*) m + ALIGN(sizeof(struct sd_bus_message)));
365 m->header->endian = SD_BUS_NATIVE_ENDIAN;
366 m->header->type = type;
367 m->header->version = bus ? bus->message_version : 1;
368 m->allow_fds = !bus || bus->can_fds || (bus->state != BUS_HELLO && bus->state != BUS_RUNNING);
373 int sd_bus_message_new_signal(
376 const char *interface,
378 sd_bus_message **m) {
391 if (bus && bus->state == BUS_UNSET)
394 t = message_new(bus, SD_BUS_MESSAGE_TYPE_SIGNAL);
398 t->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
400 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_PATH, SD_BUS_TYPE_OBJECT_PATH, path, &t->path);
403 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_INTERFACE, SD_BUS_TYPE_STRING, interface, &t->interface);
406 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_MEMBER, SD_BUS_TYPE_STRING, member, &t->member);
414 sd_bus_message_unref(t);
418 int sd_bus_message_new_method_call(
420 const char *destination,
422 const char *interface,
424 sd_bus_message **m) {
435 if (bus && bus->state == BUS_UNSET)
438 t = message_new(bus, SD_BUS_MESSAGE_TYPE_METHOD_CALL);
442 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_PATH, SD_BUS_TYPE_OBJECT_PATH, path, &t->path);
445 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_MEMBER, SD_BUS_TYPE_STRING, member, &t->member);
450 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_INTERFACE, SD_BUS_TYPE_STRING, interface, &t->interface);
456 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &t->destination);
469 static int message_new_reply(
471 sd_bus_message *call,
473 sd_bus_message **m) {
482 if (call->header->type != SD_BUS_MESSAGE_TYPE_METHOD_CALL)
486 if (bus && bus->state == BUS_UNSET)
489 t = message_new(bus, type);
493 t->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
494 t->reply_serial = BUS_MESSAGE_SERIAL(call);
496 r = message_append_field_uint32(t, SD_BUS_MESSAGE_HEADER_REPLY_SERIAL, t->reply_serial);
501 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, call->sender, &t->sender);
506 t->dont_send = !!(call->header->flags & SD_BUS_MESSAGE_NO_REPLY_EXPECTED);
516 int sd_bus_message_new_method_return(
518 sd_bus_message *call,
519 sd_bus_message **m) {
521 return message_new_reply(bus, call, SD_BUS_MESSAGE_TYPE_METHOD_RETURN, m);
524 int sd_bus_message_new_method_error(
526 sd_bus_message *call,
527 const sd_bus_error *e,
528 sd_bus_message **m) {
533 if (!sd_bus_error_is_set(e))
538 r = message_new_reply(bus, call, SD_BUS_MESSAGE_TYPE_METHOD_ERROR, &t);
542 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_ERROR_NAME, SD_BUS_TYPE_STRING, e->name, &t->error.name);
547 r = message_append_basic(t, SD_BUS_TYPE_STRING, e->message, (const void**) &t->error.message);
560 sd_bus_message* sd_bus_message_ref(sd_bus_message *m) {
564 assert(m->n_ref > 0);
570 sd_bus_message* sd_bus_message_unref(sd_bus_message *m) {
574 assert(m->n_ref > 0);
583 int sd_bus_message_get_type(sd_bus_message *m, uint8_t *type) {
589 *type = m->header->type;
593 int sd_bus_message_get_serial(sd_bus_message *m, uint64_t *serial) {
598 if (m->header->serial == 0)
601 *serial = BUS_MESSAGE_SERIAL(m);
605 int sd_bus_message_get_reply_serial(sd_bus_message *m, uint64_t *serial) {
610 if (m->reply_serial == 0)
613 *serial = m->reply_serial;
617 int sd_bus_message_get_no_reply(sd_bus_message *m) {
621 return m->header->type == SD_BUS_MESSAGE_TYPE_METHOD_CALL ? !!(m->header->flags & SD_BUS_MESSAGE_NO_REPLY_EXPECTED) : 0;
624 const char *sd_bus_message_get_path(sd_bus_message *m) {
631 const char *sd_bus_message_get_interface(sd_bus_message *m) {
638 const char *sd_bus_message_get_member(sd_bus_message *m) {
644 const char *sd_bus_message_get_destination(sd_bus_message *m) {
648 return m->destination;
651 const char *sd_bus_message_get_sender(sd_bus_message *m) {
658 const sd_bus_error *sd_bus_message_get_error(sd_bus_message *m) {
662 if (!sd_bus_error_is_set(&m->error))
668 int sd_bus_message_get_uid(sd_bus_message *m, uid_t *uid) {
680 int sd_bus_message_get_gid(sd_bus_message *m, gid_t *gid) {
692 int sd_bus_message_get_pid(sd_bus_message *m, pid_t *pid) {
704 int sd_bus_message_get_tid(sd_bus_message *m, pid_t *tid) {
716 int sd_bus_message_get_pid_starttime(sd_bus_message *m, uint64_t *usec) {
721 if (m->pid_starttime <= 0)
724 *usec = m->pid_starttime;
728 int sd_bus_message_get_selinux_context(sd_bus_message *m, const char **ret) {
738 int sd_bus_message_get_monotonic_timestamp(sd_bus_message *m, uint64_t *usec) {
743 if (m->monotonic <= 0)
746 *usec = m->monotonic;
750 int sd_bus_message_get_realtime_timestamp(sd_bus_message *m, uint64_t *usec) {
755 if (m->realtime <= 0)
762 int sd_bus_message_get_comm(sd_bus_message *m, const char **ret) {
774 int sd_bus_message_get_tid_comm(sd_bus_message *m, const char **ret) {
786 int sd_bus_message_get_exe(sd_bus_message *m, const char **ret) {
798 int sd_bus_message_get_cgroup(sd_bus_message *m, const char **ret) {
810 int sd_bus_message_get_unit(sd_bus_message *m, const char **ret) {
821 r = cg_path_get_unit(m->cgroup, &m->unit);
830 int sd_bus_message_get_user_unit(sd_bus_message *m, const char **ret) {
841 r = cg_path_get_user_unit(m->cgroup, &m->user_unit);
850 int sd_bus_message_get_session(sd_bus_message *m, const char **ret) {
861 r = cg_path_get_session(m->cgroup, &m->session);
870 int sd_bus_message_get_owner_uid(sd_bus_message *m, uid_t *uid) {
878 return cg_path_get_owner_uid(m->cgroup, uid);
881 int sd_bus_message_get_cmdline(sd_bus_message *m, char ***cmdline) {
892 for (p = m->cmdline, n = 0; p < m->cmdline + m->cmdline_length; p++)
896 m->cmdline_array = new(char*, n + 1);
897 if (!m->cmdline_array)
900 for (p = m->cmdline, i = 0, first = true; p < m->cmdline + m->cmdline_length; p++) {
902 m->cmdline_array[i++] = (char*) p;
907 m->cmdline_array[i] = NULL;
908 *cmdline = m->cmdline_array;
913 int sd_bus_message_get_audit_sessionid(sd_bus_message *m, uint32_t *sessionid) {
921 *sessionid = m->audit->sessionid;
925 int sd_bus_message_get_audit_loginuid(sd_bus_message *m, uid_t *uid) {
933 *uid = m->audit->loginuid;
937 int sd_bus_message_has_effective_cap(sd_bus_message *m, int capability) {
947 sz = m->capability_size / 4;
948 if ((unsigned) capability >= sz*8)
951 return !!(m->capability[2 * sz + (capability / 8)] & (1 << (capability % 8)));
954 int sd_bus_message_is_signal(sd_bus_message *m, const char *interface, const char *member) {
958 if (m->header->type != SD_BUS_MESSAGE_TYPE_SIGNAL)
961 if (interface && (!m->interface || !streq(m->interface, interface)))
964 if (member && (!m->member || !streq(m->member, member)))
970 int sd_bus_message_is_method_call(sd_bus_message *m, const char *interface, const char *member) {
974 if (m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_CALL)
977 if (interface && (!m->interface || !streq(m->interface, interface)))
980 if (member && (!m->member || !streq(m->member, member)))
986 int sd_bus_message_is_method_error(sd_bus_message *m, const char *name) {
990 if (m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_ERROR)
993 if (name && (!m->error.name || !streq(m->error.name, name)))
999 int sd_bus_message_set_no_reply(sd_bus_message *m, int b) {
1004 if (m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_CALL)
1008 m->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
1010 m->header->flags &= ~SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
1015 static struct bus_container *message_get_container(sd_bus_message *m) {
1018 if (m->n_containers == 0)
1019 return &m->root_container;
1021 assert(m->containers);
1022 return m->containers + m->n_containers - 1;
1025 static void *message_extend_body(sd_bus_message *m, size_t align, size_t sz) {
1028 struct bus_container *c;
1034 added = m->header->body_size;
1036 p = buffer_extend(&m->body, &m->header->body_size, align, sz);
1040 added = m->header->body_size - added;
1042 for (c = m->containers; c < m->containers + m->n_containers; c++)
1043 if (c->array_size) {
1044 c->array_size = (uint32_t*) ((uint8_t*) m->body + ((uint8_t*) c->array_size - (uint8_t*) o));
1045 *c->array_size += added;
1049 if (m->error.message)
1050 m->error.message = (const char*) m->body + (m->error.message - (const char*) o);
1053 m->free_body = true;
1058 int message_append_basic(sd_bus_message *m, char type, const void *p, const void **stored) {
1059 struct bus_container *c;
1074 if (!bus_type_is_basic(type))
1077 c = message_get_container(m);
1079 if (c->signature && c->signature[c->index]) {
1080 /* Container signature is already set */
1082 if (c->signature[c->index] != type)
1085 /* Maybe we can append to the signature? But only if this is the top-level container*/
1086 if (c->enclosing != 0)
1089 e = strextend(&c->signature, CHAR_TO_STR(type), NULL);
1096 case SD_BUS_TYPE_STRING:
1097 case SD_BUS_TYPE_OBJECT_PATH:
1100 sz = 4 + strlen(p) + 1;
1103 case SD_BUS_TYPE_SIGNATURE:
1106 sz = 1 + strlen(p) + 1;
1109 case SD_BUS_TYPE_BOOLEAN:
1112 assert_cc(sizeof(int) == sizeof(uint32_t));
1118 case SD_BUS_TYPE_UNIX_FD: {
1121 if (!m->allow_fds) {
1134 fd = fcntl(z, F_DUPFD_CLOEXEC, 3);
1140 f = realloc(m->fds, sizeof(int) * (m->n_fds + 1));
1154 align = bus_type_get_alignment(type);
1155 sz = bus_type_get_size(type);
1162 a = message_extend_body(m, align, sz);
1168 if (type == SD_BUS_TYPE_STRING || type == SD_BUS_TYPE_OBJECT_PATH) {
1169 *(uint32_t*) a = sz - 5;
1170 memcpy((uint8_t*) a + 4, p, sz - 4);
1173 *stored = (const uint8_t*) a + 4;
1175 } else if (type == SD_BUS_TYPE_SIGNATURE) {
1176 *(uint8_t*) a = sz - 1;
1177 memcpy((uint8_t*) a + 1, p, sz - 1);
1180 *stored = (const uint8_t*) a + 1;
1181 } else if (type == SD_BUS_TYPE_UNIX_FD) {
1182 *(uint32_t*) a = fdi;
1196 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1202 /* Truncate extended signature again */
1204 c->signature[c->index] = 0;
1207 close_nointr_nofail(fd);
1212 int sd_bus_message_append_basic(sd_bus_message *m, char type, const void *p) {
1213 return message_append_basic(m, type, p, NULL);
1216 int sd_bus_message_append_string_space(sd_bus_message *m, size_t size, char **s) {
1217 struct bus_container *c;
1229 c = message_get_container(m);
1231 if (c->signature && c->signature[c->index]) {
1232 /* Container signature is already set */
1234 if (c->signature[c->index] != SD_BUS_TYPE_STRING)
1237 /* Maybe we can append to the signature? But only if this is the top-level container*/
1238 if (c->enclosing != 0)
1241 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRING), NULL);
1247 a = message_extend_body(m, 4, 4 + size + 1);
1253 *(uint32_t*) a = size;
1258 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1265 c->signature[c->index] = 0;
1270 static int bus_message_open_array(
1272 struct bus_container *c,
1273 const char *contents,
1274 uint32_t **array_size) {
1287 if (!signature_is_single(contents))
1290 alignment = bus_type_get_alignment(contents[0]);
1294 if (c->signature && c->signature[c->index]) {
1296 /* Verify the existing signature */
1298 if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
1301 if (!startswith(c->signature + c->index + 1, contents))
1304 nindex = c->index + 1 + strlen(contents);
1306 if (c->enclosing != 0)
1309 /* Extend the existing signature */
1311 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_ARRAY), contents, NULL);
1315 nindex = e - c->signature;
1318 saved = m->header->body_size;
1319 a = message_extend_body(m, 4, 4);
1321 /* Truncate extended signature again */
1323 c->signature[c->index] = 0;
1329 if (!message_extend_body(m, alignment, 0)) {
1330 /* Add alignment between size and first element */
1332 c->signature[c->index] = 0;
1334 m->header->body_size = saved;
1338 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1341 /* m->body might have changed so let's readjust a */
1342 a = (uint8_t*) m->body + ((uint8_t*) a - (uint8_t*) b);
1349 static int bus_message_open_variant(
1351 struct bus_container *c,
1352 const char *contents) {
1362 if (!signature_is_single(contents))
1365 if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
1368 if (c->signature && c->signature[c->index]) {
1370 if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
1374 if (c->enclosing != 0)
1377 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_VARIANT), NULL);
1382 l = strlen(contents);
1383 a = message_extend_body(m, 1, 1 + l + 1);
1385 /* Truncate extended signature again */
1387 c->signature[c->index] = 0;
1393 memcpy((uint8_t*) a + 1, contents, l + 1);
1395 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1401 static int bus_message_open_struct(
1403 struct bus_container *c,
1404 const char *contents) {
1413 if (!signature_is_valid(contents, false))
1416 if (c->signature && c->signature[c->index]) {
1419 l = strlen(contents);
1421 if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
1422 !startswith(c->signature + c->index + 1, contents) ||
1423 c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
1426 nindex = c->index + 1 + l + 1;
1428 if (c->enclosing != 0)
1431 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_BEGIN), contents, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_END), NULL);
1435 nindex = e - c->signature;
1438 /* Align contents to 8 byte boundary */
1439 if (!message_extend_body(m, 8, 0)) {
1441 c->signature[c->index] = 0;
1446 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1452 static int bus_message_open_dict_entry(
1454 struct bus_container *c,
1455 const char *contents) {
1463 if (!signature_is_pair(contents))
1466 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1469 if (c->signature && c->signature[c->index]) {
1472 l = strlen(contents);
1474 if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
1475 !startswith(c->signature + c->index + 1, contents) ||
1476 c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
1479 nindex = c->index + 1 + l + 1;
1483 /* Align contents to 8 byte boundary */
1484 if (!message_extend_body(m, 8, 0))
1487 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1493 int sd_bus_message_open_container(
1496 const char *contents) {
1498 struct bus_container *c, *w;
1499 uint32_t *array_size = NULL;
1511 /* Make sure we have space for one more container */
1512 w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
1517 c = message_get_container(m);
1519 signature = strdup(contents);
1523 /* Save old index in the parent container, in case we have to
1524 * abort this container */
1525 c->saved_index = c->index;
1526 before = m->header->body_size;
1528 if (type == SD_BUS_TYPE_ARRAY)
1529 r = bus_message_open_array(m, c, contents, &array_size);
1530 else if (type == SD_BUS_TYPE_VARIANT)
1531 r = bus_message_open_variant(m, c, contents);
1532 else if (type == SD_BUS_TYPE_STRUCT)
1533 r = bus_message_open_struct(m, c, contents);
1534 else if (type == SD_BUS_TYPE_DICT_ENTRY)
1535 r = bus_message_open_dict_entry(m, c, contents);
1544 /* OK, let's fill it in */
1545 w += m->n_containers++;
1546 w->enclosing = type;
1547 w->signature = signature;
1549 w->array_size = array_size;
1551 w->begin = m->rindex;
1556 int sd_bus_message_close_container(sd_bus_message *m) {
1557 struct bus_container *c;
1563 if (m->n_containers <= 0)
1566 c = message_get_container(m);
1567 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1568 if (c->signature && c->signature[c->index] != 0)
1577 static void message_abort_container(sd_bus_message *m) {
1578 struct bus_container *c;
1583 assert(m->n_containers > 0);
1585 c = message_get_container(m);
1588 assert(m->header->body_size >= c->before);
1589 delta = m->header->body_size - c->before;
1590 m->header->body_size = c->before;
1592 /* Free container */
1596 /* Correct index of new top-level container */
1597 c = message_get_container(m);
1598 c->index = c->saved_index;
1600 /* Correct array sizes all the way up */
1601 for (c = m->containers; c < m->containers + m->n_containers; c++)
1602 if (c->array_size) {
1603 assert(*c->array_size >= delta);
1604 *c->array_size -= delta;
1614 static int type_stack_push(TypeStack *stack, unsigned max, unsigned *i, const char *types, unsigned n_struct, unsigned n_array) {
1621 stack[*i].types = types;
1622 stack[*i].n_struct = n_struct;
1623 stack[*i].n_array = n_array;
1629 static int type_stack_pop(TypeStack *stack, unsigned max, unsigned *i, const char **types, unsigned *n_struct, unsigned *n_array) {
1640 *types = stack[*i].types;
1641 *n_struct = stack[*i].n_struct;
1642 *n_array = stack[*i].n_array;
1647 int bus_message_append_ap(
1652 unsigned n_array, n_struct;
1653 TypeStack stack[BUS_CONTAINER_DEPTH];
1654 unsigned stack_ptr = 0;
1662 n_array = (unsigned) -1;
1663 n_struct = strlen(types);
1668 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
1669 r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
1675 r = sd_bus_message_close_container(m);
1683 if (n_array != (unsigned) -1)
1692 case SD_BUS_TYPE_BYTE: {
1695 x = (uint8_t) va_arg(ap, int);
1696 r = sd_bus_message_append_basic(m, *t, &x);
1700 case SD_BUS_TYPE_BOOLEAN:
1701 case SD_BUS_TYPE_INT32:
1702 case SD_BUS_TYPE_UINT32:
1703 case SD_BUS_TYPE_UNIX_FD: {
1706 /* We assume a boolean is the same as int32_t */
1707 assert_cc(sizeof(int32_t) == sizeof(int));
1709 x = va_arg(ap, uint32_t);
1710 r = sd_bus_message_append_basic(m, *t, &x);
1714 case SD_BUS_TYPE_INT16:
1715 case SD_BUS_TYPE_UINT16: {
1718 x = (uint16_t) va_arg(ap, int);
1719 r = sd_bus_message_append_basic(m, *t, &x);
1723 case SD_BUS_TYPE_INT64:
1724 case SD_BUS_TYPE_UINT64:
1725 case SD_BUS_TYPE_DOUBLE: {
1728 x = va_arg(ap, uint64_t);
1729 r = sd_bus_message_append_basic(m, *t, &x);
1733 case SD_BUS_TYPE_STRING:
1734 case SD_BUS_TYPE_OBJECT_PATH:
1735 case SD_BUS_TYPE_SIGNATURE: {
1738 x = va_arg(ap, const char*);
1739 r = sd_bus_message_append_basic(m, *t, x);
1743 case SD_BUS_TYPE_ARRAY: {
1746 r = signature_element_length(t + 1, &k);
1752 memcpy(s, t + 1, k);
1755 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, s);
1760 if (n_array == (unsigned) -1) {
1765 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
1771 n_array = va_arg(ap, unsigned);
1776 case SD_BUS_TYPE_VARIANT: {
1779 s = va_arg(ap, const char*);
1783 r = sd_bus_message_open_container(m, SD_BUS_TYPE_VARIANT, s);
1787 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
1792 n_struct = strlen(s);
1793 n_array = (unsigned) -1;
1798 case SD_BUS_TYPE_STRUCT_BEGIN:
1799 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
1802 r = signature_element_length(t, &k);
1809 memcpy(s, t + 1, k - 2);
1812 r = sd_bus_message_open_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
1817 if (n_array == (unsigned) -1) {
1822 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
1828 n_array = (unsigned) -1;
1844 int sd_bus_message_append(sd_bus_message *m, const char *types, ...) {
1855 va_start(ap, types);
1856 r = bus_message_append_ap(m, types, ap);
1862 int sd_bus_message_append_array_space(sd_bus_message *m, char type, size_t size, void **ptr) {
1871 if (!bus_type_is_trivial(type))
1873 if (!ptr && size > 0)
1876 align = bus_type_get_alignment(type);
1877 sz = bus_type_get_size(type);
1879 assert_se(align > 0);
1885 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
1889 a = message_extend_body(m, align, size);
1895 r = sd_bus_message_close_container(m);
1903 message_abort_container(m);
1907 int sd_bus_message_append_array(sd_bus_message *m, char type, const void *ptr, size_t size) {
1911 if (!ptr && size > 0)
1914 r = sd_bus_message_append_array_space(m, type, size, &p);
1919 memcpy(p, ptr, size);
1924 static int buffer_peek(const void *p, uint32_t sz, size_t *rindex, size_t align, size_t nbytes, void **r) {
1930 start = ALIGN_TO((size_t) *rindex, align);
1936 /* Verify that padding is 0 */
1937 for (k = *rindex; k < start; k++)
1938 if (((const uint8_t*) p)[k] != 0)
1942 *r = (uint8_t*) p + start;
1949 static bool message_end_of_array(sd_bus_message *m, size_t index) {
1950 struct bus_container *c;
1954 c = message_get_container(m);
1958 return index >= c->begin + BUS_MESSAGE_BSWAP32(m, *c->array_size);
1961 static int message_peek_body(sd_bus_message *m, size_t *rindex, size_t align, size_t nbytes, void **ret) {
1966 if (message_end_of_array(m, *rindex))
1969 return buffer_peek(m->body, BUS_MESSAGE_BODY_SIZE(m), rindex, align, nbytes, ret);
1972 static bool validate_nul(const char *s, size_t l) {
1974 /* Check for NUL chars in the string */
1975 if (memchr(s, 0, l))
1978 /* Check for NUL termination */
1985 static bool validate_string(const char *s, size_t l) {
1987 if (!validate_nul(s, l))
1990 /* Check if valid UTF8 */
1991 if (!utf8_is_valid(s))
1997 static bool validate_signature(const char *s, size_t l) {
1999 if (!validate_nul(s, l))
2002 /* Check if valid signature */
2003 if (!signature_is_valid(s, true))
2009 static bool validate_object_path(const char *s, size_t l) {
2011 if (!validate_nul(s, l))
2014 if (!object_path_is_valid(s))
2020 int sd_bus_message_read_basic(sd_bus_message *m, char type, void *p) {
2021 struct bus_container *c;
2029 if (!bus_type_is_basic(type))
2034 c = message_get_container(m);
2036 if (!c->signature || c->signature[c->index] == 0)
2039 if (c->signature[c->index] != type)
2044 case SD_BUS_TYPE_STRING:
2045 case SD_BUS_TYPE_OBJECT_PATH: {
2050 r = message_peek_body(m, &rindex, 4, 4, &q);
2054 l = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2055 r = message_peek_body(m, &rindex, 1, l+1, &q);
2061 if (type == SD_BUS_TYPE_OBJECT_PATH) {
2062 if (!validate_object_path(q, l))
2065 if (!validate_string(q, l))
2070 *(const char**) p = q;
2074 case SD_BUS_TYPE_SIGNATURE: {
2079 r = message_peek_body(m, &rindex, 1, 1, &q);
2084 r = message_peek_body(m, &rindex, 1, l+1, &q);
2090 if (!validate_signature(q, l))
2094 *(const char**) p = q;
2102 align = bus_type_get_alignment(type);
2103 sz = bus_type_get_size(type);
2104 assert(align > 0 && sz > 0);
2107 r = message_peek_body(m, &rindex, align, sz, &q);
2113 case SD_BUS_TYPE_BYTE:
2114 *(uint8_t*) p = *(uint8_t*) q;
2117 case SD_BUS_TYPE_BOOLEAN:
2118 *(int*) p = !!*(uint32_t*) q;
2121 case SD_BUS_TYPE_INT16:
2122 case SD_BUS_TYPE_UINT16:
2123 *(uint16_t*) p = BUS_MESSAGE_BSWAP16(m, *(uint16_t*) q);
2126 case SD_BUS_TYPE_INT32:
2127 case SD_BUS_TYPE_UINT32:
2128 *(uint32_t*) p = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2131 case SD_BUS_TYPE_INT64:
2132 case SD_BUS_TYPE_UINT64:
2133 case SD_BUS_TYPE_DOUBLE:
2134 *(uint64_t*) p = BUS_MESSAGE_BSWAP64(m, *(uint64_t*) q);
2137 case SD_BUS_TYPE_UNIX_FD: {
2140 j = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2144 *(int*) p = m->fds[j];
2149 assert_not_reached("Unknown basic type...");
2158 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2164 static int bus_message_enter_array(
2166 struct bus_container *c,
2167 const char *contents,
2168 uint32_t **array_size) {
2179 if (!signature_is_single(contents))
2182 alignment = bus_type_get_alignment(contents[0]);
2186 if (!c->signature || c->signature[c->index] == 0)
2189 if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
2192 if (!startswith(c->signature + c->index + 1, contents))
2196 r = message_peek_body(m, &rindex, 4, 4, &q);
2200 if (BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q) > BUS_ARRAY_MAX_SIZE)
2203 r = message_peek_body(m, &rindex, alignment, 0, NULL);
2209 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2210 c->index += 1 + strlen(contents);
2214 *array_size = (uint32_t*) q;
2219 static int bus_message_enter_variant(
2221 struct bus_container *c,
2222 const char *contents) {
2233 if (!signature_is_single(contents))
2236 if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
2239 if (!c->signature || c->signature[c->index] == 0)
2242 if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
2246 r = message_peek_body(m, &rindex, 1, 1, &q);
2251 r = message_peek_body(m, &rindex, 1, l+1, &q);
2257 if (!validate_signature(q, l))
2260 if (!streq(q, contents))
2263 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2271 static int bus_message_enter_struct(
2273 struct bus_container *c,
2274 const char *contents) {
2283 if (!signature_is_valid(contents, false))
2286 if (!c->signature || c->signature[c->index] == 0)
2289 l = strlen(contents);
2291 if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
2292 !startswith(c->signature + c->index + 1, contents) ||
2293 c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
2296 r = message_peek_body(m, &m->rindex, 8, 0, NULL);
2300 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2301 c->index += 1 + l + 1;
2306 static int bus_message_enter_dict_entry(
2308 struct bus_container *c,
2309 const char *contents) {
2318 if (!signature_is_pair(contents))
2321 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2324 if (!c->signature || c->signature[c->index] == 0)
2327 l = strlen(contents);
2329 if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
2330 !startswith(c->signature + c->index + 1, contents) ||
2331 c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
2334 r = message_peek_body(m, &m->rindex, 8, 0, NULL);
2338 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2339 c->index += 1 + l + 1;
2344 int sd_bus_message_enter_container(sd_bus_message *m, char type, const char *contents) {
2345 struct bus_container *c, *w;
2346 uint32_t *array_size = NULL;
2359 * We enforce a global limit on container depth, that is much
2360 * higher than the 32 structs and 32 arrays the specification
2361 * mandates. This is simpler to implement for us, and we need
2362 * this only to ensure our container array doesn't grow
2363 * without bounds. We are happy to return any data from a
2364 * message as long as the data itself is valid, even if the
2365 * overall message might be not.
2367 * Note that the message signature is validated when
2368 * parsing the headers, and that validation does check the
2371 * Note that the specification defines no limits on the depth
2372 * of stacked variants, but we do.
2374 if (m->n_containers >= BUS_CONTAINER_DEPTH)
2377 w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
2382 c = message_get_container(m);
2384 if (!c->signature || c->signature[c->index] == 0)
2387 signature = strdup(contents);
2391 c->saved_index = c->index;
2394 if (type == SD_BUS_TYPE_ARRAY)
2395 r = bus_message_enter_array(m, c, contents, &array_size);
2396 else if (type == SD_BUS_TYPE_VARIANT)
2397 r = bus_message_enter_variant(m, c, contents);
2398 else if (type == SD_BUS_TYPE_STRUCT)
2399 r = bus_message_enter_struct(m, c, contents);
2400 else if (type == SD_BUS_TYPE_DICT_ENTRY)
2401 r = bus_message_enter_dict_entry(m, c, contents);
2410 /* OK, let's fill it in */
2411 w += m->n_containers++;
2412 w->enclosing = type;
2413 w->signature = signature;
2415 w->array_size = array_size;
2417 w->begin = m->rindex;
2422 int sd_bus_message_exit_container(sd_bus_message *m) {
2423 struct bus_container *c;
2429 if (m->n_containers <= 0)
2432 c = message_get_container(m);
2433 if (c->enclosing == SD_BUS_TYPE_ARRAY) {
2436 l = BUS_MESSAGE_BSWAP32(m, *c->array_size);
2437 if (c->begin + l != m->rindex)
2441 if (c->signature && c->signature[c->index] != 0)
2451 static void message_quit_container(sd_bus_message *m) {
2452 struct bus_container *c;
2456 assert(m->n_containers > 0);
2458 c = message_get_container(m);
2461 assert(m->rindex >= c->before);
2462 m->rindex = c->before;
2464 /* Free container */
2468 /* Correct index of new top-level container */
2469 c = message_get_container(m);
2470 c->index = c->saved_index;
2473 int sd_bus_message_peek_type(sd_bus_message *m, char *type, const char **contents) {
2474 struct bus_container *c;
2482 c = message_get_container(m);
2484 if (!c->signature || c->signature[c->index] == 0)
2487 if (message_end_of_array(m, m->rindex))
2490 if (bus_type_is_basic(c->signature[c->index])) {
2494 *type = c->signature[c->index];
2498 if (c->signature[c->index] == SD_BUS_TYPE_ARRAY) {
2504 r = signature_element_length(c->signature+c->index+1, &l);
2510 sig = strndup(c->signature + c->index + 1, l);
2514 free(m->peeked_signature);
2515 m->peeked_signature = sig;
2521 *type = SD_BUS_TYPE_ARRAY;
2526 if (c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ||
2527 c->signature[c->index] == SD_BUS_TYPE_DICT_ENTRY_BEGIN) {
2533 r = signature_element_length(c->signature+c->index, &l);
2538 sig = strndup(c->signature + c->index + 1, l - 2);
2542 free(m->peeked_signature);
2543 m->peeked_signature = sig;
2549 *type = c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY;
2554 if (c->signature[c->index] == SD_BUS_TYPE_VARIANT) {
2560 r = message_peek_body(m, &rindex, 1, 1, &q);
2567 r = message_peek_body(m, &rindex, 1, l+1, &q);
2573 if (!validate_signature(q, l))
2580 *type = SD_BUS_TYPE_VARIANT;
2589 *type = c->enclosing;
2595 int sd_bus_message_rewind(sd_bus_message *m, int complete) {
2596 struct bus_container *c;
2604 reset_containers(m);
2606 m->root_container.index = 0;
2608 c = message_get_container(m);
2610 c = message_get_container(m);
2613 m->rindex = c->begin;
2616 return !isempty(c->signature);
2618 static int message_read_ap(
2623 unsigned n_array, n_struct;
2624 TypeStack stack[BUS_CONTAINER_DEPTH];
2625 unsigned stack_ptr = 0;
2633 /* Ideally, we'd just call ourselves recursively on every
2634 * complex type. However, the state of a va_list that is
2635 * passed to a function is undefined after that function
2636 * returns. This means we need to docode the va_list linearly
2637 * in a single stackframe. We hence implement our own
2638 * home-grown stack in an array. */
2640 n_array = (unsigned) -1;
2641 n_struct = strlen(types);
2646 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
2647 r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
2653 r = sd_bus_message_exit_container(m);
2661 if (n_array != (unsigned) -1)
2670 case SD_BUS_TYPE_BYTE:
2671 case SD_BUS_TYPE_BOOLEAN:
2672 case SD_BUS_TYPE_INT16:
2673 case SD_BUS_TYPE_UINT16:
2674 case SD_BUS_TYPE_INT32:
2675 case SD_BUS_TYPE_UINT32:
2676 case SD_BUS_TYPE_INT64:
2677 case SD_BUS_TYPE_UINT64:
2678 case SD_BUS_TYPE_DOUBLE:
2679 case SD_BUS_TYPE_STRING:
2680 case SD_BUS_TYPE_OBJECT_PATH:
2681 case SD_BUS_TYPE_SIGNATURE:
2682 case SD_BUS_TYPE_UNIX_FD: {
2685 p = va_arg(ap, void*);
2686 r = sd_bus_message_read_basic(m, *t, p);
2695 case SD_BUS_TYPE_ARRAY: {
2698 r = signature_element_length(t + 1, &k);
2704 memcpy(s, t + 1, k);
2707 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, s);
2714 if (n_array == (unsigned) -1) {
2719 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2725 n_array = va_arg(ap, unsigned);
2730 case SD_BUS_TYPE_VARIANT: {
2733 s = va_arg(ap, const char *);
2737 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, s);
2743 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2748 n_struct = strlen(s);
2749 n_array = (unsigned) -1;
2754 case SD_BUS_TYPE_STRUCT_BEGIN:
2755 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
2758 r = signature_element_length(t, &k);
2764 memcpy(s, t + 1, k - 2);
2767 r = sd_bus_message_enter_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
2774 if (n_array == (unsigned) -1) {
2779 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2785 n_array = (unsigned) -1;
2798 int sd_bus_message_read(sd_bus_message *m, const char *types, ...) {
2809 va_start(ap, types);
2810 r = message_read_ap(m, types, ap);
2816 int sd_bus_message_read_array(sd_bus_message *m, char type, const void **ptr, size_t *size) {
2817 struct bus_container *c;
2827 if (!bus_type_is_trivial(type))
2833 if (BUS_MESSAGE_NEED_BSWAP(m))
2836 align = bus_type_get_alignment(type);
2840 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
2844 c = message_get_container(m);
2845 sz = BUS_MESSAGE_BSWAP32(m, *c->array_size);
2847 r = message_peek_body(m, &m->rindex, align, sz, &p);
2855 r = sd_bus_message_exit_container(m);
2859 *ptr = (const void*) p;
2865 message_quit_container(m);
2869 static int message_peek_fields(
2880 return buffer_peek(m->fields, BUS_MESSAGE_FIELDS_SIZE(m), rindex, align, nbytes, ret);
2883 static int message_peek_field_uint32(
2894 r = message_peek_fields(m, ri, 4, 4, &q);
2899 *ret = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2904 static int message_peek_field_string(
2906 bool (*validate)(const char *p),
2917 r = message_peek_field_uint32(m, ri, &l);
2921 r = message_peek_fields(m, ri, 1, l+1, &q);
2926 if (!validate_nul(q, l))
2932 if (!validate_string(q, l))
2942 static int message_peek_field_signature(
2954 r = message_peek_fields(m, ri, 1, 1, &q);
2959 r = message_peek_fields(m, ri, 1, l+1, &q);
2963 if (!validate_signature(q, l))
2972 static int message_skip_fields(
2975 uint32_t array_size,
2976 const char **signature) {
2978 size_t original_index;
2985 original_index = *ri;
2991 if (array_size != (uint32_t) -1 &&
2992 array_size <= *ri - original_index)
2999 if (t == SD_BUS_TYPE_STRING) {
3001 r = message_peek_field_string(m, NULL, ri, NULL);
3007 } else if (t == SD_BUS_TYPE_OBJECT_PATH) {
3009 r = message_peek_field_string(m, object_path_is_valid, ri, NULL);
3015 } else if (t == SD_BUS_TYPE_SIGNATURE) {
3017 r = message_peek_field_signature(m, ri, NULL);
3023 } else if (bus_type_is_basic(t)) {
3026 align = bus_type_get_alignment(t);
3027 k = bus_type_get_size(t);
3028 assert(align > 0 && k > 0);
3030 r = message_peek_fields(m, ri, align, k, NULL);
3036 } else if (t == SD_BUS_TYPE_ARRAY) {
3038 r = signature_element_length(*signature+1, &l);
3048 strncpy(sig, *signature + 1, l-1);
3051 alignment = bus_type_get_alignment(sig[0]);
3055 r = message_peek_field_uint32(m, ri, &nas);
3058 if (nas > BUS_ARRAY_MAX_SIZE)
3061 r = message_peek_fields(m, ri, alignment, 0, NULL);
3065 r = message_skip_fields(m, ri, nas, (const char**) &s);
3070 (*signature) += 1 + l;
3072 } else if (t == SD_BUS_TYPE_VARIANT) {
3075 r = message_peek_field_signature(m, ri, &s);
3079 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
3085 } else if (t == SD_BUS_TYPE_STRUCT ||
3086 t == SD_BUS_TYPE_DICT_ENTRY) {
3088 r = signature_element_length(*signature, &l);
3095 strncpy(sig, *signature + 1, l-1);
3098 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
3109 int bus_message_parse_fields(sd_bus_message *m) {
3112 uint32_t unix_fds = 0;
3116 for (ri = 0; ri < BUS_MESSAGE_FIELDS_SIZE(m); ) {
3117 const char *signature;
3120 r = message_peek_fields(m, &ri, 8, 1, (void**) &header);
3124 r = message_peek_field_signature(m, &ri, &signature);
3129 case _SD_BUS_MESSAGE_HEADER_INVALID:
3132 case SD_BUS_MESSAGE_HEADER_PATH:
3137 if (!streq(signature, "o"))
3140 r = message_peek_field_string(m, object_path_is_valid, &ri, &m->path);
3143 case SD_BUS_MESSAGE_HEADER_INTERFACE:
3148 if (!streq(signature, "s"))
3151 r = message_peek_field_string(m, interface_name_is_valid, &ri, &m->interface);
3154 case SD_BUS_MESSAGE_HEADER_MEMBER:
3159 if (!streq(signature, "s"))
3162 r = message_peek_field_string(m, member_name_is_valid, &ri, &m->member);
3165 case SD_BUS_MESSAGE_HEADER_ERROR_NAME:
3170 if (!streq(signature, "s"))
3173 r = message_peek_field_string(m, error_name_is_valid, &ri, &m->error.name);
3176 case SD_BUS_MESSAGE_HEADER_DESTINATION:
3181 if (!streq(signature, "s"))
3184 r = message_peek_field_string(m, service_name_is_valid, &ri, &m->destination);
3187 case SD_BUS_MESSAGE_HEADER_SENDER:
3192 if (!streq(signature, "s"))
3195 r = message_peek_field_string(m, service_name_is_valid, &ri, &m->sender);
3199 case SD_BUS_MESSAGE_HEADER_SIGNATURE: {
3203 if (m->root_container.signature)
3206 if (!streq(signature, "g"))
3209 r = message_peek_field_signature(m, &ri, &s);
3217 free(m->root_container.signature);
3218 m->root_container.signature = c;
3222 case SD_BUS_MESSAGE_HEADER_REPLY_SERIAL:
3223 if (m->reply_serial != 0)
3226 if (!streq(signature, "u"))
3229 r = message_peek_field_uint32(m, &ri, &m->reply_serial);
3233 if (m->reply_serial == 0)
3238 case SD_BUS_MESSAGE_HEADER_UNIX_FDS:
3242 if (!streq(signature, "u"))
3245 r = message_peek_field_uint32(m, &ri, &unix_fds);
3255 r = message_skip_fields(m, &ri, (uint32_t) -1, (const char **) &signature);
3262 if (m->n_fds != unix_fds)
3265 if (isempty(m->root_container.signature) != (BUS_MESSAGE_BODY_SIZE(m) == 0))
3268 switch (m->header->type) {
3270 case SD_BUS_MESSAGE_TYPE_SIGNAL:
3271 if (!m->path || !m->interface || !m->member)
3275 case SD_BUS_MESSAGE_TYPE_METHOD_CALL:
3277 if (!m->path || !m->member)
3282 case SD_BUS_MESSAGE_TYPE_METHOD_RETURN:
3284 if (m->reply_serial == 0)
3288 case SD_BUS_MESSAGE_TYPE_METHOD_ERROR:
3290 if (m->reply_serial == 0 || !m->error.name)
3295 /* Try to read the error message, but if we can't it's a non-issue */
3296 if (m->header->type == SD_BUS_MESSAGE_TYPE_METHOD_ERROR)
3297 sd_bus_message_read(m, "s", &m->error.message);
3302 int bus_message_seal(sd_bus_message *m, uint64_t serial) {
3311 if (m->n_containers > 0)
3314 /* If there's a non-trivial signature set, then add it in here */
3315 if (!isempty(m->root_container.signature)) {
3316 r = message_append_field_signature(m, SD_BUS_MESSAGE_HEADER_SIGNATURE, m->root_container.signature, NULL);
3322 r = message_append_field_uint32(m, SD_BUS_MESSAGE_HEADER_UNIX_FDS, m->n_fds);
3327 l = BUS_MESSAGE_FIELDS_SIZE(m);
3331 /* Add padding at the end, since we know the body
3332 * needs to start at an 8 byte alignment. */
3335 p = message_extend_fields(m, 1, a);
3340 m->header->fields_size -= a;
3343 m->header->serial = serial;
3349 int sd_bus_message_set_destination(sd_bus_message *m, const char *destination) {
3359 return message_append_field_string(m, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &m->destination);
3362 int bus_message_dump(sd_bus_message *m) {
3363 const char *u = NULL, *uu = NULL, *s = NULL;
3364 char **cmdline = NULL;
3367 uid_t owner, audit_loginuid;
3368 uint32_t audit_sessionid;
3372 printf("Message %p\n"
3379 "\tfields_size=%u\n"
3384 "\tdestination=%s\n"
3387 "\treply_serial=%u\n"
3389 "\terror.message=%s\n"
3397 BUS_MESSAGE_SERIAL(m),
3398 BUS_MESSAGE_FIELDS_SIZE(m),
3399 BUS_MESSAGE_BODY_SIZE(m),
3401 strna(m->interface),
3403 strna(m->destination),
3405 strna(m->root_container.signature),
3407 strna(m->error.name),
3408 strna(m->error.message),
3412 printf("\tpid=%lu\n", (unsigned long) m->pid);
3414 printf("\ttid=%lu\n", (unsigned long) m->tid);
3416 printf("\tuid=%lu\n", (unsigned long) m->uid);
3418 printf("\tgid=%lu\n", (unsigned long) m->gid);
3419 if (m->pid_starttime != 0)
3420 printf("\tpid_starttime=%llu\n", (unsigned long long) m->pid_starttime);
3421 if (m->monotonic != 0)
3422 printf("\tmonotonic=%llu\n", (unsigned long long) m->monotonic);
3423 if (m->realtime != 0)
3424 printf("\trealtime=%llu\n", (unsigned long long) m->realtime);
3426 printf("\texe=[%s]\n", m->exe);
3428 printf("\tcomm=[%s]\n", m->comm);
3430 printf("\ttid_comm=[%s]\n", m->tid_comm);
3432 printf("\tlabel=[%s]\n", m->label);
3434 printf("\tcgroup=[%s]\n", m->cgroup);
3436 sd_bus_message_get_unit(m, &u);
3438 printf("\tunit=[%s]\n", u);
3439 sd_bus_message_get_user_unit(m, &uu);
3441 printf("\tuser_unit=[%s]\n", uu);
3442 sd_bus_message_get_session(m, &s);
3444 printf("\tsession=[%s]\n", s);
3445 if (sd_bus_message_get_owner_uid(m, &owner) >= 0)
3446 printf("\towner_uid=%lu\n", (unsigned long) owner);
3447 if (sd_bus_message_get_audit_loginuid(m, &audit_loginuid) >= 0)
3448 printf("\taudit_loginuid=%lu\n", (unsigned long) audit_loginuid);
3449 if (sd_bus_message_get_audit_sessionid(m, &audit_sessionid) >= 0)
3450 printf("\taudit_sessionid=%lu\n", (unsigned long) audit_sessionid);
3452 printf("\tCAP_KILL=%i\n", sd_bus_message_has_effective_cap(m, 5));
3454 if (sd_bus_message_get_cmdline(m, &cmdline) >= 0) {
3457 fputs("\tcmdline=[", stdout);
3458 STRV_FOREACH(c, cmdline) {
3465 fputs("]\n", stdout);
3468 r = sd_bus_message_rewind(m, true);
3470 log_error("Failed to rewind: %s", strerror(-r));
3474 printf("BEGIN_MESSAGE \"%s\" {\n", strempty(m->root_container.signature));
3477 _cleanup_free_ char *prefix = NULL;
3478 const char *contents = NULL;
3493 r = sd_bus_message_peek_type(m, &type, &contents);
3495 log_error("Failed to peek type: %s", strerror(-r));
3502 r = sd_bus_message_exit_container(m);
3504 log_error("Failed to exit container: %s", strerror(-r));
3510 prefix = strrep("\t", level);
3514 if (type == SD_BUS_TYPE_ARRAY)
3515 printf("%s} END_ARRAY \n", prefix);
3516 else if (type == SD_BUS_TYPE_VARIANT)
3517 printf("%s} END_VARIANT\n", prefix);
3518 else if (type == SD_BUS_TYPE_STRUCT)
3519 printf("%s} END_STRUCT\n", prefix);
3520 else if (type == SD_BUS_TYPE_DICT_ENTRY)
3521 printf("%s} END_DICT_ENTRY\n", prefix);
3526 prefix = strrep("\t", level);
3530 if (bus_type_is_container(type) > 0) {
3531 r = sd_bus_message_enter_container(m, type, contents);
3533 log_error("Failed to enter container: %s", strerror(-r));
3537 if (type == SD_BUS_TYPE_ARRAY)
3538 printf("%sBEGIN_ARRAY \"%s\" {\n", prefix, contents);
3539 else if (type == SD_BUS_TYPE_VARIANT)
3540 printf("%sBEGIN_VARIANT \"%s\" {\n", prefix, contents);
3541 else if (type == SD_BUS_TYPE_STRUCT)
3542 printf("%sBEGIN_STRUCT \"%s\" {\n", prefix, contents);
3543 else if (type == SD_BUS_TYPE_DICT_ENTRY)
3544 printf("%sBEGIN_DICT_ENTRY \"%s\" {\n", prefix, contents);
3551 r = sd_bus_message_read_basic(m, type, &basic);
3553 log_error("Failed to get basic: %s", strerror(-r));
3559 case SD_BUS_TYPE_BYTE:
3560 printf("%sBYTE: %u\n", prefix, basic.u8);
3563 case SD_BUS_TYPE_BOOLEAN:
3564 printf("%sBOOLEAN: %s\n", prefix, yes_no(basic.i));
3567 case SD_BUS_TYPE_INT16:
3568 printf("%sINT16: %i\n", prefix, basic.s16);
3571 case SD_BUS_TYPE_UINT16:
3572 printf("%sUINT16: %u\n", prefix, basic.u16);
3575 case SD_BUS_TYPE_INT32:
3576 printf("%sINT32: %i\n", prefix, basic.s32);
3579 case SD_BUS_TYPE_UINT32:
3580 printf("%sUINT32: %u\n", prefix, basic.u32);
3583 case SD_BUS_TYPE_INT64:
3584 printf("%sINT64: %lli\n", prefix, (long long) basic.s64);
3587 case SD_BUS_TYPE_UINT64:
3588 printf("%sUINT64: %llu\n", prefix, (unsigned long long) basic.u64);
3591 case SD_BUS_TYPE_DOUBLE:
3592 printf("%sDOUBLE: %g\n", prefix, basic.d64);
3595 case SD_BUS_TYPE_STRING:
3596 printf("%sSTRING: \"%s\"\n", prefix, basic.string);
3599 case SD_BUS_TYPE_OBJECT_PATH:
3600 printf("%sOBJECT_PATH: \"%s\"\n", prefix, basic.string);
3603 case SD_BUS_TYPE_SIGNATURE:
3604 printf("%sSIGNATURE: \"%s\"\n", prefix, basic.string);
3607 case SD_BUS_TYPE_UNIX_FD:
3608 printf("%sUNIX_FD: %i\n", prefix, basic.i);
3612 assert_not_reached("Unknown basic type.");
3616 printf("} END_MESSAGE\n");
3620 int bus_message_get_blob(sd_bus_message *m, void **buffer, size_t *sz) {
3628 total = BUS_MESSAGE_SIZE(m);
3634 e = mempcpy(p, m->header, sizeof(*m->header));
3637 e = mempcpy(e, m->fields, m->header->fields_size);
3639 if (m->header->fields_size % 8 != 0)
3640 e = mempset(e, 0, 8 - (m->header->fields_size % 8));
3644 e = mempcpy(e, m->body, m->header->body_size);
3646 assert(total == (size_t) ((uint8_t*) e - (uint8_t*) p));
3654 int bus_message_read_strv_extend(sd_bus_message *m, char ***l) {
3660 r = sd_bus_message_enter_container(m, 'a', "s");
3667 r = sd_bus_message_read_basic(m, 's', &s);
3673 r = strv_extend(l, s);
3678 r = sd_bus_message_exit_container(m);
3685 const char* bus_message_get_arg(sd_bus_message *m, unsigned i) {
3687 const char *t = NULL;
3692 r = sd_bus_message_rewind(m, true);
3696 for (j = 0; j <= i; j++) {
3699 r = sd_bus_message_peek_type(m, &type, NULL);
3703 if (type != SD_BUS_TYPE_STRING &&
3704 type != SD_BUS_TYPE_OBJECT_PATH &&
3705 type != SD_BUS_TYPE_SIGNATURE)
3708 r = sd_bus_message_read_basic(m, type, &t);
3716 int bus_header_size(struct bus_header *h, size_t *sum) {
3722 if (h->endian == SD_BUS_NATIVE_ENDIAN) {
3723 fs = h->fields_size;
3725 } else if (h->endian == SD_BUS_REVERSE_ENDIAN) {
3726 fs = bswap_32(h->fields_size);
3727 bs = bswap_32(h->body_size);
3731 *sum = sizeof(struct bus_header) + ALIGN8(fs) + bs;