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_label(sd_bus_message *m) {
712 int sd_bus_message_get_timestamp(sd_bus_message *m, uint64_t *usec) {
716 if (m->timestamp <= 0)
719 *usec = m->timestamp;
723 int sd_bus_message_is_signal(sd_bus_message *m, const char *interface, const char *member) {
727 if (m->header->type != SD_BUS_MESSAGE_TYPE_SIGNAL)
730 if (interface && (!m->interface || !streq(m->interface, interface)))
733 if (member && (!m->member || !streq(m->member, member)))
739 int sd_bus_message_is_method_call(sd_bus_message *m, const char *interface, const char *member) {
743 if (m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_CALL)
746 if (interface && (!m->interface || !streq(m->interface, interface)))
749 if (member && (!m->member || !streq(m->member, member)))
755 int sd_bus_message_is_method_error(sd_bus_message *m, const char *name) {
759 if (m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_ERROR)
762 if (name && (!m->error.name || !streq(m->error.name, name)))
768 int sd_bus_message_set_no_reply(sd_bus_message *m, int b) {
773 if (m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_CALL)
777 m->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
779 m->header->flags &= ~SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
784 static struct bus_container *message_get_container(sd_bus_message *m) {
787 if (m->n_containers == 0)
788 return &m->root_container;
790 assert(m->containers);
791 return m->containers + m->n_containers - 1;
794 static void *message_extend_body(sd_bus_message *m, size_t align, size_t sz) {
797 struct bus_container *c;
803 added = m->header->body_size;
805 p = buffer_extend(&m->body, &m->header->body_size, align, sz);
809 added = m->header->body_size - added;
811 for (c = m->containers; c < m->containers + m->n_containers; c++)
813 c->array_size = (uint32_t*) ((uint8_t*) m->body + ((uint8_t*) c->array_size - (uint8_t*) o));
814 *c->array_size += added;
818 if (m->error.message)
819 m->error.message = (const char*) m->body + (m->error.message - (const char*) o);
827 int message_append_basic(sd_bus_message *m, char type, const void *p, const void **stored) {
828 struct bus_container *c;
843 if (!bus_type_is_basic(type))
846 c = message_get_container(m);
848 if (c->signature && c->signature[c->index]) {
849 /* Container signature is already set */
851 if (c->signature[c->index] != type)
854 /* Maybe we can append to the signature? But only if this is the top-level container*/
855 if (c->enclosing != 0)
858 e = strextend(&c->signature, CHAR_TO_STR(type), NULL);
865 case SD_BUS_TYPE_STRING:
866 case SD_BUS_TYPE_OBJECT_PATH:
869 sz = 4 + strlen(p) + 1;
872 case SD_BUS_TYPE_SIGNATURE:
875 sz = 1 + strlen(p) + 1;
878 case SD_BUS_TYPE_BOOLEAN:
881 assert_cc(sizeof(int) == sizeof(uint32_t));
887 case SD_BUS_TYPE_UNIX_FD: {
903 fd = fcntl(z, F_DUPFD_CLOEXEC, 3);
909 f = realloc(m->fds, sizeof(int) * (m->n_fds + 1));
923 align = bus_type_get_alignment(type);
924 sz = bus_type_get_size(type);
931 a = message_extend_body(m, align, sz);
937 if (type == SD_BUS_TYPE_STRING || type == SD_BUS_TYPE_OBJECT_PATH) {
938 *(uint32_t*) a = sz - 5;
939 memcpy((uint8_t*) a + 4, p, sz - 4);
942 *stored = (const uint8_t*) a + 4;
944 } else if (type == SD_BUS_TYPE_SIGNATURE) {
945 *(uint8_t*) a = sz - 1;
946 memcpy((uint8_t*) a + 1, p, sz - 1);
949 *stored = (const uint8_t*) a + 1;
950 } else if (type == SD_BUS_TYPE_UNIX_FD) {
951 *(uint32_t*) a = fdi;
965 if (c->enclosing != SD_BUS_TYPE_ARRAY)
971 /* Truncate extended signature again */
973 c->signature[c->index] = 0;
976 close_nointr_nofail(fd);
981 int sd_bus_message_append_basic(sd_bus_message *m, char type, const void *p) {
982 return message_append_basic(m, type, p, NULL);
985 static int bus_message_open_array(
987 struct bus_container *c,
988 const char *contents,
989 uint32_t **array_size) {
1002 if (!signature_is_single(contents))
1005 alignment = bus_type_get_alignment(contents[0]);
1009 if (c->signature && c->signature[c->index]) {
1011 /* Verify the existing signature */
1013 if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
1016 if (!startswith(c->signature + c->index + 1, contents))
1019 nindex = c->index + 1 + strlen(contents);
1021 if (c->enclosing != 0)
1024 /* Extend the existing signature */
1026 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_ARRAY), contents, NULL);
1030 nindex = e - c->signature;
1033 saved = m->header->body_size;
1034 a = message_extend_body(m, 4, 4);
1036 /* Truncate extended signature again */
1038 c->signature[c->index] = 0;
1044 if (!message_extend_body(m, alignment, 0)) {
1045 /* Add alignment between size and first element */
1047 c->signature[c->index] = 0;
1049 m->header->body_size = saved;
1053 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1056 /* m->body might have changed so let's readjust a */
1057 a = (uint8_t*) m->body + ((uint8_t*) a - (uint8_t*) b);
1064 static int bus_message_open_variant(
1066 struct bus_container *c,
1067 const char *contents) {
1077 if (!signature_is_single(contents))
1080 if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
1083 if (c->signature && c->signature[c->index]) {
1085 if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
1089 if (c->enclosing != 0)
1092 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_VARIANT), NULL);
1097 l = strlen(contents);
1098 a = message_extend_body(m, 1, 1 + l + 1);
1100 /* Truncate extended signature again */
1102 c->signature[c->index] = 0;
1108 memcpy((uint8_t*) a + 1, contents, l + 1);
1110 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1116 static int bus_message_open_struct(
1118 struct bus_container *c,
1119 const char *contents) {
1128 if (!signature_is_valid(contents, false))
1131 if (c->signature && c->signature[c->index]) {
1134 l = strlen(contents);
1136 if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
1137 !startswith(c->signature + c->index + 1, contents) ||
1138 c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
1141 nindex = c->index + 1 + l + 1;
1143 if (c->enclosing != 0)
1146 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_BEGIN), contents, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_END), NULL);
1150 nindex = e - c->signature;
1153 /* Align contents to 8 byte boundary */
1154 if (!message_extend_body(m, 8, 0)) {
1156 c->signature[c->index] = 0;
1161 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1167 static int bus_message_open_dict_entry(
1169 struct bus_container *c,
1170 const char *contents) {
1178 if (!signature_is_pair(contents))
1181 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1184 if (c->signature && c->signature[c->index]) {
1187 l = strlen(contents);
1189 if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
1190 !startswith(c->signature + c->index + 1, contents) ||
1191 c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
1194 nindex = c->index + 1 + l + 1;
1198 /* Align contents to 8 byte boundary */
1199 if (!message_extend_body(m, 8, 0))
1202 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1208 int sd_bus_message_open_container(
1211 const char *contents) {
1213 struct bus_container *c, *w;
1214 uint32_t *array_size = NULL;
1225 /* Make sure we have space for one more container */
1226 w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
1231 c = message_get_container(m);
1233 signature = strdup(contents);
1237 if (type == SD_BUS_TYPE_ARRAY)
1238 r = bus_message_open_array(m, c, contents, &array_size);
1239 else if (type == SD_BUS_TYPE_VARIANT)
1240 r = bus_message_open_variant(m, c, contents);
1241 else if (type == SD_BUS_TYPE_STRUCT)
1242 r = bus_message_open_struct(m, c, contents);
1243 else if (type == SD_BUS_TYPE_DICT_ENTRY)
1244 r = bus_message_open_dict_entry(m, c, contents);
1253 /* OK, let's fill it in */
1254 w += m->n_containers++;
1255 w->enclosing = type;
1256 w->signature = signature;
1258 w->array_size = array_size;
1264 int sd_bus_message_close_container(sd_bus_message *m) {
1265 struct bus_container *c;
1271 if (m->n_containers <= 0)
1274 c = message_get_container(m);
1275 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1276 if (c->signature && c->signature[c->index] != 0)
1292 static int type_stack_push(TypeStack *stack, unsigned max, unsigned *i, const char *types, unsigned n_struct, unsigned n_array) {
1299 stack[*i].types = types;
1300 stack[*i].n_struct = n_struct;
1301 stack[*i].n_array = n_array;
1307 static int type_stack_pop(TypeStack *stack, unsigned max, unsigned *i, const char **types, unsigned *n_struct, unsigned *n_array) {
1318 *types = stack[*i].types;
1319 *n_struct = stack[*i].n_struct;
1320 *n_array = stack[*i].n_array;
1325 int bus_message_append_ap(
1330 unsigned n_array, n_struct;
1331 TypeStack stack[BUS_CONTAINER_DEPTH];
1332 unsigned stack_ptr = 0;
1340 n_array = (unsigned) -1;
1341 n_struct = strlen(types);
1346 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
1347 r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
1353 r = sd_bus_message_close_container(m);
1361 if (n_array != (unsigned) -1)
1370 case SD_BUS_TYPE_BYTE: {
1373 x = (uint8_t) va_arg(ap, int);
1374 r = sd_bus_message_append_basic(m, *t, &x);
1378 case SD_BUS_TYPE_BOOLEAN:
1379 case SD_BUS_TYPE_INT32:
1380 case SD_BUS_TYPE_UINT32:
1381 case SD_BUS_TYPE_UNIX_FD: {
1384 /* We assume a boolean is the same as int32_t */
1385 assert_cc(sizeof(int32_t) == sizeof(int));
1387 x = va_arg(ap, uint32_t);
1388 r = sd_bus_message_append_basic(m, *t, &x);
1392 case SD_BUS_TYPE_INT16:
1393 case SD_BUS_TYPE_UINT16: {
1396 x = (uint16_t) va_arg(ap, int);
1397 r = sd_bus_message_append_basic(m, *t, &x);
1401 case SD_BUS_TYPE_INT64:
1402 case SD_BUS_TYPE_UINT64:
1403 case SD_BUS_TYPE_DOUBLE: {
1406 x = va_arg(ap, uint64_t);
1407 r = sd_bus_message_append_basic(m, *t, &x);
1411 case SD_BUS_TYPE_STRING:
1412 case SD_BUS_TYPE_OBJECT_PATH:
1413 case SD_BUS_TYPE_SIGNATURE: {
1416 x = va_arg(ap, const char*);
1417 r = sd_bus_message_append_basic(m, *t, x);
1421 case SD_BUS_TYPE_ARRAY: {
1424 r = signature_element_length(t + 1, &k);
1430 memcpy(s, t + 1, k);
1433 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, s);
1438 if (n_array == (unsigned) -1) {
1443 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
1449 n_array = va_arg(ap, unsigned);
1454 case SD_BUS_TYPE_VARIANT: {
1457 s = va_arg(ap, const char*);
1461 r = sd_bus_message_open_container(m, SD_BUS_TYPE_VARIANT, s);
1465 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
1470 n_struct = strlen(s);
1471 n_array = (unsigned) -1;
1476 case SD_BUS_TYPE_STRUCT_BEGIN:
1477 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
1480 r = signature_element_length(t, &k);
1487 memcpy(s, t + 1, k - 2);
1490 r = sd_bus_message_open_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
1495 if (n_array == (unsigned) -1) {
1500 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
1506 n_array = (unsigned) -1;
1522 int sd_bus_message_append(sd_bus_message *m, const char *types, ...) {
1533 va_start(ap, types);
1534 r = bus_message_append_ap(m, types, ap);
1540 static int buffer_peek(const void *p, uint32_t sz, size_t *rindex, size_t align, size_t nbytes, void **r) {
1546 start = ALIGN_TO((size_t) *rindex, align);
1552 /* Verify that padding is 0 */
1553 for (k = *rindex; k < start; k++)
1554 if (((const uint8_t*) p)[k] != 0)
1558 *r = (uint8_t*) p + start;
1565 static bool message_end_of_array(sd_bus_message *m, size_t index) {
1566 struct bus_container *c;
1570 c = message_get_container(m);
1574 return index >= c->begin + BUS_MESSAGE_BSWAP32(m, *c->array_size);
1577 static int message_peek_body(sd_bus_message *m, size_t *rindex, size_t align, size_t nbytes, void **ret) {
1582 if (message_end_of_array(m, *rindex))
1585 return buffer_peek(m->body, BUS_MESSAGE_BODY_SIZE(m), rindex, align, nbytes, ret);
1588 static bool validate_nul(const char *s, size_t l) {
1590 /* Check for NUL chars in the string */
1591 if (memchr(s, 0, l))
1594 /* Check for NUL termination */
1601 static bool validate_string(const char *s, size_t l) {
1603 if (!validate_nul(s, l))
1606 /* Check if valid UTF8 */
1607 if (!utf8_is_valid(s))
1613 static bool validate_signature(const char *s, size_t l) {
1615 if (!validate_nul(s, l))
1618 /* Check if valid signature */
1619 if (!signature_is_valid(s, true))
1625 static bool validate_object_path(const char *s, size_t l) {
1627 if (!validate_nul(s, l))
1630 if (!object_path_is_valid(s))
1636 int sd_bus_message_read_basic(sd_bus_message *m, char type, void *p) {
1637 struct bus_container *c;
1645 if (!bus_type_is_basic(type))
1650 c = message_get_container(m);
1652 if (!c->signature || c->signature[c->index] == 0)
1655 if (c->signature[c->index] != type)
1660 case SD_BUS_TYPE_STRING:
1661 case SD_BUS_TYPE_OBJECT_PATH: {
1666 r = message_peek_body(m, &rindex, 4, 4, &q);
1670 l = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
1671 r = message_peek_body(m, &rindex, 1, l+1, &q);
1677 if (type == SD_BUS_TYPE_OBJECT_PATH) {
1678 if (!validate_object_path(q, l))
1681 if (!validate_string(q, l))
1686 *(const char**) p = q;
1690 case SD_BUS_TYPE_SIGNATURE: {
1695 r = message_peek_body(m, &rindex, 1, 1, &q);
1700 r = message_peek_body(m, &rindex, 1, l+1, &q);
1706 if (!validate_signature(q, l))
1710 *(const char**) p = q;
1718 align = bus_type_get_alignment(type);
1719 sz = bus_type_get_size(type);
1720 assert(align > 0 && sz > 0);
1723 r = message_peek_body(m, &rindex, align, sz, &q);
1729 case SD_BUS_TYPE_BYTE:
1730 *(uint8_t*) p = *(uint8_t*) q;
1733 case SD_BUS_TYPE_BOOLEAN:
1734 *(int*) p = !!*(uint32_t*) q;
1737 case SD_BUS_TYPE_INT16:
1738 case SD_BUS_TYPE_UINT16:
1739 *(uint16_t*) p = BUS_MESSAGE_BSWAP16(m, *(uint16_t*) q);
1742 case SD_BUS_TYPE_INT32:
1743 case SD_BUS_TYPE_UINT32:
1744 *(uint32_t*) p = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
1747 case SD_BUS_TYPE_INT64:
1748 case SD_BUS_TYPE_UINT64:
1749 case SD_BUS_TYPE_DOUBLE:
1750 *(uint64_t*) p = BUS_MESSAGE_BSWAP64(m, *(uint64_t*) q);
1753 case SD_BUS_TYPE_UNIX_FD: {
1756 j = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
1760 *(int*) p = m->fds[j];
1765 assert_not_reached("Unknown basic type...");
1774 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1780 static int bus_message_enter_array(
1782 struct bus_container *c,
1783 const char *contents,
1784 uint32_t **array_size) {
1795 if (!signature_is_single(contents))
1798 alignment = bus_type_get_alignment(contents[0]);
1802 if (!c->signature || c->signature[c->index] == 0)
1805 if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
1808 if (!startswith(c->signature + c->index + 1, contents))
1812 r = message_peek_body(m, &rindex, 4, 4, &q);
1816 if (BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q) > BUS_ARRAY_MAX_SIZE)
1819 r = message_peek_body(m, &rindex, alignment, 0, NULL);
1825 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1826 c->index += 1 + strlen(contents);
1830 *array_size = (uint32_t*) q;
1835 static int bus_message_enter_variant(
1837 struct bus_container *c,
1838 const char *contents) {
1849 if (!signature_is_single(contents))
1852 if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
1855 if (!c->signature || c->signature[c->index] == 0)
1858 if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
1862 r = message_peek_body(m, &rindex, 1, 1, &q);
1867 r = message_peek_body(m, &rindex, 1, l+1, &q);
1873 if (!validate_signature(q, l))
1876 if (!streq(q, contents))
1879 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1887 static int bus_message_enter_struct(
1889 struct bus_container *c,
1890 const char *contents) {
1899 if (!signature_is_valid(contents, false))
1902 if (!c->signature || c->signature[c->index] == 0)
1905 l = strlen(contents);
1907 if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
1908 !startswith(c->signature + c->index + 1, contents) ||
1909 c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
1912 r = message_peek_body(m, &m->rindex, 8, 0, NULL);
1916 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1917 c->index += 1 + l + 1;
1922 static int bus_message_enter_dict_entry(
1924 struct bus_container *c,
1925 const char *contents) {
1934 if (!signature_is_pair(contents))
1937 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1940 if (!c->signature || c->signature[c->index] == 0)
1943 l = strlen(contents);
1945 if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
1946 !startswith(c->signature + c->index + 1, contents) ||
1947 c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
1950 r = message_peek_body(m, &m->rindex, 8, 0, NULL);
1954 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1955 c->index += 1 + l + 1;
1960 int sd_bus_message_enter_container(sd_bus_message *m, char type, const char *contents) {
1961 struct bus_container *c, *w;
1962 uint32_t *array_size = NULL;
1974 * We enforce a global limit on container depth, that is much
1975 * higher than the 32 structs and 32 arrays the specification
1976 * mandates. This is simpler to implement for us, and we need
1977 * this only to ensure our container array doesn't grow
1978 * without bounds. We are happy to return any data from a
1979 * message as long as the data itself is valid, even if the
1980 * overall message might be not.
1982 * Note that the message signature is validated when
1983 * parsing the headers, and that validation does check the
1986 * Note that the specification defines no limits on the depth
1987 * of stacked variants, but we do.
1989 if (m->n_containers >= BUS_CONTAINER_DEPTH)
1992 w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
1997 c = message_get_container(m);
1999 if (!c->signature || c->signature[c->index] == 0)
2002 signature = strdup(contents);
2006 if (type == SD_BUS_TYPE_ARRAY)
2007 r = bus_message_enter_array(m, c, contents, &array_size);
2008 else if (type == SD_BUS_TYPE_VARIANT)
2009 r = bus_message_enter_variant(m, c, contents);
2010 else if (type == SD_BUS_TYPE_STRUCT)
2011 r = bus_message_enter_struct(m, c, contents);
2012 else if (type == SD_BUS_TYPE_DICT_ENTRY)
2013 r = bus_message_enter_dict_entry(m, c, contents);
2022 /* OK, let's fill it in */
2023 w += m->n_containers++;
2024 w->enclosing = type;
2025 w->signature = signature;
2027 w->array_size = array_size;
2028 w->begin = m->rindex;
2033 int sd_bus_message_exit_container(sd_bus_message *m) {
2034 struct bus_container *c;
2040 if (m->n_containers <= 0)
2043 c = message_get_container(m);
2044 if (c->enclosing == SD_BUS_TYPE_ARRAY) {
2047 l = BUS_MESSAGE_BSWAP32(m, *c->array_size);
2048 if (c->begin + l != m->rindex)
2052 if (c->signature && c->signature[c->index] != 0)
2062 int sd_bus_message_peek_type(sd_bus_message *m, char *type, const char **contents) {
2063 struct bus_container *c;
2071 c = message_get_container(m);
2073 if (!c->signature || c->signature[c->index] == 0)
2076 if (message_end_of_array(m, m->rindex))
2079 if (bus_type_is_basic(c->signature[c->index])) {
2083 *type = c->signature[c->index];
2087 if (c->signature[c->index] == SD_BUS_TYPE_ARRAY) {
2093 r = signature_element_length(c->signature+c->index+1, &l);
2099 sig = strndup(c->signature + c->index + 1, l);
2103 free(m->peeked_signature);
2104 m->peeked_signature = sig;
2110 *type = SD_BUS_TYPE_ARRAY;
2115 if (c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ||
2116 c->signature[c->index] == SD_BUS_TYPE_DICT_ENTRY_BEGIN) {
2122 r = signature_element_length(c->signature+c->index, &l);
2127 sig = strndup(c->signature + c->index + 1, l - 2);
2131 free(m->peeked_signature);
2132 m->peeked_signature = sig;
2138 *type = c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY;
2143 if (c->signature[c->index] == SD_BUS_TYPE_VARIANT) {
2149 r = message_peek_body(m, &rindex, 1, 1, &q);
2156 r = message_peek_body(m, &rindex, 1, l+1, &q);
2162 if (!validate_signature(q, l))
2169 *type = SD_BUS_TYPE_VARIANT;
2178 *type = c->enclosing;
2184 int sd_bus_message_rewind(sd_bus_message *m, int complete) {
2185 struct bus_container *c;
2193 reset_containers(m);
2195 m->root_container.index = 0;
2197 c = message_get_container(m);
2199 c = message_get_container(m);
2202 m->rindex = c->begin;
2205 return !isempty(c->signature);
2207 static int message_read_ap(
2212 unsigned n_array, n_struct;
2213 TypeStack stack[BUS_CONTAINER_DEPTH];
2214 unsigned stack_ptr = 0;
2222 /* Ideally, we'd just call ourselves recursively on every
2223 * complex type. However, the state of a va_list that is
2224 * passed to a function is undefined after that function
2225 * returns. This means we need to docode the va_list linearly
2226 * in a single stackframe. We hence implement our own
2227 * home-grown stack in an array. */
2229 n_array = (unsigned) -1;
2230 n_struct = strlen(types);
2235 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
2236 r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
2242 r = sd_bus_message_exit_container(m);
2250 if (n_array != (unsigned) -1)
2259 case SD_BUS_TYPE_BYTE:
2260 case SD_BUS_TYPE_BOOLEAN:
2261 case SD_BUS_TYPE_INT16:
2262 case SD_BUS_TYPE_UINT16:
2263 case SD_BUS_TYPE_INT32:
2264 case SD_BUS_TYPE_UINT32:
2265 case SD_BUS_TYPE_INT64:
2266 case SD_BUS_TYPE_UINT64:
2267 case SD_BUS_TYPE_DOUBLE:
2268 case SD_BUS_TYPE_STRING:
2269 case SD_BUS_TYPE_OBJECT_PATH:
2270 case SD_BUS_TYPE_SIGNATURE:
2271 case SD_BUS_TYPE_UNIX_FD: {
2274 p = va_arg(ap, void*);
2275 r = sd_bus_message_read_basic(m, *t, p);
2284 case SD_BUS_TYPE_ARRAY: {
2287 r = signature_element_length(t + 1, &k);
2293 memcpy(s, t + 1, k);
2296 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, s);
2303 if (n_array == (unsigned) -1) {
2308 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2314 n_array = va_arg(ap, unsigned);
2319 case SD_BUS_TYPE_VARIANT: {
2322 s = va_arg(ap, const char *);
2326 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, s);
2332 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2337 n_struct = strlen(s);
2338 n_array = (unsigned) -1;
2343 case SD_BUS_TYPE_STRUCT_BEGIN:
2344 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
2347 r = signature_element_length(t, &k);
2353 memcpy(s, t + 1, k - 2);
2356 r = sd_bus_message_enter_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
2363 if (n_array == (unsigned) -1) {
2368 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2374 n_array = (unsigned) -1;
2387 int sd_bus_message_read(sd_bus_message *m, const char *types, ...) {
2398 va_start(ap, types);
2399 r = message_read_ap(m, types, ap);
2405 static int message_peek_fields(
2416 return buffer_peek(m->fields, BUS_MESSAGE_FIELDS_SIZE(m), rindex, align, nbytes, ret);
2419 static int message_peek_field_uint32(
2430 r = message_peek_fields(m, ri, 4, 4, &q);
2435 *ret = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2440 static int message_peek_field_string(
2442 bool (*validate)(const char *p),
2453 r = message_peek_field_uint32(m, ri, &l);
2457 r = message_peek_fields(m, ri, 1, l+1, &q);
2462 if (!validate_nul(q, l))
2468 if (!validate_string(q, l))
2478 static int message_peek_field_signature(
2490 r = message_peek_fields(m, ri, 1, 1, &q);
2495 r = message_peek_fields(m, ri, 1, l+1, &q);
2499 if (!validate_signature(q, l))
2508 static int message_skip_fields(
2511 uint32_t array_size,
2512 const char **signature) {
2514 size_t original_index;
2521 original_index = *ri;
2527 if (array_size != (uint32_t) -1 &&
2528 array_size <= *ri - original_index)
2535 if (t == SD_BUS_TYPE_STRING) {
2537 r = message_peek_field_string(m, NULL, ri, NULL);
2543 } else if (t == SD_BUS_TYPE_OBJECT_PATH) {
2545 r = message_peek_field_string(m, object_path_is_valid, ri, NULL);
2551 } else if (t == SD_BUS_TYPE_SIGNATURE) {
2553 r = message_peek_field_signature(m, ri, NULL);
2559 } else if (bus_type_is_basic(t)) {
2562 align = bus_type_get_alignment(t);
2563 k = bus_type_get_size(t);
2564 assert(align > 0 && k > 0);
2566 r = message_peek_fields(m, ri, align, k, NULL);
2572 } else if (t == SD_BUS_TYPE_ARRAY) {
2574 r = signature_element_length(*signature+1, &l);
2584 strncpy(sig, *signature + 1, l-1);
2587 alignment = bus_type_get_alignment(sig[0]);
2591 r = message_peek_field_uint32(m, ri, &nas);
2594 if (nas > BUS_ARRAY_MAX_SIZE)
2597 r = message_peek_fields(m, ri, alignment, 0, NULL);
2601 r = message_skip_fields(m, ri, nas, (const char**) &s);
2606 (*signature) += 1 + l;
2608 } else if (t == SD_BUS_TYPE_VARIANT) {
2611 r = message_peek_field_signature(m, ri, &s);
2615 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
2621 } else if (t == SD_BUS_TYPE_STRUCT ||
2622 t == SD_BUS_TYPE_DICT_ENTRY) {
2624 r = signature_element_length(*signature, &l);
2631 strncpy(sig, *signature + 1, l-1);
2634 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
2645 int bus_message_parse_fields(sd_bus_message *m) {
2648 uint32_t unix_fds = 0;
2652 for (ri = 0; ri < BUS_MESSAGE_FIELDS_SIZE(m); ) {
2653 const char *signature;
2656 r = message_peek_fields(m, &ri, 8, 1, (void**) &header);
2660 r = message_peek_field_signature(m, &ri, &signature);
2665 case _SD_BUS_MESSAGE_HEADER_INVALID:
2668 case SD_BUS_MESSAGE_HEADER_PATH:
2673 if (!streq(signature, "o"))
2676 r = message_peek_field_string(m, object_path_is_valid, &ri, &m->path);
2679 case SD_BUS_MESSAGE_HEADER_INTERFACE:
2684 if (!streq(signature, "s"))
2687 r = message_peek_field_string(m, interface_name_is_valid, &ri, &m->interface);
2690 case SD_BUS_MESSAGE_HEADER_MEMBER:
2695 if (!streq(signature, "s"))
2698 r = message_peek_field_string(m, member_name_is_valid, &ri, &m->member);
2701 case SD_BUS_MESSAGE_HEADER_ERROR_NAME:
2706 if (!streq(signature, "s"))
2709 r = message_peek_field_string(m, error_name_is_valid, &ri, &m->error.name);
2712 case SD_BUS_MESSAGE_HEADER_DESTINATION:
2717 if (!streq(signature, "s"))
2720 r = message_peek_field_string(m, service_name_is_valid, &ri, &m->destination);
2723 case SD_BUS_MESSAGE_HEADER_SENDER:
2728 if (!streq(signature, "s"))
2731 r = message_peek_field_string(m, service_name_is_valid, &ri, &m->sender);
2735 case SD_BUS_MESSAGE_HEADER_SIGNATURE: {
2739 if (m->root_container.signature)
2742 if (!streq(signature, "g"))
2745 r = message_peek_field_signature(m, &ri, &s);
2753 free(m->root_container.signature);
2754 m->root_container.signature = c;
2758 case SD_BUS_MESSAGE_HEADER_REPLY_SERIAL:
2759 if (m->reply_serial != 0)
2762 if (!streq(signature, "u"))
2765 r = message_peek_field_uint32(m, &ri, &m->reply_serial);
2769 if (m->reply_serial == 0)
2774 case SD_BUS_MESSAGE_HEADER_UNIX_FDS:
2778 if (!streq(signature, "u"))
2781 r = message_peek_field_uint32(m, &ri, &unix_fds);
2791 r = message_skip_fields(m, &ri, (uint32_t) -1, (const char **) &signature);
2798 if (m->n_fds != unix_fds)
2801 if (isempty(m->root_container.signature) != (BUS_MESSAGE_BODY_SIZE(m) == 0))
2804 switch (m->header->type) {
2806 case SD_BUS_MESSAGE_TYPE_SIGNAL:
2807 if (!m->path || !m->interface || !m->member)
2811 case SD_BUS_MESSAGE_TYPE_METHOD_CALL:
2813 if (!m->path || !m->member)
2818 case SD_BUS_MESSAGE_TYPE_METHOD_RETURN:
2820 if (m->reply_serial == 0)
2824 case SD_BUS_MESSAGE_TYPE_METHOD_ERROR:
2826 if (m->reply_serial == 0 || !m->error.name)
2831 /* Try to read the error message, but if we can't it's a non-issue */
2832 if (m->header->type == SD_BUS_MESSAGE_TYPE_METHOD_ERROR)
2833 sd_bus_message_read(m, "s", &m->error.message);
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;
2868 int sd_bus_message_set_destination(sd_bus_message *m, const char *destination) {
2878 return message_append_field_string(m, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &m->destination);
2881 int bus_message_dump(sd_bus_message *m) {
2887 printf("Message %p\n"
2894 "\tfields_size=%u\n"
2899 "\tdestination=%s\n"
2902 "\treply_serial=%u\n"
2904 "\terror.message=%s\n"
2912 BUS_MESSAGE_SERIAL(m),
2913 BUS_MESSAGE_FIELDS_SIZE(m),
2914 BUS_MESSAGE_BODY_SIZE(m),
2916 strna(m->interface),
2918 strna(m->destination),
2920 strna(m->root_container.signature),
2922 strna(m->error.name),
2923 strna(m->error.message),
2927 printf("\tpid=%lu\n", (unsigned long) m->pid);
2929 printf("\ttid=%lu\n", (unsigned long) m->tid);
2931 printf("\tuid=%lu\n", (unsigned long) m->uid);
2933 printf("\tgid=%lu\n", (unsigned long) m->gid);
2934 if (m->pid_starttime != 0)
2935 printf("\tpid_starttime=%llu\n", (unsigned long long) m->pid_starttime);
2937 printf("\ttimestamp=%llu\n", (unsigned long long) m->timestamp);
2939 r = sd_bus_message_rewind(m, true);
2941 log_error("Failed to rewind: %s", strerror(-r));
2945 printf("BEGIN_MESSAGE \"%s\" {\n", strempty(m->root_container.signature));
2948 _cleanup_free_ char *prefix = NULL;
2949 const char *contents = NULL;
2964 r = sd_bus_message_peek_type(m, &type, &contents);
2966 log_error("Failed to peek type: %s", strerror(-r));
2973 r = sd_bus_message_exit_container(m);
2975 log_error("Failed to exit container: %s", strerror(-r));
2981 prefix = strrep("\t", level);
2985 if (type == SD_BUS_TYPE_ARRAY)
2986 printf("%s} END_ARRAY \n", prefix);
2987 else if (type == SD_BUS_TYPE_VARIANT)
2988 printf("%s} END_VARIANT\n", prefix);
2989 else if (type == SD_BUS_TYPE_STRUCT)
2990 printf("%s} END_STRUCT\n", prefix);
2991 else if (type == SD_BUS_TYPE_DICT_ENTRY)
2992 printf("%s} END_DICT_ENTRY\n", prefix);
2997 prefix = strrep("\t", level);
3001 if (bus_type_is_container(type) > 0) {
3002 r = sd_bus_message_enter_container(m, type, contents);
3004 log_error("Failed to enter container: %s", strerror(-r));
3008 if (type == SD_BUS_TYPE_ARRAY)
3009 printf("%sBEGIN_ARRAY \"%s\" {\n", prefix, contents);
3010 else if (type == SD_BUS_TYPE_VARIANT)
3011 printf("%sBEGIN_VARIANT \"%s\" {\n", prefix, contents);
3012 else if (type == SD_BUS_TYPE_STRUCT)
3013 printf("%sBEGIN_STRUCT \"%s\" {\n", prefix, contents);
3014 else if (type == SD_BUS_TYPE_DICT_ENTRY)
3015 printf("%sBEGIN_DICT_ENTRY \"%s\" {\n", prefix, contents);
3022 r = sd_bus_message_read_basic(m, type, &basic);
3024 log_error("Failed to get basic: %s", strerror(-r));
3030 case SD_BUS_TYPE_BYTE:
3031 printf("%sBYTE: %u\n", prefix, basic.u8);
3034 case SD_BUS_TYPE_BOOLEAN:
3035 printf("%sBOOLEAN: %s\n", prefix, yes_no(basic.i));
3038 case SD_BUS_TYPE_INT16:
3039 printf("%sINT16: %i\n", prefix, basic.s16);
3042 case SD_BUS_TYPE_UINT16:
3043 printf("%sUINT16: %u\n", prefix, basic.u16);
3046 case SD_BUS_TYPE_INT32:
3047 printf("%sINT32: %i\n", prefix, basic.s32);
3050 case SD_BUS_TYPE_UINT32:
3051 printf("%sUINT32: %u\n", prefix, basic.u32);
3054 case SD_BUS_TYPE_INT64:
3055 printf("%sINT64: %lli\n", prefix, (long long) basic.s64);
3058 case SD_BUS_TYPE_UINT64:
3059 printf("%sUINT64: %llu\n", prefix, (unsigned long long) basic.u64);
3062 case SD_BUS_TYPE_DOUBLE:
3063 printf("%sDOUBLE: %g\n", prefix, basic.d64);
3066 case SD_BUS_TYPE_STRING:
3067 printf("%sSTRING: \"%s\"\n", prefix, basic.string);
3070 case SD_BUS_TYPE_OBJECT_PATH:
3071 printf("%sOBJECT_PATH: \"%s\"\n", prefix, basic.string);
3074 case SD_BUS_TYPE_SIGNATURE:
3075 printf("%sSIGNATURE: \"%s\"\n", prefix, basic.string);
3078 case SD_BUS_TYPE_UNIX_FD:
3079 printf("%sUNIX_FD: %i\n", prefix, basic.i);
3083 assert_not_reached("Unknown basic type.");
3087 printf("} END_MESSAGE\n");
3091 int bus_message_get_blob(sd_bus_message *m, void **buffer, size_t *sz) {
3099 total = BUS_MESSAGE_SIZE(m);
3105 e = mempcpy(p, m->header, sizeof(*m->header));
3108 e = mempcpy(e, m->fields, m->header->fields_size);
3110 if (m->header->fields_size % 8 != 0)
3111 e = mempset(e, 0, 8 - (m->header->fields_size % 8));
3115 e = mempcpy(e, m->body, m->header->body_size);
3117 assert(total == (size_t) ((uint8_t*) e - (uint8_t*) p));
3125 int bus_message_read_strv_extend(sd_bus_message *m, char ***l) {
3131 r = sd_bus_message_enter_container(m, 'a', "s");
3138 r = sd_bus_message_read_basic(m, 's', &s);
3144 r = strv_extend(l, s);
3149 r = sd_bus_message_exit_container(m);
3156 const char* bus_message_get_arg(sd_bus_message *m, unsigned i) {
3163 r = sd_bus_message_rewind(m, true);
3168 r = sd_bus_message_peek_type(m, &type, NULL);
3172 if (type != SD_BUS_TYPE_STRING &&
3173 type != SD_BUS_TYPE_OBJECT_PATH &&
3174 type != SD_BUS_TYPE_SIGNATURE)
3177 r = sd_bus_message_read_basic(m, type, &t);
3184 r = sd_bus_message_rewind(m, true);
3191 int bus_header_size(struct bus_header *h, size_t *sum) {
3197 if (h->endian == SD_BUS_NATIVE_ENDIAN) {
3198 fs = h->fields_size;
3200 } else if (h->endian == SD_BUS_REVERSE_ENDIAN) {
3201 fs = bswap_32(h->fields_size);
3202 bs = bswap_32(h->body_size);
3206 *sum = sizeof(struct bus_header) + ALIGN8(fs) + bs;