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/>.
30 #include "bus-message.h"
31 #include "bus-internal.h"
33 #include "bus-signature.h"
35 static int message_parse_fields(sd_bus_message *m);
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) {
66 close_many(m->fds, m->n_fds);
71 free(m->root_container.signature);
73 free(m->peeked_signature);
77 static void* buffer_extend(void **p, uint32_t *sz, size_t align, size_t extend) {
85 start = ALIGN_TO((size_t) *sz, align);
89 return (uint8_t*) *p + start;
91 if (n > (size_t) ((uint32_t) -1))
98 /* Zero out padding */
100 memset((uint8_t*) k + *sz, 0, start - *sz);
105 return (uint8_t*) k + start;
108 static void *message_extend_fields(sd_bus_message *m, size_t align, size_t sz) {
114 p = buffer_extend(&m->fields, &m->header->fields_size, align, sz);
118 if (o != m->fields) {
119 /* Adjust quick access pointers */
122 m->path = (const char*) m->fields + (m->path - (const char*) o);
124 m->interface = (const char*) m->fields + (m->interface - (const char*) o);
126 m->member = (const char*) m->fields + (m->member - (const char*) o);
128 m->destination = (const char*) m->fields + (m->destination - (const char*) o);
130 m->sender = (const char*) m->fields + (m->sender - (const char*) o);
132 m->error.name = (const char*) m->fields + (m->error.name - (const char*) o);
135 m->free_fields = true;
140 static int message_append_field_string(
153 if (l > (size_t) (uint32_t) -1)
156 /* field id byte + signature length + signature 's' + NUL + string length + string + NUL */
157 p = message_extend_fields(m, 8, 4 + 4 + l + 1);
166 ((uint32_t*) p)[1] = l;
167 memcpy(p + 8, s, l + 1);
170 *ret = (const char*) p + 8;
175 static int message_append_field_signature(
190 /* field id byte + signature length + signature 'g' + NUL + string length + string + NUL */
191 p = message_extend_fields(m, 8, 4 + 1 + l + 1);
197 p[2] = SD_BUS_TYPE_SIGNATURE;
200 memcpy(p + 5, s, l + 1);
203 *ret = (const char*) p + 5;
208 static int message_append_field_uint32(sd_bus_message *m, uint8_t h, uint32_t x) {
213 /* field id byte + signature length + signature 'u' + NUL + value */
214 p = message_extend_fields(m, 8, 4 + 4);
220 p[2] = SD_BUS_TYPE_UINT32;
223 ((uint32_t*) p)[1] = x;
228 int bus_message_from_malloc(
233 const struct ucred *ucred,
235 sd_bus_message **ret) {
238 struct bus_header *h;
239 size_t total, fs, bs, label_sz, a;
242 assert(buffer || length <= 0);
243 assert(fds || n_fds <= 0);
246 if (length < sizeof(struct bus_header))
256 if (h->type == _SD_BUS_MESSAGE_TYPE_INVALID)
259 if (h->endian == SD_BUS_NATIVE_ENDIAN) {
262 } else if (h->endian == SD_BUS_REVERSE_ENDIAN) {
263 fs = bswap_32(h->fields_size);
264 bs = bswap_32(h->body_size);
268 total = sizeof(struct bus_header) + ALIGN_TO(fs, 8) + bs;
273 label_sz = strlen(label);
274 a = ALIGN(sizeof(sd_bus_message)) + label_sz + 1;
276 a = sizeof(sd_bus_message);
285 m->fields = (uint8_t*) buffer + sizeof(struct bus_header);
286 m->body = (uint8_t*) buffer + sizeof(struct bus_header) + ALIGN_TO(fs, 8);
294 m->uid_valid = m->gid_valid = true;
298 m->label = (char*) m + ALIGN(sizeof(sd_bus_message));
299 memcpy(m->label, label, label_sz + 1);
303 m->iovec[0].iov_base = buffer;
304 m->iovec[0].iov_len = length;
307 r = message_parse_fields(m);
311 /* We take possession of the memory and fds now */
312 m->free_header = true;
323 static sd_bus_message *message_new(sd_bus *bus, uint8_t type) {
326 m = malloc0(ALIGN(sizeof(sd_bus_message)) + sizeof(struct bus_header));
331 m->header = (struct bus_header*) ((uint8_t*) m + ALIGN(sizeof(struct sd_bus_message)));
332 m->header->endian = SD_BUS_NATIVE_ENDIAN;
333 m->header->type = type;
334 m->header->version = bus ? bus->message_version : 1;
335 m->allow_fds = !bus || bus->can_fds || (bus->state != BUS_HELLO && bus->state != BUS_RUNNING);
340 int sd_bus_message_new_signal(
343 const char *interface,
345 sd_bus_message **m) {
358 if (bus && bus->state == BUS_UNSET)
361 t = message_new(bus, SD_BUS_MESSAGE_TYPE_SIGNAL);
365 t->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
367 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_PATH, SD_BUS_TYPE_OBJECT_PATH, path, &t->path);
370 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_INTERFACE, SD_BUS_TYPE_STRING, interface, &t->interface);
373 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_MEMBER, SD_BUS_TYPE_STRING, member, &t->member);
381 sd_bus_message_unref(t);
385 int sd_bus_message_new_method_call(
387 const char *destination,
389 const char *interface,
391 sd_bus_message **m) {
402 if (bus && bus->state == BUS_UNSET)
405 t = message_new(bus, SD_BUS_MESSAGE_TYPE_METHOD_CALL);
409 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_PATH, SD_BUS_TYPE_OBJECT_PATH, path, &t->path);
412 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_MEMBER, SD_BUS_TYPE_STRING, member, &t->member);
417 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_INTERFACE, SD_BUS_TYPE_STRING, interface, &t->interface);
423 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &t->destination);
436 static int message_new_reply(
438 sd_bus_message *call,
440 sd_bus_message **m) {
449 if (call->header->type != SD_BUS_MESSAGE_TYPE_METHOD_CALL)
453 if (bus && bus->state == BUS_UNSET)
456 t = message_new(bus, type);
460 t->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
461 t->reply_serial = BUS_MESSAGE_SERIAL(call);
463 r = message_append_field_uint32(t, SD_BUS_MESSAGE_HEADER_REPLY_SERIAL, t->reply_serial);
468 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, call->sender, &t->sender);
473 t->dont_send = !!(call->header->flags & SD_BUS_MESSAGE_NO_REPLY_EXPECTED);
483 int sd_bus_message_new_method_return(
485 sd_bus_message *call,
486 sd_bus_message **m) {
488 return message_new_reply(bus, call, SD_BUS_MESSAGE_TYPE_METHOD_RETURN, m);
491 int sd_bus_message_new_method_error(
493 sd_bus_message *call,
494 const sd_bus_error *e,
495 sd_bus_message **m) {
500 if (!sd_bus_error_is_set(e))
505 r = message_new_reply(bus, call, SD_BUS_MESSAGE_TYPE_METHOD_ERROR, &t);
509 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_ERROR_NAME, SD_BUS_TYPE_STRING, e->name, &t->error.name);
514 r = message_append_basic(t, SD_BUS_TYPE_STRING, e->message, (const void**) &t->error.message);
527 sd_bus_message* sd_bus_message_ref(sd_bus_message *m) {
531 assert(m->n_ref > 0);
537 sd_bus_message* sd_bus_message_unref(sd_bus_message *m) {
541 assert(m->n_ref > 0);
550 int sd_bus_message_get_type(sd_bus_message *m, uint8_t *type) {
556 *type = m->header->type;
560 int sd_bus_message_get_serial(sd_bus_message *m, uint64_t *serial) {
565 if (m->header->serial == 0)
568 *serial = BUS_MESSAGE_SERIAL(m);
572 int sd_bus_message_get_reply_serial(sd_bus_message *m, uint64_t *serial) {
577 if (m->reply_serial == 0)
580 *serial = m->reply_serial;
584 int sd_bus_message_get_no_reply(sd_bus_message *m) {
588 return m->header->type == SD_BUS_MESSAGE_TYPE_METHOD_CALL ? !!(m->header->flags & SD_BUS_MESSAGE_NO_REPLY_EXPECTED) : 0;
591 const char *sd_bus_message_get_path(sd_bus_message *m) {
598 const char *sd_bus_message_get_interface(sd_bus_message *m) {
605 const char *sd_bus_message_get_member(sd_bus_message *m) {
611 const char *sd_bus_message_get_destination(sd_bus_message *m) {
615 return m->destination;
618 const char *sd_bus_message_get_sender(sd_bus_message *m) {
625 const sd_bus_error *sd_bus_message_get_error(sd_bus_message *m) {
629 if (!sd_bus_error_is_set(&m->error))
635 int sd_bus_message_get_uid(sd_bus_message *m, uid_t *uid) {
645 int sd_bus_message_get_gid(sd_bus_message *m, gid_t *gid) {
655 int sd_bus_message_get_pid(sd_bus_message *m, pid_t *pid) {
665 int sd_bus_message_get_tid(sd_bus_message *m, pid_t *tid) {
675 const char *sd_bus_message_get_label(sd_bus_message *m) {
682 int sd_bus_message_is_signal(sd_bus_message *m, const char *interface, const char *member) {
686 if (m->header->type != SD_BUS_MESSAGE_TYPE_SIGNAL)
689 if (interface && (!m->interface || !streq(m->interface, interface)))
692 if (member && (!m->member || !streq(m->member, member)))
698 int sd_bus_message_is_method_call(sd_bus_message *m, const char *interface, const char *member) {
702 if (m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_CALL)
705 if (interface && (!m->interface || !streq(m->interface, interface)))
708 if (member && (!m->member || !streq(m->member, member)))
714 int sd_bus_message_is_method_error(sd_bus_message *m, const char *name) {
718 if (m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_ERROR)
721 if (name && (!m->error.name || !streq(m->error.name, name)))
727 int sd_bus_message_set_no_reply(sd_bus_message *m, int b) {
732 if (m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_CALL)
736 m->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
738 m->header->flags &= ~SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
743 static struct bus_container *message_get_container(sd_bus_message *m) {
746 if (m->n_containers == 0)
747 return &m->root_container;
749 assert(m->containers);
750 return m->containers + m->n_containers - 1;
753 static void *message_extend_body(sd_bus_message *m, size_t align, size_t sz) {
756 struct bus_container *c;
762 added = m->header->body_size;
764 p = buffer_extend(&m->body, &m->header->body_size, align, sz);
768 added = m->header->body_size - added;
770 for (c = m->containers; c < m->containers + m->n_containers; c++)
772 c->array_size = (uint32_t*) ((uint8_t*) m->body + ((uint8_t*) c->array_size - (uint8_t*) o));
773 *c->array_size += added;
777 if (m->error.message)
778 m->error.message = (const char*) m->body + (m->error.message - (const char*) o);
786 int message_append_basic(sd_bus_message *m, char type, const void *p, const void **stored) {
787 struct bus_container *c;
802 if (!bus_type_is_basic(type))
805 c = message_get_container(m);
807 if (c->signature && c->signature[c->index]) {
808 /* Container signature is already set */
810 if (c->signature[c->index] != type)
813 /* Maybe we can append to the signature? But only if this is the top-level container*/
814 if (c->enclosing != 0)
817 e = strextend(&c->signature, CHAR_TO_STR(type), NULL);
824 case SD_BUS_TYPE_STRING:
825 case SD_BUS_TYPE_OBJECT_PATH:
828 sz = 4 + strlen(p) + 1;
831 case SD_BUS_TYPE_SIGNATURE:
834 sz = 1 + strlen(p) + 1;
837 case SD_BUS_TYPE_BOOLEAN:
840 assert_cc(sizeof(int) == sizeof(uint32_t));
846 case SD_BUS_TYPE_UNIX_FD: {
862 fd = fcntl(z, F_DUPFD_CLOEXEC, 3);
868 f = realloc(m->fds, sizeof(int) * (m->n_fds + 1));
882 align = bus_type_get_alignment(type);
883 sz = bus_type_get_size(type);
890 a = message_extend_body(m, align, sz);
896 if (type == SD_BUS_TYPE_STRING || type == SD_BUS_TYPE_OBJECT_PATH) {
897 *(uint32_t*) a = sz - 5;
898 memcpy((uint8_t*) a + 4, p, sz - 4);
901 *stored = (const uint8_t*) a + 4;
903 } else if (type == SD_BUS_TYPE_SIGNATURE) {
904 *(uint8_t*) a = sz - 1;
905 memcpy((uint8_t*) a + 1, p, sz - 1);
908 *stored = (const uint8_t*) a + 1;
909 } else if (type == SD_BUS_TYPE_UNIX_FD) {
910 *(uint32_t*) a = fdi;
924 if (c->enclosing != SD_BUS_TYPE_ARRAY)
930 /* Truncate extended signature again */
932 c->signature[c->index] = 0;
935 close_nointr_nofail(fd);
940 int sd_bus_message_append_basic(sd_bus_message *m, char type, const void *p) {
941 return message_append_basic(m, type, p, NULL);
944 static int bus_message_open_array(
946 struct bus_container *c,
947 const char *contents,
948 uint32_t **array_size) {
961 if (!signature_is_single(contents))
964 alignment = bus_type_get_alignment(contents[0]);
968 if (c->signature && c->signature[c->index]) {
970 /* Verify the existing signature */
972 if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
975 if (!startswith(c->signature + c->index + 1, contents))
978 nindex = c->index + 1 + strlen(contents);
980 if (c->enclosing != 0)
983 /* Extend the existing signature */
985 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_ARRAY), contents, NULL);
989 nindex = e - c->signature;
992 saved = m->header->body_size;
993 a = message_extend_body(m, 4, 4);
995 /* Truncate extended signature again */
997 c->signature[c->index] = 0;
1003 if (!message_extend_body(m, alignment, 0)) {
1004 /* Add alignment between size and first element */
1006 c->signature[c->index] = 0;
1008 m->header->body_size = saved;
1012 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1015 /* m->body might have changed so let's readjust a */
1016 a = (uint8_t*) m->body + ((uint8_t*) a - (uint8_t*) b);
1023 static int bus_message_open_variant(
1025 struct bus_container *c,
1026 const char *contents) {
1036 if (!signature_is_single(contents))
1039 if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
1042 if (c->signature && c->signature[c->index]) {
1044 if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
1048 if (c->enclosing != 0)
1051 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_VARIANT), NULL);
1056 l = strlen(contents);
1057 a = message_extend_body(m, 1, 1 + l + 1);
1059 /* Truncate extended signature again */
1061 c->signature[c->index] = 0;
1067 memcpy((uint8_t*) a + 1, contents, l + 1);
1069 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1075 static int bus_message_open_struct(
1077 struct bus_container *c,
1078 const char *contents) {
1087 if (!signature_is_valid(contents, false))
1090 if (c->signature && c->signature[c->index]) {
1093 l = strlen(contents);
1095 if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
1096 !startswith(c->signature + c->index + 1, contents) ||
1097 c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
1100 nindex = c->index + 1 + l + 1;
1102 if (c->enclosing != 0)
1105 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_BEGIN), contents, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_END), NULL);
1109 nindex = e - c->signature;
1112 /* Align contents to 8 byte boundary */
1113 if (!message_extend_body(m, 8, 0)) {
1115 c->signature[c->index] = 0;
1120 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1126 static int bus_message_open_dict_entry(
1128 struct bus_container *c,
1129 const char *contents) {
1137 if (!signature_is_pair(contents))
1140 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1143 if (c->signature && c->signature[c->index]) {
1146 l = strlen(contents);
1148 if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
1149 !startswith(c->signature + c->index + 1, contents) ||
1150 c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
1153 nindex = c->index + 1 + l + 1;
1157 /* Align contents to 8 byte boundary */
1158 if (!message_extend_body(m, 8, 0))
1161 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1167 int sd_bus_message_open_container(
1170 const char *contents) {
1172 struct bus_container *c, *w;
1173 uint32_t *array_size = NULL;
1184 /* Make sure we have space for one more container */
1185 w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
1190 c = message_get_container(m);
1192 signature = strdup(contents);
1196 if (type == SD_BUS_TYPE_ARRAY)
1197 r = bus_message_open_array(m, c, contents, &array_size);
1198 else if (type == SD_BUS_TYPE_VARIANT)
1199 r = bus_message_open_variant(m, c, contents);
1200 else if (type == SD_BUS_TYPE_STRUCT)
1201 r = bus_message_open_struct(m, c, contents);
1202 else if (type == SD_BUS_TYPE_DICT_ENTRY)
1203 r = bus_message_open_dict_entry(m, c, contents);
1212 /* OK, let's fill it in */
1213 w += m->n_containers++;
1214 w->enclosing = type;
1215 w->signature = signature;
1217 w->array_size = array_size;
1223 int sd_bus_message_close_container(sd_bus_message *m) {
1224 struct bus_container *c;
1230 if (m->n_containers <= 0)
1233 c = message_get_container(m);
1234 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1235 if (c->signature && c->signature[c->index] != 0)
1251 static int type_stack_push(TypeStack *stack, unsigned max, unsigned *i, const char *types, unsigned n_struct, unsigned n_array) {
1258 stack[*i].types = types;
1259 stack[*i].n_struct = n_struct;
1260 stack[*i].n_array = n_array;
1266 static int type_stack_pop(TypeStack *stack, unsigned max, unsigned *i, const char **types, unsigned *n_struct, unsigned *n_array) {
1277 *types = stack[*i].types;
1278 *n_struct = stack[*i].n_struct;
1279 *n_array = stack[*i].n_array;
1284 int bus_message_append_ap(
1289 unsigned n_array, n_struct;
1290 TypeStack stack[BUS_CONTAINER_DEPTH];
1291 unsigned stack_ptr = 0;
1299 n_array = (unsigned) -1;
1300 n_struct = strlen(types);
1305 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
1306 r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
1312 r = sd_bus_message_close_container(m);
1320 if (n_array != (unsigned) -1)
1329 case SD_BUS_TYPE_BYTE: {
1332 x = (uint8_t) va_arg(ap, int);
1333 r = sd_bus_message_append_basic(m, *t, &x);
1337 case SD_BUS_TYPE_BOOLEAN:
1338 case SD_BUS_TYPE_INT32:
1339 case SD_BUS_TYPE_UINT32:
1340 case SD_BUS_TYPE_UNIX_FD: {
1343 /* We assume a boolean is the same as int32_t */
1344 assert_cc(sizeof(int32_t) == sizeof(int));
1346 x = va_arg(ap, uint32_t);
1347 r = sd_bus_message_append_basic(m, *t, &x);
1351 case SD_BUS_TYPE_INT16:
1352 case SD_BUS_TYPE_UINT16: {
1355 x = (uint16_t) va_arg(ap, int);
1356 r = sd_bus_message_append_basic(m, *t, &x);
1360 case SD_BUS_TYPE_INT64:
1361 case SD_BUS_TYPE_UINT64:
1362 case SD_BUS_TYPE_DOUBLE: {
1365 x = va_arg(ap, uint64_t);
1366 r = sd_bus_message_append_basic(m, *t, &x);
1370 case SD_BUS_TYPE_STRING:
1371 case SD_BUS_TYPE_OBJECT_PATH:
1372 case SD_BUS_TYPE_SIGNATURE: {
1375 x = va_arg(ap, const char*);
1376 r = sd_bus_message_append_basic(m, *t, x);
1380 case SD_BUS_TYPE_ARRAY: {
1383 r = signature_element_length(t + 1, &k);
1389 memcpy(s, t + 1, k);
1392 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, s);
1397 if (n_array == (unsigned) -1) {
1402 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
1408 n_array = va_arg(ap, unsigned);
1413 case SD_BUS_TYPE_VARIANT: {
1416 s = va_arg(ap, const char*);
1420 r = sd_bus_message_open_container(m, SD_BUS_TYPE_VARIANT, s);
1424 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
1429 n_struct = strlen(s);
1430 n_array = (unsigned) -1;
1435 case SD_BUS_TYPE_STRUCT_BEGIN:
1436 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
1439 r = signature_element_length(t, &k);
1446 memcpy(s, t + 1, k - 2);
1449 r = sd_bus_message_open_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
1454 if (n_array == (unsigned) -1) {
1459 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
1465 n_array = (unsigned) -1;
1481 int sd_bus_message_append(sd_bus_message *m, const char *types, ...) {
1492 va_start(ap, types);
1493 r = bus_message_append_ap(m, types, ap);
1499 static int buffer_peek(const void *p, uint32_t sz, size_t *rindex, size_t align, size_t nbytes, void **r) {
1505 start = ALIGN_TO((size_t) *rindex, align);
1511 /* Verify that padding is 0 */
1512 for (k = *rindex; k < start; k++)
1513 if (((const uint8_t*) p)[k] != 0)
1517 *r = (uint8_t*) p + start;
1524 static bool message_end_of_array(sd_bus_message *m, size_t index) {
1525 struct bus_container *c;
1529 c = message_get_container(m);
1533 return index >= c->begin + BUS_MESSAGE_BSWAP32(m, *c->array_size);
1536 static int message_peek_body(sd_bus_message *m, size_t *rindex, size_t align, size_t nbytes, void **ret) {
1541 if (message_end_of_array(m, *rindex))
1544 return buffer_peek(m->body, BUS_MESSAGE_BODY_SIZE(m), rindex, align, nbytes, ret);
1547 static bool validate_nul(const char *s, size_t l) {
1549 /* Check for NUL chars in the string */
1550 if (memchr(s, 0, l))
1553 /* Check for NUL termination */
1560 static bool validate_string(const char *s, size_t l) {
1562 if (!validate_nul(s, l))
1565 /* Check if valid UTF8 */
1566 if (!utf8_is_valid(s))
1572 static bool validate_signature(const char *s, size_t l) {
1574 if (!validate_nul(s, l))
1577 /* Check if valid signature */
1578 if (!signature_is_valid(s, true))
1584 static bool validate_object_path(const char *s, size_t l) {
1586 if (!validate_nul(s, l))
1589 if (!object_path_is_valid(s))
1595 int sd_bus_message_read_basic(sd_bus_message *m, char type, void *p) {
1596 struct bus_container *c;
1604 if (!bus_type_is_basic(type))
1609 c = message_get_container(m);
1611 if (!c->signature || c->signature[c->index] == 0)
1614 if (c->signature[c->index] != type)
1619 case SD_BUS_TYPE_STRING:
1620 case SD_BUS_TYPE_OBJECT_PATH: {
1625 r = message_peek_body(m, &rindex, 4, 4, &q);
1629 l = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
1630 r = message_peek_body(m, &rindex, 1, l+1, &q);
1636 if (type == SD_BUS_TYPE_OBJECT_PATH) {
1637 if (!validate_object_path(q, l))
1640 if (!validate_string(q, l))
1645 *(const char**) p = q;
1649 case SD_BUS_TYPE_SIGNATURE: {
1654 r = message_peek_body(m, &rindex, 1, 1, &q);
1659 r = message_peek_body(m, &rindex, 1, l+1, &q);
1665 if (!validate_signature(q, l))
1669 *(const char**) p = q;
1677 align = bus_type_get_alignment(type);
1678 sz = bus_type_get_size(type);
1679 assert(align > 0 && sz > 0);
1682 r = message_peek_body(m, &rindex, align, sz, &q);
1688 case SD_BUS_TYPE_BYTE:
1689 *(uint8_t*) p = *(uint8_t*) q;
1692 case SD_BUS_TYPE_BOOLEAN:
1693 *(int*) p = !!*(uint32_t*) q;
1696 case SD_BUS_TYPE_INT16:
1697 case SD_BUS_TYPE_UINT16:
1698 *(uint16_t*) p = BUS_MESSAGE_BSWAP16(m, *(uint16_t*) q);
1701 case SD_BUS_TYPE_INT32:
1702 case SD_BUS_TYPE_UINT32:
1703 *(uint32_t*) p = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
1706 case SD_BUS_TYPE_INT64:
1707 case SD_BUS_TYPE_UINT64:
1708 case SD_BUS_TYPE_DOUBLE:
1709 *(uint64_t*) p = BUS_MESSAGE_BSWAP64(m, *(uint64_t*) q);
1712 case SD_BUS_TYPE_UNIX_FD: {
1716 j = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
1720 copy = fcntl(m->fds[j], F_DUPFD_CLOEXEC, 3);
1729 assert_not_reached("Unknown basic type...");
1738 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1744 static int bus_message_enter_array(
1746 struct bus_container *c,
1747 const char *contents,
1748 uint32_t **array_size) {
1759 if (!signature_is_single(contents))
1762 alignment = bus_type_get_alignment(contents[0]);
1766 if (!c->signature || c->signature[c->index] == 0)
1769 if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
1772 if (!startswith(c->signature + c->index + 1, contents))
1776 r = message_peek_body(m, &rindex, 4, 4, &q);
1780 if (BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q) > BUS_ARRAY_MAX_SIZE)
1783 r = message_peek_body(m, &rindex, alignment, 0, NULL);
1789 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1790 c->index += 1 + strlen(contents);
1794 *array_size = (uint32_t*) q;
1799 static int bus_message_enter_variant(
1801 struct bus_container *c,
1802 const char *contents) {
1813 if (!signature_is_single(contents))
1816 if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
1819 if (!c->signature || c->signature[c->index] == 0)
1822 if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
1826 r = message_peek_body(m, &rindex, 1, 1, &q);
1831 r = message_peek_body(m, &rindex, 1, l+1, &q);
1837 if (!validate_signature(q, l))
1840 if (!streq(q, contents))
1843 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1851 static int bus_message_enter_struct(
1853 struct bus_container *c,
1854 const char *contents) {
1863 if (!signature_is_valid(contents, false))
1866 if (!c->signature || c->signature[c->index] == 0)
1869 l = strlen(contents);
1871 if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
1872 !startswith(c->signature + c->index + 1, contents) ||
1873 c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
1876 r = message_peek_body(m, &m->rindex, 8, 0, NULL);
1880 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1881 c->index += 1 + l + 1;
1886 static int bus_message_enter_dict_entry(
1888 struct bus_container *c,
1889 const char *contents) {
1898 if (!signature_is_pair(contents))
1901 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1904 if (!c->signature || c->signature[c->index] == 0)
1907 l = strlen(contents);
1909 if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
1910 !startswith(c->signature + c->index + 1, contents) ||
1911 c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
1914 r = message_peek_body(m, &m->rindex, 8, 0, NULL);
1918 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1919 c->index += 1 + l + 1;
1924 int sd_bus_message_enter_container(sd_bus_message *m, char type, const char *contents) {
1925 struct bus_container *c, *w;
1926 uint32_t *array_size = NULL;
1938 * We enforce a global limit on container depth, that is much
1939 * higher than the 32 structs and 32 arrays the specification
1940 * mandates. This is simpler to implement for us, and we need
1941 * this only to ensure our container array doesn't grow
1942 * without bounds. We are happy to return any data from a
1943 * message as long as the data itself is valid, even if the
1944 * overall message might be not.
1946 * Note that the message signature is validated when
1947 * parsing the headers, and that validation does check the
1950 * Note that the specification defines no limits on the depth
1951 * of stacked variants, but we do.
1953 if (m->n_containers >= BUS_CONTAINER_DEPTH)
1956 w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
1961 c = message_get_container(m);
1963 if (!c->signature || c->signature[c->index] == 0)
1966 signature = strdup(contents);
1970 if (type == SD_BUS_TYPE_ARRAY)
1971 r = bus_message_enter_array(m, c, contents, &array_size);
1972 else if (type == SD_BUS_TYPE_VARIANT)
1973 r = bus_message_enter_variant(m, c, contents);
1974 else if (type == SD_BUS_TYPE_STRUCT)
1975 r = bus_message_enter_struct(m, c, contents);
1976 else if (type == SD_BUS_TYPE_DICT_ENTRY)
1977 r = bus_message_enter_dict_entry(m, c, contents);
1986 /* OK, let's fill it in */
1987 w += m->n_containers++;
1988 w->enclosing = type;
1989 w->signature = signature;
1991 w->array_size = array_size;
1992 w->begin = m->rindex;
1997 int sd_bus_message_exit_container(sd_bus_message *m) {
1998 struct bus_container *c;
2004 if (m->n_containers <= 0)
2007 c = message_get_container(m);
2008 if (c->enclosing == SD_BUS_TYPE_ARRAY) {
2011 l = BUS_MESSAGE_BSWAP32(m, *c->array_size);
2012 if (c->begin + l != m->rindex)
2016 if (c->signature && c->signature[c->index] != 0)
2026 int sd_bus_message_peek_type(sd_bus_message *m, char *type, const char **contents) {
2027 struct bus_container *c;
2035 c = message_get_container(m);
2037 if (!c->signature || c->signature[c->index] == 0)
2040 if (message_end_of_array(m, m->rindex))
2043 if (bus_type_is_basic(c->signature[c->index])) {
2047 *type = c->signature[c->index];
2051 if (c->signature[c->index] == SD_BUS_TYPE_ARRAY) {
2057 r = signature_element_length(c->signature+c->index+1, &l);
2063 sig = strndup(c->signature + c->index + 1, l);
2067 free(m->peeked_signature);
2068 m->peeked_signature = sig;
2074 *type = SD_BUS_TYPE_ARRAY;
2079 if (c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ||
2080 c->signature[c->index] == SD_BUS_TYPE_DICT_ENTRY_BEGIN) {
2086 r = signature_element_length(c->signature+c->index, &l);
2091 sig = strndup(c->signature + c->index + 1, l - 2);
2095 free(m->peeked_signature);
2096 m->peeked_signature = sig;
2102 *type = c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY;
2107 if (c->signature[c->index] == SD_BUS_TYPE_VARIANT) {
2113 r = message_peek_body(m, &rindex, 1, 1, &q);
2120 r = message_peek_body(m, &rindex, 1, l+1, &q);
2126 if (!validate_signature(q, l))
2133 *type = SD_BUS_TYPE_VARIANT;
2142 *type = c->enclosing;
2148 int sd_bus_message_rewind(sd_bus_message *m, int complete) {
2149 struct bus_container *c;
2157 reset_containers(m);
2159 m->root_container.index = 0;
2161 c = message_get_container(m);
2163 c = message_get_container(m);
2166 m->rindex = c->begin;
2169 return !isempty(c->signature);
2171 static int message_read_ap(
2176 unsigned n_array, n_struct;
2177 TypeStack stack[BUS_CONTAINER_DEPTH];
2178 unsigned stack_ptr = 0;
2186 /* Ideally, we'd just call ourselves recursively on every
2187 * complex type. However, the state of a va_list that is
2188 * passed to a function is undefined after that function
2189 * returns. This means we need to docode the va_list linearly
2190 * in a single stackframe. We hence implement our own
2191 * home-grown stack in an array. */
2193 n_array = (unsigned) -1;
2194 n_struct = strlen(types);
2199 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
2200 r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
2206 r = sd_bus_message_exit_container(m);
2214 if (n_array != (unsigned) -1)
2223 case SD_BUS_TYPE_BYTE:
2224 case SD_BUS_TYPE_BOOLEAN:
2225 case SD_BUS_TYPE_INT16:
2226 case SD_BUS_TYPE_UINT16:
2227 case SD_BUS_TYPE_INT32:
2228 case SD_BUS_TYPE_UINT32:
2229 case SD_BUS_TYPE_INT64:
2230 case SD_BUS_TYPE_UINT64:
2231 case SD_BUS_TYPE_DOUBLE:
2232 case SD_BUS_TYPE_STRING:
2233 case SD_BUS_TYPE_OBJECT_PATH:
2234 case SD_BUS_TYPE_SIGNATURE:
2235 case SD_BUS_TYPE_UNIX_FD: {
2238 p = va_arg(ap, void*);
2239 r = sd_bus_message_read_basic(m, *t, p);
2248 case SD_BUS_TYPE_ARRAY: {
2251 r = signature_element_length(t + 1, &k);
2257 memcpy(s, t + 1, k);
2260 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, s);
2267 if (n_array == (unsigned) -1) {
2272 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2278 n_array = va_arg(ap, unsigned);
2283 case SD_BUS_TYPE_VARIANT: {
2286 s = va_arg(ap, const char *);
2290 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, s);
2296 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2301 n_struct = strlen(s);
2302 n_array = (unsigned) -1;
2307 case SD_BUS_TYPE_STRUCT_BEGIN:
2308 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
2311 r = signature_element_length(t, &k);
2317 memcpy(s, t + 1, k - 2);
2320 r = sd_bus_message_enter_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
2327 if (n_array == (unsigned) -1) {
2332 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2338 n_array = (unsigned) -1;
2351 int sd_bus_message_read(sd_bus_message *m, const char *types, ...) {
2362 va_start(ap, types);
2363 r = message_read_ap(m, types, ap);
2369 static int message_peek_fields(
2380 return buffer_peek(m->fields, BUS_MESSAGE_FIELDS_SIZE(m), rindex, align, nbytes, ret);
2383 static int message_peek_field_uint32(
2394 r = message_peek_fields(m, ri, 4, 4, &q);
2399 *ret = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2404 static int message_peek_field_string(
2406 bool (*validate)(const char *p),
2417 r = message_peek_field_uint32(m, ri, &l);
2421 r = message_peek_fields(m, ri, 1, l+1, &q);
2426 if (!validate_nul(q, l))
2432 if (!validate_string(q, l))
2442 static int message_peek_field_signature(
2454 r = message_peek_fields(m, ri, 1, 1, &q);
2459 r = message_peek_fields(m, ri, 1, l+1, &q);
2463 if (!validate_signature(q, l))
2472 static int message_skip_fields(
2475 uint32_t array_size,
2476 const char **signature) {
2478 size_t original_index;
2485 original_index = *ri;
2491 if (array_size != (uint32_t) -1 &&
2492 array_size <= *ri - original_index)
2499 if (t == SD_BUS_TYPE_STRING) {
2501 r = message_peek_field_string(m, NULL, ri, NULL);
2507 } else if (t == SD_BUS_TYPE_OBJECT_PATH) {
2509 r = message_peek_field_string(m, object_path_is_valid, ri, NULL);
2515 } else if (t == SD_BUS_TYPE_SIGNATURE) {
2517 r = message_peek_field_signature(m, ri, NULL);
2523 } else if (bus_type_is_basic(t)) {
2526 align = bus_type_get_alignment(t);
2527 k = bus_type_get_size(t);
2528 assert(align > 0 && k > 0);
2530 r = message_peek_fields(m, ri, align, k, NULL);
2536 } else if (t == SD_BUS_TYPE_ARRAY) {
2538 r = signature_element_length(*signature+1, &l);
2548 strncpy(sig, *signature + 1, l-1);
2551 alignment = bus_type_get_alignment(sig[0]);
2555 r = message_peek_field_uint32(m, ri, &nas);
2558 if (nas > BUS_ARRAY_MAX_SIZE)
2561 r = message_peek_fields(m, ri, alignment, 0, NULL);
2565 r = message_skip_fields(m, ri, nas, (const char**) &s);
2570 (*signature) += 1 + l;
2572 } else if (t == SD_BUS_TYPE_VARIANT) {
2575 r = message_peek_field_signature(m, ri, &s);
2579 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
2585 } else if (t == SD_BUS_TYPE_STRUCT ||
2586 t == SD_BUS_TYPE_DICT_ENTRY) {
2588 r = signature_element_length(*signature, &l);
2595 strncpy(sig, *signature + 1, l-1);
2598 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
2609 static int message_parse_fields(sd_bus_message *m) {
2612 uint32_t unix_fds = 0;
2616 for (ri = 0; ri < BUS_MESSAGE_FIELDS_SIZE(m); ) {
2617 const char *signature;
2620 r = message_peek_fields(m, &ri, 8, 1, (void**) &header);
2624 r = message_peek_field_signature(m, &ri, &signature);
2629 case _SD_BUS_MESSAGE_HEADER_INVALID:
2632 case SD_BUS_MESSAGE_HEADER_PATH:
2637 if (!streq(signature, "o"))
2640 r = message_peek_field_string(m, object_path_is_valid, &ri, &m->path);
2643 case SD_BUS_MESSAGE_HEADER_INTERFACE:
2648 if (!streq(signature, "s"))
2651 r = message_peek_field_string(m, interface_name_is_valid, &ri, &m->interface);
2654 case SD_BUS_MESSAGE_HEADER_MEMBER:
2659 if (!streq(signature, "s"))
2662 r = message_peek_field_string(m, member_name_is_valid, &ri, &m->member);
2665 case SD_BUS_MESSAGE_HEADER_ERROR_NAME:
2670 if (!streq(signature, "s"))
2673 r = message_peek_field_string(m, error_name_is_valid, &ri, &m->error.name);
2676 case SD_BUS_MESSAGE_HEADER_DESTINATION:
2681 if (!streq(signature, "s"))
2684 r = message_peek_field_string(m, service_name_is_valid, &ri, &m->destination);
2687 case SD_BUS_MESSAGE_HEADER_SENDER:
2692 if (!streq(signature, "s"))
2695 r = message_peek_field_string(m, service_name_is_valid, &ri, &m->sender);
2699 case SD_BUS_MESSAGE_HEADER_SIGNATURE: {
2703 if (m->root_container.signature)
2706 if (!streq(signature, "g"))
2709 r = message_peek_field_signature(m, &ri, &s);
2717 free(m->root_container.signature);
2718 m->root_container.signature = c;
2722 case SD_BUS_MESSAGE_HEADER_REPLY_SERIAL:
2723 if (m->reply_serial != 0)
2726 if (!streq(signature, "u"))
2729 r = message_peek_field_uint32(m, &ri, &m->reply_serial);
2733 if (m->reply_serial == 0)
2738 case SD_BUS_MESSAGE_HEADER_UNIX_FDS:
2742 if (!streq(signature, "u"))
2745 r = message_peek_field_uint32(m, &ri, &unix_fds);
2755 r = message_skip_fields(m, &ri, (uint32_t) -1, (const char **) &signature);
2762 if (m->n_fds != unix_fds)
2765 if (isempty(m->root_container.signature) != (BUS_MESSAGE_BODY_SIZE(m) == 0))
2768 switch (m->header->type) {
2770 case SD_BUS_MESSAGE_TYPE_SIGNAL:
2771 if (!m->path || !m->interface || !m->member)
2775 case SD_BUS_MESSAGE_TYPE_METHOD_CALL:
2777 if (!m->path || !m->member)
2782 case SD_BUS_MESSAGE_TYPE_METHOD_RETURN:
2784 if (m->reply_serial == 0)
2788 case SD_BUS_MESSAGE_TYPE_METHOD_ERROR:
2790 if (m->reply_serial == 0 || !m->error.name)
2795 /* Try to read the error message, but if we can't it's a non-issue */
2796 if (m->header->type == SD_BUS_MESSAGE_TYPE_METHOD_ERROR)
2797 sd_bus_message_read(m, "s", &m->error.message);
2802 static void setup_iovec(sd_bus_message *m) {
2809 m->iovec[m->n_iovec].iov_base = m->header;
2810 m->iovec[m->n_iovec].iov_len = sizeof(*m->header);
2811 m->size += m->iovec[m->n_iovec].iov_len;
2815 m->iovec[m->n_iovec].iov_base = m->fields;
2816 m->iovec[m->n_iovec].iov_len = m->header->fields_size;
2817 m->size += m->iovec[m->n_iovec].iov_len;
2820 if (m->header->fields_size % 8 != 0) {
2821 static const uint8_t padding[7] = { 0, 0, 0, 0, 0, 0, 0 };
2823 m->iovec[m->n_iovec].iov_base = (void*) padding;
2824 m->iovec[m->n_iovec].iov_len = 8 - m->header->fields_size % 8;
2825 m->size += m->iovec[m->n_iovec].iov_len;
2831 m->iovec[m->n_iovec].iov_base = m->body;
2832 m->iovec[m->n_iovec].iov_len = m->header->body_size;
2833 m->size += m->iovec[m->n_iovec].iov_len;
2838 int bus_message_seal(sd_bus_message *m, uint64_t serial) {
2846 if (m->n_containers > 0)
2849 /* If there's a non-trivial signature set, then add it in here */
2850 if (!isempty(m->root_container.signature)) {
2851 r = message_append_field_signature(m, SD_BUS_MESSAGE_HEADER_SIGNATURE, m->root_container.signature, NULL);
2857 r = message_append_field_uint32(m, SD_BUS_MESSAGE_HEADER_UNIX_FDS, m->n_fds);
2862 m->header->serial = serial;
2870 int sd_bus_message_set_destination(sd_bus_message *m, const char *destination) {
2880 return message_append_field_string(m, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &m->destination);
2883 int bus_message_dump(sd_bus_message *m) {
2889 printf("Message %p\n"
2896 "\tfields_size=%u\n"
2901 "\tdestination=%s\n"
2904 "\treply_serial=%u\n"
2906 "\terror.message=%s\n"
2914 BUS_MESSAGE_SERIAL(m),
2915 BUS_MESSAGE_FIELDS_SIZE(m),
2916 BUS_MESSAGE_BODY_SIZE(m),
2918 strna(m->interface),
2920 strna(m->destination),
2922 strna(m->root_container.signature),
2924 strna(m->error.name),
2925 strna(m->error.message),
2928 r = sd_bus_message_rewind(m, true);
2930 log_error("Failed to rewind: %s", strerror(-r));
2934 printf("BEGIN_MESSAGE \"%s\" {\n", strempty(m->root_container.signature));
2937 _cleanup_free_ char *prefix = NULL;
2938 const char *contents = NULL;
2953 r = sd_bus_message_peek_type(m, &type, &contents);
2955 log_error("Failed to peek type: %s", strerror(-r));
2962 r = sd_bus_message_exit_container(m);
2964 log_error("Failed to exit container: %s", strerror(-r));
2970 prefix = strrep("\t", level);
2974 if (type == SD_BUS_TYPE_ARRAY)
2975 printf("%s} END_ARRAY \n", prefix);
2976 else if (type == SD_BUS_TYPE_VARIANT)
2977 printf("%s} END_VARIANT\n", prefix);
2978 else if (type == SD_BUS_TYPE_STRUCT)
2979 printf("%s} END_STRUCT\n", prefix);
2980 else if (type == SD_BUS_TYPE_DICT_ENTRY)
2981 printf("%s} END_DICT_ENTRY\n", prefix);
2986 prefix = strrep("\t", level);
2990 if (bus_type_is_container(type) > 0) {
2991 r = sd_bus_message_enter_container(m, type, contents);
2993 log_error("Failed to enter container: %s", strerror(-r));
2997 if (type == SD_BUS_TYPE_ARRAY)
2998 printf("%sBEGIN_ARRAY \"%s\" {\n", prefix, contents);
2999 else if (type == SD_BUS_TYPE_VARIANT)
3000 printf("%sBEGIN_VARIANT \"%s\" {\n", prefix, contents);
3001 else if (type == SD_BUS_TYPE_STRUCT)
3002 printf("%sBEGIN_STRUCT \"%s\" {\n", prefix, contents);
3003 else if (type == SD_BUS_TYPE_DICT_ENTRY)
3004 printf("%sBEGIN_DICT_ENTRY \"%s\" {\n", prefix, contents);
3011 r = sd_bus_message_read_basic(m, type, &basic);
3013 log_error("Failed to get basic: %s", strerror(-r));
3019 case SD_BUS_TYPE_BYTE:
3020 printf("%sBYTE: %u\n", prefix, basic.u8);
3023 case SD_BUS_TYPE_BOOLEAN:
3024 printf("%sBOOLEAN: %s\n", prefix, yes_no(basic.i));
3027 case SD_BUS_TYPE_INT16:
3028 printf("%sINT16: %i\n", prefix, basic.s16);
3031 case SD_BUS_TYPE_UINT16:
3032 printf("%sUINT16: %u\n", prefix, basic.u16);
3035 case SD_BUS_TYPE_INT32:
3036 printf("%sINT32: %i\n", prefix, basic.s32);
3039 case SD_BUS_TYPE_UINT32:
3040 printf("%sUINT32: %u\n", prefix, basic.u32);
3043 case SD_BUS_TYPE_INT64:
3044 printf("%sINT64: %lli\n", prefix, (long long) basic.s64);
3047 case SD_BUS_TYPE_UINT64:
3048 printf("%sUINT64: %llu\n", prefix, (unsigned long long) basic.u64);
3051 case SD_BUS_TYPE_DOUBLE:
3052 printf("%sDOUBLE: %g\n", prefix, basic.d64);
3055 case SD_BUS_TYPE_STRING:
3056 printf("%sSTRING: \"%s\"\n", prefix, basic.string);
3059 case SD_BUS_TYPE_OBJECT_PATH:
3060 printf("%sOBJECT_PATH: \"%s\"\n", prefix, basic.string);
3063 case SD_BUS_TYPE_SIGNATURE:
3064 printf("%sSIGNATURE: \"%s\"\n", prefix, basic.string);
3067 case SD_BUS_TYPE_UNIX_FD:
3068 printf("%sUNIX_FD: %i\n", prefix, basic.i);
3072 assert_not_reached("Unknown basic type.");
3076 printf("} END_MESSAGE\n");
3080 int bus_message_get_blob(sd_bus_message *m, void **buffer, size_t *sz) {
3089 for (i = 0, total = 0; i < m->n_iovec; i++)
3090 total += m->iovec[i].iov_len;
3096 for (i = 0, e = p; i < m->n_iovec; i++)
3097 e = mempcpy(e, m->iovec[i].iov_base, m->iovec[i].iov_len);
3105 int bus_message_read_strv_extend(sd_bus_message *m, char ***l) {
3111 r = sd_bus_message_enter_container(m, 'a', "s");
3118 r = sd_bus_message_read_basic(m, 's', &s);
3124 r = strv_extend(l, s);
3129 r = sd_bus_message_exit_container(m);
3136 const char* bus_message_get_arg(sd_bus_message *m, unsigned i) {
3143 r = sd_bus_message_rewind(m, true);
3148 r = sd_bus_message_peek_type(m, &type, NULL);
3152 if (type != SD_BUS_TYPE_STRING &&
3153 type != SD_BUS_TYPE_OBJECT_PATH &&
3154 type != SD_BUS_TYPE_SIGNATURE)
3157 r = sd_bus_message_read_basic(m, type, &t);
3164 r = sd_bus_message_rewind(m, true);