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"
31 #include "bus-message.h"
32 #include "bus-internal.h"
34 #include "bus-signature.h"
36 static int message_append_basic(sd_bus_message *m, char type, const void *p, const void **stored);
38 static void reset_containers(sd_bus_message *m) {
43 for (i = 0; i < m->n_containers; i++)
44 free(m->containers[i].signature);
50 m->root_container.index = 0;
53 static void message_free(sd_bus_message *m) {
69 close_many(m->fds, m->n_fds);
74 free(m->root_container.signature);
76 free(m->peeked_signature);
80 static void* buffer_extend(void **p, uint32_t *sz, size_t align, size_t extend) {
88 start = ALIGN_TO((size_t) *sz, align);
92 return (uint8_t*) *p + start;
94 if (n > (size_t) ((uint32_t) -1))
101 /* Zero out padding */
103 memset((uint8_t*) k + *sz, 0, start - *sz);
108 return (uint8_t*) k + start;
111 static void *message_extend_fields(sd_bus_message *m, size_t align, size_t sz) {
117 p = buffer_extend(&m->fields, &m->header->fields_size, align, sz);
121 if (o != m->fields) {
122 /* Adjust quick access pointers */
125 m->path = (const char*) m->fields + (m->path - (const char*) o);
127 m->interface = (const char*) m->fields + (m->interface - (const char*) o);
129 m->member = (const char*) m->fields + (m->member - (const char*) o);
131 m->destination = (const char*) m->fields + (m->destination - (const char*) o);
133 m->sender = (const char*) m->fields + (m->sender - (const char*) o);
135 m->error.name = (const char*) m->fields + (m->error.name - (const char*) o);
138 m->free_fields = true;
143 static int message_append_field_string(
156 if (l > (size_t) (uint32_t) -1)
159 /* field id byte + signature length + signature 's' + NUL + string length + string + NUL */
160 p = message_extend_fields(m, 8, 4 + 4 + l + 1);
169 ((uint32_t*) p)[1] = l;
170 memcpy(p + 8, s, l + 1);
173 *ret = (const char*) p + 8;
178 static int message_append_field_signature(
193 /* field id byte + signature length + signature 'g' + NUL + string length + string + NUL */
194 p = message_extend_fields(m, 8, 4 + 1 + l + 1);
200 p[2] = SD_BUS_TYPE_SIGNATURE;
203 memcpy(p + 5, s, l + 1);
206 *ret = (const char*) p + 5;
211 static int message_append_field_uint32(sd_bus_message *m, uint8_t h, uint32_t x) {
216 /* field id byte + signature length + signature 'u' + NUL + value */
217 p = message_extend_fields(m, 8, 4 + 4);
223 p[2] = SD_BUS_TYPE_UINT32;
226 ((uint32_t*) p)[1] = x;
231 int bus_message_from_header(
236 const struct ucred *ucred,
239 sd_bus_message **ret) {
242 struct bus_header *h;
245 assert(buffer || length <= 0);
246 assert(fds || n_fds <= 0);
249 if (length < sizeof(struct bus_header))
259 if (h->type == _SD_BUS_MESSAGE_TYPE_INVALID)
262 if (h->endian != SD_BUS_LITTLE_ENDIAN &&
263 h->endian != SD_BUS_BIG_ENDIAN)
266 a = ALIGN(sizeof(sd_bus_message)) + ALIGN(extra);
269 label_sz = strlen(label);
287 m->uid_valid = m->gid_valid = true;
291 m->label = (char*) m + ALIGN(sizeof(sd_bus_message)) + ALIGN(extra);
292 memcpy(m->label, label, label_sz + 1);
299 int bus_message_from_malloc(
304 const struct ucred *ucred,
306 sd_bus_message **ret) {
311 r = bus_message_from_header(buffer, length, fds, n_fds, ucred, label, 0, &m);
315 if (length != BUS_MESSAGE_SIZE(m)) {
320 m->fields = (uint8_t*) buffer + sizeof(struct bus_header);
321 m->body = (uint8_t*) buffer + sizeof(struct bus_header) + ALIGN8(BUS_MESSAGE_FIELDS_SIZE(m));
324 m->iovec[0].iov_base = buffer;
325 m->iovec[0].iov_len = length;
327 r = bus_message_parse_fields(m);
331 /* We take possession of the memory and fds now */
332 m->free_header = true;
343 static sd_bus_message *message_new(sd_bus *bus, uint8_t type) {
346 m = malloc0(ALIGN(sizeof(sd_bus_message)) + sizeof(struct bus_header));
351 m->header = (struct bus_header*) ((uint8_t*) m + ALIGN(sizeof(struct sd_bus_message)));
352 m->header->endian = SD_BUS_NATIVE_ENDIAN;
353 m->header->type = type;
354 m->header->version = bus ? bus->message_version : 1;
355 m->allow_fds = !bus || bus->can_fds || (bus->state != BUS_HELLO && bus->state != BUS_RUNNING);
360 int sd_bus_message_new_signal(
363 const char *interface,
365 sd_bus_message **m) {
378 if (bus && bus->state == BUS_UNSET)
381 t = message_new(bus, SD_BUS_MESSAGE_TYPE_SIGNAL);
385 t->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
387 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_PATH, SD_BUS_TYPE_OBJECT_PATH, path, &t->path);
390 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_INTERFACE, SD_BUS_TYPE_STRING, interface, &t->interface);
393 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_MEMBER, SD_BUS_TYPE_STRING, member, &t->member);
401 sd_bus_message_unref(t);
405 int sd_bus_message_new_method_call(
407 const char *destination,
409 const char *interface,
411 sd_bus_message **m) {
422 if (bus && bus->state == BUS_UNSET)
425 t = message_new(bus, SD_BUS_MESSAGE_TYPE_METHOD_CALL);
429 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_PATH, SD_BUS_TYPE_OBJECT_PATH, path, &t->path);
432 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_MEMBER, SD_BUS_TYPE_STRING, member, &t->member);
437 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_INTERFACE, SD_BUS_TYPE_STRING, interface, &t->interface);
443 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &t->destination);
456 static int message_new_reply(
458 sd_bus_message *call,
460 sd_bus_message **m) {
469 if (call->header->type != SD_BUS_MESSAGE_TYPE_METHOD_CALL)
473 if (bus && bus->state == BUS_UNSET)
476 t = message_new(bus, type);
480 t->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
481 t->reply_serial = BUS_MESSAGE_SERIAL(call);
483 r = message_append_field_uint32(t, SD_BUS_MESSAGE_HEADER_REPLY_SERIAL, t->reply_serial);
488 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, call->sender, &t->sender);
493 t->dont_send = !!(call->header->flags & SD_BUS_MESSAGE_NO_REPLY_EXPECTED);
503 int sd_bus_message_new_method_return(
505 sd_bus_message *call,
506 sd_bus_message **m) {
508 return message_new_reply(bus, call, SD_BUS_MESSAGE_TYPE_METHOD_RETURN, m);
511 int sd_bus_message_new_method_error(
513 sd_bus_message *call,
514 const sd_bus_error *e,
515 sd_bus_message **m) {
520 if (!sd_bus_error_is_set(e))
525 r = message_new_reply(bus, call, SD_BUS_MESSAGE_TYPE_METHOD_ERROR, &t);
529 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_ERROR_NAME, SD_BUS_TYPE_STRING, e->name, &t->error.name);
534 r = message_append_basic(t, SD_BUS_TYPE_STRING, e->message, (const void**) &t->error.message);
547 sd_bus_message* sd_bus_message_ref(sd_bus_message *m) {
551 assert(m->n_ref > 0);
557 sd_bus_message* sd_bus_message_unref(sd_bus_message *m) {
561 assert(m->n_ref > 0);
570 int sd_bus_message_get_type(sd_bus_message *m, uint8_t *type) {
576 *type = m->header->type;
580 int sd_bus_message_get_serial(sd_bus_message *m, uint64_t *serial) {
585 if (m->header->serial == 0)
588 *serial = BUS_MESSAGE_SERIAL(m);
592 int sd_bus_message_get_reply_serial(sd_bus_message *m, uint64_t *serial) {
597 if (m->reply_serial == 0)
600 *serial = m->reply_serial;
604 int sd_bus_message_get_no_reply(sd_bus_message *m) {
608 return m->header->type == SD_BUS_MESSAGE_TYPE_METHOD_CALL ? !!(m->header->flags & SD_BUS_MESSAGE_NO_REPLY_EXPECTED) : 0;
611 const char *sd_bus_message_get_path(sd_bus_message *m) {
618 const char *sd_bus_message_get_interface(sd_bus_message *m) {
625 const char *sd_bus_message_get_member(sd_bus_message *m) {
631 const char *sd_bus_message_get_destination(sd_bus_message *m) {
635 return m->destination;
638 const char *sd_bus_message_get_sender(sd_bus_message *m) {
645 const sd_bus_error *sd_bus_message_get_error(sd_bus_message *m) {
649 if (!sd_bus_error_is_set(&m->error))
655 int sd_bus_message_get_uid(sd_bus_message *m, uid_t *uid) {
665 int sd_bus_message_get_gid(sd_bus_message *m, gid_t *gid) {
675 int sd_bus_message_get_pid(sd_bus_message *m, pid_t *pid) {
685 int sd_bus_message_get_tid(sd_bus_message *m, pid_t *tid) {
695 int sd_bus_message_get_pid_starttime(sd_bus_message *m, uint64_t *usec) {
698 if (m->pid_starttime <= 0)
701 *usec = m->pid_starttime;
705 const char *sd_bus_message_get_selinux_context(sd_bus_message *m) {
712 int sd_bus_message_get_monotonic_timestamp(sd_bus_message *m, uint64_t *usec) {
716 if (m->monotonic <= 0)
719 *usec = m->monotonic;
723 int sd_bus_message_get_realtime_timestamp(sd_bus_message *m, uint64_t *usec) {
727 if (m->realtime <= 0)
734 const char *sd_bus_message_get_comm(sd_bus_message *m) {
741 const char *sd_bus_message_get_tid_comm(sd_bus_message *m) {
748 const char *sd_bus_message_get_exe(sd_bus_message *m) {
755 int sd_bus_message_is_signal(sd_bus_message *m, const char *interface, const char *member) {
759 if (m->header->type != SD_BUS_MESSAGE_TYPE_SIGNAL)
762 if (interface && (!m->interface || !streq(m->interface, interface)))
765 if (member && (!m->member || !streq(m->member, member)))
771 int sd_bus_message_is_method_call(sd_bus_message *m, const char *interface, const char *member) {
775 if (m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_CALL)
778 if (interface && (!m->interface || !streq(m->interface, interface)))
781 if (member && (!m->member || !streq(m->member, member)))
787 int sd_bus_message_is_method_error(sd_bus_message *m, const char *name) {
791 if (m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_ERROR)
794 if (name && (!m->error.name || !streq(m->error.name, name)))
800 int sd_bus_message_set_no_reply(sd_bus_message *m, int b) {
805 if (m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_CALL)
809 m->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
811 m->header->flags &= ~SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
816 static struct bus_container *message_get_container(sd_bus_message *m) {
819 if (m->n_containers == 0)
820 return &m->root_container;
822 assert(m->containers);
823 return m->containers + m->n_containers - 1;
826 static void *message_extend_body(sd_bus_message *m, size_t align, size_t sz) {
829 struct bus_container *c;
835 added = m->header->body_size;
837 p = buffer_extend(&m->body, &m->header->body_size, align, sz);
841 added = m->header->body_size - added;
843 for (c = m->containers; c < m->containers + m->n_containers; c++)
845 c->array_size = (uint32_t*) ((uint8_t*) m->body + ((uint8_t*) c->array_size - (uint8_t*) o));
846 *c->array_size += added;
850 if (m->error.message)
851 m->error.message = (const char*) m->body + (m->error.message - (const char*) o);
859 int message_append_basic(sd_bus_message *m, char type, const void *p, const void **stored) {
860 struct bus_container *c;
875 if (!bus_type_is_basic(type))
878 c = message_get_container(m);
880 if (c->signature && c->signature[c->index]) {
881 /* Container signature is already set */
883 if (c->signature[c->index] != type)
886 /* Maybe we can append to the signature? But only if this is the top-level container*/
887 if (c->enclosing != 0)
890 e = strextend(&c->signature, CHAR_TO_STR(type), NULL);
897 case SD_BUS_TYPE_STRING:
898 case SD_BUS_TYPE_OBJECT_PATH:
901 sz = 4 + strlen(p) + 1;
904 case SD_BUS_TYPE_SIGNATURE:
907 sz = 1 + strlen(p) + 1;
910 case SD_BUS_TYPE_BOOLEAN:
913 assert_cc(sizeof(int) == sizeof(uint32_t));
919 case SD_BUS_TYPE_UNIX_FD: {
935 fd = fcntl(z, F_DUPFD_CLOEXEC, 3);
941 f = realloc(m->fds, sizeof(int) * (m->n_fds + 1));
955 align = bus_type_get_alignment(type);
956 sz = bus_type_get_size(type);
963 a = message_extend_body(m, align, sz);
969 if (type == SD_BUS_TYPE_STRING || type == SD_BUS_TYPE_OBJECT_PATH) {
970 *(uint32_t*) a = sz - 5;
971 memcpy((uint8_t*) a + 4, p, sz - 4);
974 *stored = (const uint8_t*) a + 4;
976 } else if (type == SD_BUS_TYPE_SIGNATURE) {
977 *(uint8_t*) a = sz - 1;
978 memcpy((uint8_t*) a + 1, p, sz - 1);
981 *stored = (const uint8_t*) a + 1;
982 } else if (type == SD_BUS_TYPE_UNIX_FD) {
983 *(uint32_t*) a = fdi;
997 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1003 /* Truncate extended signature again */
1005 c->signature[c->index] = 0;
1008 close_nointr_nofail(fd);
1013 int sd_bus_message_append_basic(sd_bus_message *m, char type, const void *p) {
1014 return message_append_basic(m, type, p, NULL);
1017 static int bus_message_open_array(
1019 struct bus_container *c,
1020 const char *contents,
1021 uint32_t **array_size) {
1034 if (!signature_is_single(contents))
1037 alignment = bus_type_get_alignment(contents[0]);
1041 if (c->signature && c->signature[c->index]) {
1043 /* Verify the existing signature */
1045 if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
1048 if (!startswith(c->signature + c->index + 1, contents))
1051 nindex = c->index + 1 + strlen(contents);
1053 if (c->enclosing != 0)
1056 /* Extend the existing signature */
1058 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_ARRAY), contents, NULL);
1062 nindex = e - c->signature;
1065 saved = m->header->body_size;
1066 a = message_extend_body(m, 4, 4);
1068 /* Truncate extended signature again */
1070 c->signature[c->index] = 0;
1076 if (!message_extend_body(m, alignment, 0)) {
1077 /* Add alignment between size and first element */
1079 c->signature[c->index] = 0;
1081 m->header->body_size = saved;
1085 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1088 /* m->body might have changed so let's readjust a */
1089 a = (uint8_t*) m->body + ((uint8_t*) a - (uint8_t*) b);
1096 static int bus_message_open_variant(
1098 struct bus_container *c,
1099 const char *contents) {
1109 if (!signature_is_single(contents))
1112 if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
1115 if (c->signature && c->signature[c->index]) {
1117 if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
1121 if (c->enclosing != 0)
1124 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_VARIANT), NULL);
1129 l = strlen(contents);
1130 a = message_extend_body(m, 1, 1 + l + 1);
1132 /* Truncate extended signature again */
1134 c->signature[c->index] = 0;
1140 memcpy((uint8_t*) a + 1, contents, l + 1);
1142 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1148 static int bus_message_open_struct(
1150 struct bus_container *c,
1151 const char *contents) {
1160 if (!signature_is_valid(contents, false))
1163 if (c->signature && c->signature[c->index]) {
1166 l = strlen(contents);
1168 if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
1169 !startswith(c->signature + c->index + 1, contents) ||
1170 c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
1173 nindex = c->index + 1 + l + 1;
1175 if (c->enclosing != 0)
1178 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_BEGIN), contents, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_END), NULL);
1182 nindex = e - c->signature;
1185 /* Align contents to 8 byte boundary */
1186 if (!message_extend_body(m, 8, 0)) {
1188 c->signature[c->index] = 0;
1193 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1199 static int bus_message_open_dict_entry(
1201 struct bus_container *c,
1202 const char *contents) {
1210 if (!signature_is_pair(contents))
1213 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1216 if (c->signature && c->signature[c->index]) {
1219 l = strlen(contents);
1221 if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
1222 !startswith(c->signature + c->index + 1, contents) ||
1223 c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
1226 nindex = c->index + 1 + l + 1;
1230 /* Align contents to 8 byte boundary */
1231 if (!message_extend_body(m, 8, 0))
1234 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1240 int sd_bus_message_open_container(
1243 const char *contents) {
1245 struct bus_container *c, *w;
1246 uint32_t *array_size = NULL;
1257 /* Make sure we have space for one more container */
1258 w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
1263 c = message_get_container(m);
1265 signature = strdup(contents);
1269 if (type == SD_BUS_TYPE_ARRAY)
1270 r = bus_message_open_array(m, c, contents, &array_size);
1271 else if (type == SD_BUS_TYPE_VARIANT)
1272 r = bus_message_open_variant(m, c, contents);
1273 else if (type == SD_BUS_TYPE_STRUCT)
1274 r = bus_message_open_struct(m, c, contents);
1275 else if (type == SD_BUS_TYPE_DICT_ENTRY)
1276 r = bus_message_open_dict_entry(m, c, contents);
1285 /* OK, let's fill it in */
1286 w += m->n_containers++;
1287 w->enclosing = type;
1288 w->signature = signature;
1290 w->array_size = array_size;
1296 int sd_bus_message_close_container(sd_bus_message *m) {
1297 struct bus_container *c;
1303 if (m->n_containers <= 0)
1306 c = message_get_container(m);
1307 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1308 if (c->signature && c->signature[c->index] != 0)
1324 static int type_stack_push(TypeStack *stack, unsigned max, unsigned *i, const char *types, unsigned n_struct, unsigned n_array) {
1331 stack[*i].types = types;
1332 stack[*i].n_struct = n_struct;
1333 stack[*i].n_array = n_array;
1339 static int type_stack_pop(TypeStack *stack, unsigned max, unsigned *i, const char **types, unsigned *n_struct, unsigned *n_array) {
1350 *types = stack[*i].types;
1351 *n_struct = stack[*i].n_struct;
1352 *n_array = stack[*i].n_array;
1357 int bus_message_append_ap(
1362 unsigned n_array, n_struct;
1363 TypeStack stack[BUS_CONTAINER_DEPTH];
1364 unsigned stack_ptr = 0;
1372 n_array = (unsigned) -1;
1373 n_struct = strlen(types);
1378 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
1379 r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
1385 r = sd_bus_message_close_container(m);
1393 if (n_array != (unsigned) -1)
1402 case SD_BUS_TYPE_BYTE: {
1405 x = (uint8_t) va_arg(ap, int);
1406 r = sd_bus_message_append_basic(m, *t, &x);
1410 case SD_BUS_TYPE_BOOLEAN:
1411 case SD_BUS_TYPE_INT32:
1412 case SD_BUS_TYPE_UINT32:
1413 case SD_BUS_TYPE_UNIX_FD: {
1416 /* We assume a boolean is the same as int32_t */
1417 assert_cc(sizeof(int32_t) == sizeof(int));
1419 x = va_arg(ap, uint32_t);
1420 r = sd_bus_message_append_basic(m, *t, &x);
1424 case SD_BUS_TYPE_INT16:
1425 case SD_BUS_TYPE_UINT16: {
1428 x = (uint16_t) va_arg(ap, int);
1429 r = sd_bus_message_append_basic(m, *t, &x);
1433 case SD_BUS_TYPE_INT64:
1434 case SD_BUS_TYPE_UINT64:
1435 case SD_BUS_TYPE_DOUBLE: {
1438 x = va_arg(ap, uint64_t);
1439 r = sd_bus_message_append_basic(m, *t, &x);
1443 case SD_BUS_TYPE_STRING:
1444 case SD_BUS_TYPE_OBJECT_PATH:
1445 case SD_BUS_TYPE_SIGNATURE: {
1448 x = va_arg(ap, const char*);
1449 r = sd_bus_message_append_basic(m, *t, x);
1453 case SD_BUS_TYPE_ARRAY: {
1456 r = signature_element_length(t + 1, &k);
1462 memcpy(s, t + 1, k);
1465 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, s);
1470 if (n_array == (unsigned) -1) {
1475 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
1481 n_array = va_arg(ap, unsigned);
1486 case SD_BUS_TYPE_VARIANT: {
1489 s = va_arg(ap, const char*);
1493 r = sd_bus_message_open_container(m, SD_BUS_TYPE_VARIANT, s);
1497 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
1502 n_struct = strlen(s);
1503 n_array = (unsigned) -1;
1508 case SD_BUS_TYPE_STRUCT_BEGIN:
1509 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
1512 r = signature_element_length(t, &k);
1519 memcpy(s, t + 1, k - 2);
1522 r = sd_bus_message_open_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
1527 if (n_array == (unsigned) -1) {
1532 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
1538 n_array = (unsigned) -1;
1554 int sd_bus_message_append(sd_bus_message *m, const char *types, ...) {
1565 va_start(ap, types);
1566 r = bus_message_append_ap(m, types, ap);
1572 static int buffer_peek(const void *p, uint32_t sz, size_t *rindex, size_t align, size_t nbytes, void **r) {
1578 start = ALIGN_TO((size_t) *rindex, align);
1584 /* Verify that padding is 0 */
1585 for (k = *rindex; k < start; k++)
1586 if (((const uint8_t*) p)[k] != 0)
1590 *r = (uint8_t*) p + start;
1597 static bool message_end_of_array(sd_bus_message *m, size_t index) {
1598 struct bus_container *c;
1602 c = message_get_container(m);
1606 return index >= c->begin + BUS_MESSAGE_BSWAP32(m, *c->array_size);
1609 static int message_peek_body(sd_bus_message *m, size_t *rindex, size_t align, size_t nbytes, void **ret) {
1614 if (message_end_of_array(m, *rindex))
1617 return buffer_peek(m->body, BUS_MESSAGE_BODY_SIZE(m), rindex, align, nbytes, ret);
1620 static bool validate_nul(const char *s, size_t l) {
1622 /* Check for NUL chars in the string */
1623 if (memchr(s, 0, l))
1626 /* Check for NUL termination */
1633 static bool validate_string(const char *s, size_t l) {
1635 if (!validate_nul(s, l))
1638 /* Check if valid UTF8 */
1639 if (!utf8_is_valid(s))
1645 static bool validate_signature(const char *s, size_t l) {
1647 if (!validate_nul(s, l))
1650 /* Check if valid signature */
1651 if (!signature_is_valid(s, true))
1657 static bool validate_object_path(const char *s, size_t l) {
1659 if (!validate_nul(s, l))
1662 if (!object_path_is_valid(s))
1668 int sd_bus_message_read_basic(sd_bus_message *m, char type, void *p) {
1669 struct bus_container *c;
1677 if (!bus_type_is_basic(type))
1682 c = message_get_container(m);
1684 if (!c->signature || c->signature[c->index] == 0)
1687 if (c->signature[c->index] != type)
1692 case SD_BUS_TYPE_STRING:
1693 case SD_BUS_TYPE_OBJECT_PATH: {
1698 r = message_peek_body(m, &rindex, 4, 4, &q);
1702 l = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
1703 r = message_peek_body(m, &rindex, 1, l+1, &q);
1709 if (type == SD_BUS_TYPE_OBJECT_PATH) {
1710 if (!validate_object_path(q, l))
1713 if (!validate_string(q, l))
1718 *(const char**) p = q;
1722 case SD_BUS_TYPE_SIGNATURE: {
1727 r = message_peek_body(m, &rindex, 1, 1, &q);
1732 r = message_peek_body(m, &rindex, 1, l+1, &q);
1738 if (!validate_signature(q, l))
1742 *(const char**) p = q;
1750 align = bus_type_get_alignment(type);
1751 sz = bus_type_get_size(type);
1752 assert(align > 0 && sz > 0);
1755 r = message_peek_body(m, &rindex, align, sz, &q);
1761 case SD_BUS_TYPE_BYTE:
1762 *(uint8_t*) p = *(uint8_t*) q;
1765 case SD_BUS_TYPE_BOOLEAN:
1766 *(int*) p = !!*(uint32_t*) q;
1769 case SD_BUS_TYPE_INT16:
1770 case SD_BUS_TYPE_UINT16:
1771 *(uint16_t*) p = BUS_MESSAGE_BSWAP16(m, *(uint16_t*) q);
1774 case SD_BUS_TYPE_INT32:
1775 case SD_BUS_TYPE_UINT32:
1776 *(uint32_t*) p = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
1779 case SD_BUS_TYPE_INT64:
1780 case SD_BUS_TYPE_UINT64:
1781 case SD_BUS_TYPE_DOUBLE:
1782 *(uint64_t*) p = BUS_MESSAGE_BSWAP64(m, *(uint64_t*) q);
1785 case SD_BUS_TYPE_UNIX_FD: {
1788 j = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
1792 *(int*) p = m->fds[j];
1797 assert_not_reached("Unknown basic type...");
1806 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1812 static int bus_message_enter_array(
1814 struct bus_container *c,
1815 const char *contents,
1816 uint32_t **array_size) {
1827 if (!signature_is_single(contents))
1830 alignment = bus_type_get_alignment(contents[0]);
1834 if (!c->signature || c->signature[c->index] == 0)
1837 if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
1840 if (!startswith(c->signature + c->index + 1, contents))
1844 r = message_peek_body(m, &rindex, 4, 4, &q);
1848 if (BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q) > BUS_ARRAY_MAX_SIZE)
1851 r = message_peek_body(m, &rindex, alignment, 0, NULL);
1857 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1858 c->index += 1 + strlen(contents);
1862 *array_size = (uint32_t*) q;
1867 static int bus_message_enter_variant(
1869 struct bus_container *c,
1870 const char *contents) {
1881 if (!signature_is_single(contents))
1884 if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
1887 if (!c->signature || c->signature[c->index] == 0)
1890 if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
1894 r = message_peek_body(m, &rindex, 1, 1, &q);
1899 r = message_peek_body(m, &rindex, 1, l+1, &q);
1905 if (!validate_signature(q, l))
1908 if (!streq(q, contents))
1911 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1919 static int bus_message_enter_struct(
1921 struct bus_container *c,
1922 const char *contents) {
1931 if (!signature_is_valid(contents, false))
1934 if (!c->signature || c->signature[c->index] == 0)
1937 l = strlen(contents);
1939 if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
1940 !startswith(c->signature + c->index + 1, contents) ||
1941 c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
1944 r = message_peek_body(m, &m->rindex, 8, 0, NULL);
1948 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1949 c->index += 1 + l + 1;
1954 static int bus_message_enter_dict_entry(
1956 struct bus_container *c,
1957 const char *contents) {
1966 if (!signature_is_pair(contents))
1969 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1972 if (!c->signature || c->signature[c->index] == 0)
1975 l = strlen(contents);
1977 if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
1978 !startswith(c->signature + c->index + 1, contents) ||
1979 c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
1982 r = message_peek_body(m, &m->rindex, 8, 0, NULL);
1986 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1987 c->index += 1 + l + 1;
1992 int sd_bus_message_enter_container(sd_bus_message *m, char type, const char *contents) {
1993 struct bus_container *c, *w;
1994 uint32_t *array_size = NULL;
2006 * We enforce a global limit on container depth, that is much
2007 * higher than the 32 structs and 32 arrays the specification
2008 * mandates. This is simpler to implement for us, and we need
2009 * this only to ensure our container array doesn't grow
2010 * without bounds. We are happy to return any data from a
2011 * message as long as the data itself is valid, even if the
2012 * overall message might be not.
2014 * Note that the message signature is validated when
2015 * parsing the headers, and that validation does check the
2018 * Note that the specification defines no limits on the depth
2019 * of stacked variants, but we do.
2021 if (m->n_containers >= BUS_CONTAINER_DEPTH)
2024 w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
2029 c = message_get_container(m);
2031 if (!c->signature || c->signature[c->index] == 0)
2034 signature = strdup(contents);
2038 if (type == SD_BUS_TYPE_ARRAY)
2039 r = bus_message_enter_array(m, c, contents, &array_size);
2040 else if (type == SD_BUS_TYPE_VARIANT)
2041 r = bus_message_enter_variant(m, c, contents);
2042 else if (type == SD_BUS_TYPE_STRUCT)
2043 r = bus_message_enter_struct(m, c, contents);
2044 else if (type == SD_BUS_TYPE_DICT_ENTRY)
2045 r = bus_message_enter_dict_entry(m, c, contents);
2054 /* OK, let's fill it in */
2055 w += m->n_containers++;
2056 w->enclosing = type;
2057 w->signature = signature;
2059 w->array_size = array_size;
2060 w->begin = m->rindex;
2065 int sd_bus_message_exit_container(sd_bus_message *m) {
2066 struct bus_container *c;
2072 if (m->n_containers <= 0)
2075 c = message_get_container(m);
2076 if (c->enclosing == SD_BUS_TYPE_ARRAY) {
2079 l = BUS_MESSAGE_BSWAP32(m, *c->array_size);
2080 if (c->begin + l != m->rindex)
2084 if (c->signature && c->signature[c->index] != 0)
2094 int sd_bus_message_peek_type(sd_bus_message *m, char *type, const char **contents) {
2095 struct bus_container *c;
2103 c = message_get_container(m);
2105 if (!c->signature || c->signature[c->index] == 0)
2108 if (message_end_of_array(m, m->rindex))
2111 if (bus_type_is_basic(c->signature[c->index])) {
2115 *type = c->signature[c->index];
2119 if (c->signature[c->index] == SD_BUS_TYPE_ARRAY) {
2125 r = signature_element_length(c->signature+c->index+1, &l);
2131 sig = strndup(c->signature + c->index + 1, l);
2135 free(m->peeked_signature);
2136 m->peeked_signature = sig;
2142 *type = SD_BUS_TYPE_ARRAY;
2147 if (c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ||
2148 c->signature[c->index] == SD_BUS_TYPE_DICT_ENTRY_BEGIN) {
2154 r = signature_element_length(c->signature+c->index, &l);
2159 sig = strndup(c->signature + c->index + 1, l - 2);
2163 free(m->peeked_signature);
2164 m->peeked_signature = sig;
2170 *type = c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY;
2175 if (c->signature[c->index] == SD_BUS_TYPE_VARIANT) {
2181 r = message_peek_body(m, &rindex, 1, 1, &q);
2188 r = message_peek_body(m, &rindex, 1, l+1, &q);
2194 if (!validate_signature(q, l))
2201 *type = SD_BUS_TYPE_VARIANT;
2210 *type = c->enclosing;
2216 int sd_bus_message_rewind(sd_bus_message *m, int complete) {
2217 struct bus_container *c;
2225 reset_containers(m);
2227 m->root_container.index = 0;
2229 c = message_get_container(m);
2231 c = message_get_container(m);
2234 m->rindex = c->begin;
2237 return !isempty(c->signature);
2239 static int message_read_ap(
2244 unsigned n_array, n_struct;
2245 TypeStack stack[BUS_CONTAINER_DEPTH];
2246 unsigned stack_ptr = 0;
2254 /* Ideally, we'd just call ourselves recursively on every
2255 * complex type. However, the state of a va_list that is
2256 * passed to a function is undefined after that function
2257 * returns. This means we need to docode the va_list linearly
2258 * in a single stackframe. We hence implement our own
2259 * home-grown stack in an array. */
2261 n_array = (unsigned) -1;
2262 n_struct = strlen(types);
2267 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
2268 r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
2274 r = sd_bus_message_exit_container(m);
2282 if (n_array != (unsigned) -1)
2291 case SD_BUS_TYPE_BYTE:
2292 case SD_BUS_TYPE_BOOLEAN:
2293 case SD_BUS_TYPE_INT16:
2294 case SD_BUS_TYPE_UINT16:
2295 case SD_BUS_TYPE_INT32:
2296 case SD_BUS_TYPE_UINT32:
2297 case SD_BUS_TYPE_INT64:
2298 case SD_BUS_TYPE_UINT64:
2299 case SD_BUS_TYPE_DOUBLE:
2300 case SD_BUS_TYPE_STRING:
2301 case SD_BUS_TYPE_OBJECT_PATH:
2302 case SD_BUS_TYPE_SIGNATURE:
2303 case SD_BUS_TYPE_UNIX_FD: {
2306 p = va_arg(ap, void*);
2307 r = sd_bus_message_read_basic(m, *t, p);
2316 case SD_BUS_TYPE_ARRAY: {
2319 r = signature_element_length(t + 1, &k);
2325 memcpy(s, t + 1, k);
2328 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, s);
2335 if (n_array == (unsigned) -1) {
2340 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2346 n_array = va_arg(ap, unsigned);
2351 case SD_BUS_TYPE_VARIANT: {
2354 s = va_arg(ap, const char *);
2358 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, s);
2364 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2369 n_struct = strlen(s);
2370 n_array = (unsigned) -1;
2375 case SD_BUS_TYPE_STRUCT_BEGIN:
2376 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
2379 r = signature_element_length(t, &k);
2385 memcpy(s, t + 1, k - 2);
2388 r = sd_bus_message_enter_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
2395 if (n_array == (unsigned) -1) {
2400 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2406 n_array = (unsigned) -1;
2419 int sd_bus_message_read(sd_bus_message *m, const char *types, ...) {
2430 va_start(ap, types);
2431 r = message_read_ap(m, types, ap);
2437 static int message_peek_fields(
2448 return buffer_peek(m->fields, BUS_MESSAGE_FIELDS_SIZE(m), rindex, align, nbytes, ret);
2451 static int message_peek_field_uint32(
2462 r = message_peek_fields(m, ri, 4, 4, &q);
2467 *ret = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2472 static int message_peek_field_string(
2474 bool (*validate)(const char *p),
2485 r = message_peek_field_uint32(m, ri, &l);
2489 r = message_peek_fields(m, ri, 1, l+1, &q);
2494 if (!validate_nul(q, l))
2500 if (!validate_string(q, l))
2510 static int message_peek_field_signature(
2522 r = message_peek_fields(m, ri, 1, 1, &q);
2527 r = message_peek_fields(m, ri, 1, l+1, &q);
2531 if (!validate_signature(q, l))
2540 static int message_skip_fields(
2543 uint32_t array_size,
2544 const char **signature) {
2546 size_t original_index;
2553 original_index = *ri;
2559 if (array_size != (uint32_t) -1 &&
2560 array_size <= *ri - original_index)
2567 if (t == SD_BUS_TYPE_STRING) {
2569 r = message_peek_field_string(m, NULL, ri, NULL);
2575 } else if (t == SD_BUS_TYPE_OBJECT_PATH) {
2577 r = message_peek_field_string(m, object_path_is_valid, ri, NULL);
2583 } else if (t == SD_BUS_TYPE_SIGNATURE) {
2585 r = message_peek_field_signature(m, ri, NULL);
2591 } else if (bus_type_is_basic(t)) {
2594 align = bus_type_get_alignment(t);
2595 k = bus_type_get_size(t);
2596 assert(align > 0 && k > 0);
2598 r = message_peek_fields(m, ri, align, k, NULL);
2604 } else if (t == SD_BUS_TYPE_ARRAY) {
2606 r = signature_element_length(*signature+1, &l);
2616 strncpy(sig, *signature + 1, l-1);
2619 alignment = bus_type_get_alignment(sig[0]);
2623 r = message_peek_field_uint32(m, ri, &nas);
2626 if (nas > BUS_ARRAY_MAX_SIZE)
2629 r = message_peek_fields(m, ri, alignment, 0, NULL);
2633 r = message_skip_fields(m, ri, nas, (const char**) &s);
2638 (*signature) += 1 + l;
2640 } else if (t == SD_BUS_TYPE_VARIANT) {
2643 r = message_peek_field_signature(m, ri, &s);
2647 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
2653 } else if (t == SD_BUS_TYPE_STRUCT ||
2654 t == SD_BUS_TYPE_DICT_ENTRY) {
2656 r = signature_element_length(*signature, &l);
2663 strncpy(sig, *signature + 1, l-1);
2666 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
2677 int bus_message_parse_fields(sd_bus_message *m) {
2680 uint32_t unix_fds = 0;
2684 for (ri = 0; ri < BUS_MESSAGE_FIELDS_SIZE(m); ) {
2685 const char *signature;
2688 r = message_peek_fields(m, &ri, 8, 1, (void**) &header);
2692 r = message_peek_field_signature(m, &ri, &signature);
2697 case _SD_BUS_MESSAGE_HEADER_INVALID:
2700 case SD_BUS_MESSAGE_HEADER_PATH:
2705 if (!streq(signature, "o"))
2708 r = message_peek_field_string(m, object_path_is_valid, &ri, &m->path);
2711 case SD_BUS_MESSAGE_HEADER_INTERFACE:
2716 if (!streq(signature, "s"))
2719 r = message_peek_field_string(m, interface_name_is_valid, &ri, &m->interface);
2722 case SD_BUS_MESSAGE_HEADER_MEMBER:
2727 if (!streq(signature, "s"))
2730 r = message_peek_field_string(m, member_name_is_valid, &ri, &m->member);
2733 case SD_BUS_MESSAGE_HEADER_ERROR_NAME:
2738 if (!streq(signature, "s"))
2741 r = message_peek_field_string(m, error_name_is_valid, &ri, &m->error.name);
2744 case SD_BUS_MESSAGE_HEADER_DESTINATION:
2749 if (!streq(signature, "s"))
2752 r = message_peek_field_string(m, service_name_is_valid, &ri, &m->destination);
2755 case SD_BUS_MESSAGE_HEADER_SENDER:
2760 if (!streq(signature, "s"))
2763 r = message_peek_field_string(m, service_name_is_valid, &ri, &m->sender);
2767 case SD_BUS_MESSAGE_HEADER_SIGNATURE: {
2771 if (m->root_container.signature)
2774 if (!streq(signature, "g"))
2777 r = message_peek_field_signature(m, &ri, &s);
2785 free(m->root_container.signature);
2786 m->root_container.signature = c;
2790 case SD_BUS_MESSAGE_HEADER_REPLY_SERIAL:
2791 if (m->reply_serial != 0)
2794 if (!streq(signature, "u"))
2797 r = message_peek_field_uint32(m, &ri, &m->reply_serial);
2801 if (m->reply_serial == 0)
2806 case SD_BUS_MESSAGE_HEADER_UNIX_FDS:
2810 if (!streq(signature, "u"))
2813 r = message_peek_field_uint32(m, &ri, &unix_fds);
2823 r = message_skip_fields(m, &ri, (uint32_t) -1, (const char **) &signature);
2830 if (m->n_fds != unix_fds)
2833 if (isempty(m->root_container.signature) != (BUS_MESSAGE_BODY_SIZE(m) == 0))
2836 switch (m->header->type) {
2838 case SD_BUS_MESSAGE_TYPE_SIGNAL:
2839 if (!m->path || !m->interface || !m->member)
2843 case SD_BUS_MESSAGE_TYPE_METHOD_CALL:
2845 if (!m->path || !m->member)
2850 case SD_BUS_MESSAGE_TYPE_METHOD_RETURN:
2852 if (m->reply_serial == 0)
2856 case SD_BUS_MESSAGE_TYPE_METHOD_ERROR:
2858 if (m->reply_serial == 0 || !m->error.name)
2863 /* Try to read the error message, but if we can't it's a non-issue */
2864 if (m->header->type == SD_BUS_MESSAGE_TYPE_METHOD_ERROR)
2865 sd_bus_message_read(m, "s", &m->error.message);
2870 int bus_message_seal(sd_bus_message *m, uint64_t serial) {
2879 if (m->n_containers > 0)
2882 /* If there's a non-trivial signature set, then add it in here */
2883 if (!isempty(m->root_container.signature)) {
2884 r = message_append_field_signature(m, SD_BUS_MESSAGE_HEADER_SIGNATURE, m->root_container.signature, NULL);
2890 r = message_append_field_uint32(m, SD_BUS_MESSAGE_HEADER_UNIX_FDS, m->n_fds);
2895 l = BUS_MESSAGE_FIELDS_SIZE(m);
2899 /* Add padding at the end, since we know the body
2900 * needs to start at an 8 byte alignment. */
2903 p = message_extend_fields(m, 1, a);
2908 m->header->fields_size -= a;
2911 m->header->serial = serial;
2917 int sd_bus_message_set_destination(sd_bus_message *m, const char *destination) {
2927 return message_append_field_string(m, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &m->destination);
2930 int bus_message_dump(sd_bus_message *m) {
2936 printf("Message %p\n"
2943 "\tfields_size=%u\n"
2948 "\tdestination=%s\n"
2951 "\treply_serial=%u\n"
2953 "\terror.message=%s\n"
2961 BUS_MESSAGE_SERIAL(m),
2962 BUS_MESSAGE_FIELDS_SIZE(m),
2963 BUS_MESSAGE_BODY_SIZE(m),
2965 strna(m->interface),
2967 strna(m->destination),
2969 strna(m->root_container.signature),
2971 strna(m->error.name),
2972 strna(m->error.message),
2976 printf("\tpid=%lu\n", (unsigned long) m->pid);
2978 printf("\ttid=%lu\n", (unsigned long) m->tid);
2980 printf("\tuid=%lu\n", (unsigned long) m->uid);
2982 printf("\tgid=%lu\n", (unsigned long) m->gid);
2983 if (m->pid_starttime != 0)
2984 printf("\tpid_starttime=%llu\n", (unsigned long long) m->pid_starttime);
2985 if (m->monotonic != 0)
2986 printf("\tmonotonic=%llu\n", (unsigned long long) m->monotonic);
2987 if (m->realtime != 0)
2988 printf("\trealtime=%llu\n", (unsigned long long) m->realtime);
2990 printf("\texe=[%s]\n", m->exe);
2992 printf("\tcomm=[%s]\n", m->comm);
2994 printf("\ttid_comm=[%s]\n", m->tid_comm);
2996 printf("\tlabel=[%s]\n", m->label);
2998 r = sd_bus_message_rewind(m, true);
3000 log_error("Failed to rewind: %s", strerror(-r));
3004 printf("BEGIN_MESSAGE \"%s\" {\n", strempty(m->root_container.signature));
3007 _cleanup_free_ char *prefix = NULL;
3008 const char *contents = NULL;
3023 r = sd_bus_message_peek_type(m, &type, &contents);
3025 log_error("Failed to peek type: %s", strerror(-r));
3032 r = sd_bus_message_exit_container(m);
3034 log_error("Failed to exit container: %s", strerror(-r));
3040 prefix = strrep("\t", level);
3044 if (type == SD_BUS_TYPE_ARRAY)
3045 printf("%s} END_ARRAY \n", prefix);
3046 else if (type == SD_BUS_TYPE_VARIANT)
3047 printf("%s} END_VARIANT\n", prefix);
3048 else if (type == SD_BUS_TYPE_STRUCT)
3049 printf("%s} END_STRUCT\n", prefix);
3050 else if (type == SD_BUS_TYPE_DICT_ENTRY)
3051 printf("%s} END_DICT_ENTRY\n", prefix);
3056 prefix = strrep("\t", level);
3060 if (bus_type_is_container(type) > 0) {
3061 r = sd_bus_message_enter_container(m, type, contents);
3063 log_error("Failed to enter container: %s", strerror(-r));
3067 if (type == SD_BUS_TYPE_ARRAY)
3068 printf("%sBEGIN_ARRAY \"%s\" {\n", prefix, contents);
3069 else if (type == SD_BUS_TYPE_VARIANT)
3070 printf("%sBEGIN_VARIANT \"%s\" {\n", prefix, contents);
3071 else if (type == SD_BUS_TYPE_STRUCT)
3072 printf("%sBEGIN_STRUCT \"%s\" {\n", prefix, contents);
3073 else if (type == SD_BUS_TYPE_DICT_ENTRY)
3074 printf("%sBEGIN_DICT_ENTRY \"%s\" {\n", prefix, contents);
3081 r = sd_bus_message_read_basic(m, type, &basic);
3083 log_error("Failed to get basic: %s", strerror(-r));
3089 case SD_BUS_TYPE_BYTE:
3090 printf("%sBYTE: %u\n", prefix, basic.u8);
3093 case SD_BUS_TYPE_BOOLEAN:
3094 printf("%sBOOLEAN: %s\n", prefix, yes_no(basic.i));
3097 case SD_BUS_TYPE_INT16:
3098 printf("%sINT16: %i\n", prefix, basic.s16);
3101 case SD_BUS_TYPE_UINT16:
3102 printf("%sUINT16: %u\n", prefix, basic.u16);
3105 case SD_BUS_TYPE_INT32:
3106 printf("%sINT32: %i\n", prefix, basic.s32);
3109 case SD_BUS_TYPE_UINT32:
3110 printf("%sUINT32: %u\n", prefix, basic.u32);
3113 case SD_BUS_TYPE_INT64:
3114 printf("%sINT64: %lli\n", prefix, (long long) basic.s64);
3117 case SD_BUS_TYPE_UINT64:
3118 printf("%sUINT64: %llu\n", prefix, (unsigned long long) basic.u64);
3121 case SD_BUS_TYPE_DOUBLE:
3122 printf("%sDOUBLE: %g\n", prefix, basic.d64);
3125 case SD_BUS_TYPE_STRING:
3126 printf("%sSTRING: \"%s\"\n", prefix, basic.string);
3129 case SD_BUS_TYPE_OBJECT_PATH:
3130 printf("%sOBJECT_PATH: \"%s\"\n", prefix, basic.string);
3133 case SD_BUS_TYPE_SIGNATURE:
3134 printf("%sSIGNATURE: \"%s\"\n", prefix, basic.string);
3137 case SD_BUS_TYPE_UNIX_FD:
3138 printf("%sUNIX_FD: %i\n", prefix, basic.i);
3142 assert_not_reached("Unknown basic type.");
3146 printf("} END_MESSAGE\n");
3150 int bus_message_get_blob(sd_bus_message *m, void **buffer, size_t *sz) {
3158 total = BUS_MESSAGE_SIZE(m);
3164 e = mempcpy(p, m->header, sizeof(*m->header));
3167 e = mempcpy(e, m->fields, m->header->fields_size);
3169 if (m->header->fields_size % 8 != 0)
3170 e = mempset(e, 0, 8 - (m->header->fields_size % 8));
3174 e = mempcpy(e, m->body, m->header->body_size);
3176 assert(total == (size_t) ((uint8_t*) e - (uint8_t*) p));
3184 int bus_message_read_strv_extend(sd_bus_message *m, char ***l) {
3190 r = sd_bus_message_enter_container(m, 'a', "s");
3197 r = sd_bus_message_read_basic(m, 's', &s);
3203 r = strv_extend(l, s);
3208 r = sd_bus_message_exit_container(m);
3215 const char* bus_message_get_arg(sd_bus_message *m, unsigned i) {
3222 r = sd_bus_message_rewind(m, true);
3227 r = sd_bus_message_peek_type(m, &type, NULL);
3231 if (type != SD_BUS_TYPE_STRING &&
3232 type != SD_BUS_TYPE_OBJECT_PATH &&
3233 type != SD_BUS_TYPE_SIGNATURE)
3236 r = sd_bus_message_read_basic(m, type, &t);
3243 r = sd_bus_message_rewind(m, true);
3250 int bus_header_size(struct bus_header *h, size_t *sum) {
3256 if (h->endian == SD_BUS_NATIVE_ENDIAN) {
3257 fs = h->fields_size;
3259 } else if (h->endian == SD_BUS_REVERSE_ENDIAN) {
3260 fs = bswap_32(h->fields_size);
3261 bs = bswap_32(h->body_size);
3265 *sum = sizeof(struct bus_header) + ALIGN8(fs) + bs;