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)
1244 int bus_message_append_ap(
1257 for (t = types; *t; t++) {
1260 case SD_BUS_TYPE_BYTE: {
1263 x = (uint8_t) va_arg(ap, int);
1264 r = sd_bus_message_append_basic(m, *t, &x);
1268 case SD_BUS_TYPE_BOOLEAN:
1269 case SD_BUS_TYPE_INT32:
1270 case SD_BUS_TYPE_UINT32:
1271 case SD_BUS_TYPE_UNIX_FD: {
1274 /* We assume a boolean is the same as int32_t */
1275 assert_cc(sizeof(int32_t) == sizeof(int));
1277 x = va_arg(ap, uint32_t);
1278 r = sd_bus_message_append_basic(m, *t, &x);
1282 case SD_BUS_TYPE_INT16:
1283 case SD_BUS_TYPE_UINT16: {
1286 x = (uint16_t) va_arg(ap, int);
1287 r = sd_bus_message_append_basic(m, *t, &x);
1291 case SD_BUS_TYPE_INT64:
1292 case SD_BUS_TYPE_UINT64:
1293 case SD_BUS_TYPE_DOUBLE: {
1296 x = va_arg(ap, uint64_t);
1297 r = sd_bus_message_append_basic(m, *t, &x);
1301 case SD_BUS_TYPE_STRING:
1302 case SD_BUS_TYPE_OBJECT_PATH:
1303 case SD_BUS_TYPE_SIGNATURE: {
1306 x = va_arg(ap, const char*);
1307 r = sd_bus_message_append_basic(m, *t, x);
1311 case SD_BUS_TYPE_ARRAY: {
1314 r = signature_element_length(t + 1, &k);
1322 memcpy(s, t + 1, k);
1326 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, s);
1330 n = va_arg(ap, unsigned);
1331 for (i = 0; i < n; i++) {
1332 r = bus_message_append_ap(m, s, ap);
1337 r = sd_bus_message_close_container(m);
1343 case SD_BUS_TYPE_VARIANT: {
1346 s = va_arg(ap, const char*);
1350 r = sd_bus_message_open_container(m, SD_BUS_TYPE_VARIANT, s);
1354 r = bus_message_append_ap(m, s, ap);
1358 r = sd_bus_message_close_container(m);
1362 case SD_BUS_TYPE_STRUCT_BEGIN:
1363 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
1366 r = signature_element_length(t, &k);
1373 memcpy(s, t + 1, k - 2);
1376 r = sd_bus_message_open_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
1382 r = bus_message_append_ap(m, s, ap);
1386 r = sd_bus_message_close_container(m);
1403 int sd_bus_message_append(sd_bus_message *m, const char *types, ...) {
1414 va_start(ap, types);
1415 r = bus_message_append_ap(m, types, ap);
1421 static int buffer_peek(const void *p, uint32_t sz, size_t *rindex, size_t align, size_t nbytes, void **r) {
1427 start = ALIGN_TO((size_t) *rindex, align);
1433 /* Verify that padding is 0 */
1434 for (k = *rindex; k < start; k++)
1435 if (((const uint8_t*) p)[k] != 0)
1439 *r = (uint8_t*) p + start;
1446 static bool message_end_of_array(sd_bus_message *m, size_t index) {
1447 struct bus_container *c;
1451 c = message_get_container(m);
1455 return index >= c->begin + BUS_MESSAGE_BSWAP32(m, *c->array_size);
1458 static int message_peek_body(sd_bus_message *m, size_t *rindex, size_t align, size_t nbytes, void **ret) {
1463 if (message_end_of_array(m, *rindex))
1466 return buffer_peek(m->body, BUS_MESSAGE_BODY_SIZE(m), rindex, align, nbytes, ret);
1469 static bool validate_nul(const char *s, size_t l) {
1471 /* Check for NUL chars in the string */
1472 if (memchr(s, 0, l))
1475 /* Check for NUL termination */
1482 static bool validate_string(const char *s, size_t l) {
1484 if (!validate_nul(s, l))
1487 /* Check if valid UTF8 */
1488 if (!utf8_is_valid(s))
1494 static bool validate_signature(const char *s, size_t l) {
1496 if (!validate_nul(s, l))
1499 /* Check if valid signature */
1500 if (!signature_is_valid(s, true))
1506 static bool validate_object_path(const char *s, size_t l) {
1508 if (!validate_nul(s, l))
1511 if (!object_path_is_valid(s))
1517 int sd_bus_message_read_basic(sd_bus_message *m, char type, void *p) {
1518 struct bus_container *c;
1526 if (!bus_type_is_basic(type))
1531 c = message_get_container(m);
1533 if (!c->signature || c->signature[c->index] == 0)
1536 if (c->signature[c->index] != type)
1541 case SD_BUS_TYPE_STRING:
1542 case SD_BUS_TYPE_OBJECT_PATH: {
1547 r = message_peek_body(m, &rindex, 4, 4, &q);
1551 l = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
1552 r = message_peek_body(m, &rindex, 1, l+1, &q);
1558 if (type == SD_BUS_TYPE_OBJECT_PATH) {
1559 if (!validate_object_path(q, l))
1562 if (!validate_string(q, l))
1567 *(const char**) p = q;
1571 case SD_BUS_TYPE_SIGNATURE: {
1576 r = message_peek_body(m, &rindex, 1, 1, &q);
1581 r = message_peek_body(m, &rindex, 1, l+1, &q);
1587 if (!validate_signature(q, l))
1591 *(const char**) p = q;
1599 align = bus_type_get_alignment(type);
1600 sz = bus_type_get_size(type);
1601 assert(align > 0 && sz > 0);
1604 r = message_peek_body(m, &rindex, align, sz, &q);
1610 case SD_BUS_TYPE_BYTE:
1611 *(uint8_t*) p = *(uint8_t*) q;
1614 case SD_BUS_TYPE_BOOLEAN:
1615 *(int*) p = !!*(uint32_t*) q;
1618 case SD_BUS_TYPE_INT16:
1619 case SD_BUS_TYPE_UINT16:
1620 *(uint16_t*) p = BUS_MESSAGE_BSWAP16(m, *(uint16_t*) q);
1623 case SD_BUS_TYPE_INT32:
1624 case SD_BUS_TYPE_UINT32:
1625 *(uint32_t*) p = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
1628 case SD_BUS_TYPE_INT64:
1629 case SD_BUS_TYPE_UINT64:
1630 case SD_BUS_TYPE_DOUBLE:
1631 *(uint64_t*) p = BUS_MESSAGE_BSWAP64(m, *(uint64_t*) q);
1634 case SD_BUS_TYPE_UNIX_FD: {
1638 j = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
1642 copy = fcntl(m->fds[j], F_DUPFD_CLOEXEC, 3);
1651 assert_not_reached("Unknown basic type...");
1660 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1666 static int bus_message_enter_array(
1668 struct bus_container *c,
1669 const char *contents,
1670 uint32_t **array_size) {
1681 if (!signature_is_single(contents))
1684 alignment = bus_type_get_alignment(contents[0]);
1688 if (!c->signature || c->signature[c->index] == 0)
1691 if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
1694 if (!startswith(c->signature + c->index + 1, contents))
1698 r = message_peek_body(m, &rindex, 4, 4, &q);
1702 if (BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q) > BUS_ARRAY_MAX_SIZE)
1705 r = message_peek_body(m, &rindex, alignment, 0, NULL);
1711 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1712 c->index += 1 + strlen(contents);
1716 *array_size = (uint32_t*) q;
1721 static int bus_message_enter_variant(
1723 struct bus_container *c,
1724 const char *contents) {
1735 if (!signature_is_single(contents))
1738 if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
1741 if (!c->signature || c->signature[c->index] == 0)
1744 if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
1748 r = message_peek_body(m, &rindex, 1, 1, &q);
1753 r = message_peek_body(m, &rindex, 1, l+1, &q);
1759 if (!validate_signature(q, l))
1762 if (!streq(q, contents))
1765 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1773 static int bus_message_enter_struct(
1775 struct bus_container *c,
1776 const char *contents) {
1785 if (!signature_is_valid(contents, false))
1788 if (!c->signature || c->signature[c->index] == 0)
1791 l = strlen(contents);
1793 if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
1794 !startswith(c->signature + c->index + 1, contents) ||
1795 c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
1798 r = message_peek_body(m, &m->rindex, 8, 0, NULL);
1802 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1803 c->index += 1 + l + 1;
1808 static int bus_message_enter_dict_entry(
1810 struct bus_container *c,
1811 const char *contents) {
1820 if (!signature_is_pair(contents))
1823 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1826 if (!c->signature || c->signature[c->index] == 0)
1829 l = strlen(contents);
1831 if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
1832 !startswith(c->signature + c->index + 1, contents) ||
1833 c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
1836 r = message_peek_body(m, &m->rindex, 8, 0, NULL);
1840 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1841 c->index += 1 + l + 1;
1846 int sd_bus_message_enter_container(sd_bus_message *m, char type, const char *contents) {
1847 struct bus_container *c, *w;
1848 uint32_t *array_size = NULL;
1860 * We enforce a global limit on container depth, that is much
1861 * higher than the 32 structs and 32 arrays the specification
1862 * mandates. This is simpler to implement for us, and we need
1863 * this only to ensure our container array doesn't grow
1864 * without bounds. We are happy to return any data from a
1865 * message as long as the data itself is valid, even if the
1866 * overall message might be not.
1868 * Note that the message signature is validated when
1869 * parsing the headers, and that validation does check the
1872 * Note that the specification defines no limits on the depth
1873 * of stacked variants, but we do.
1875 if (m->n_containers >= BUS_CONTAINER_DEPTH)
1878 w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
1883 c = message_get_container(m);
1885 if (!c->signature || c->signature[c->index] == 0)
1888 signature = strdup(contents);
1892 if (type == SD_BUS_TYPE_ARRAY)
1893 r = bus_message_enter_array(m, c, contents, &array_size);
1894 else if (type == SD_BUS_TYPE_VARIANT)
1895 r = bus_message_enter_variant(m, c, contents);
1896 else if (type == SD_BUS_TYPE_STRUCT)
1897 r = bus_message_enter_struct(m, c, contents);
1898 else if (type == SD_BUS_TYPE_DICT_ENTRY)
1899 r = bus_message_enter_dict_entry(m, c, contents);
1908 /* OK, let's fill it in */
1909 w += m->n_containers++;
1910 w->enclosing = type;
1911 w->signature = signature;
1913 w->array_size = array_size;
1914 w->begin = m->rindex;
1919 int sd_bus_message_exit_container(sd_bus_message *m) {
1920 struct bus_container *c;
1926 if (m->n_containers <= 0)
1929 c = message_get_container(m);
1930 if (c->enclosing == SD_BUS_TYPE_ARRAY) {
1933 l = BUS_MESSAGE_BSWAP32(m, *c->array_size);
1934 if (c->begin + l != m->rindex)
1938 if (c->signature && c->signature[c->index] != 0)
1948 int sd_bus_message_peek_type(sd_bus_message *m, char *type, const char **contents) {
1949 struct bus_container *c;
1957 c = message_get_container(m);
1959 if (!c->signature || c->signature[c->index] == 0)
1962 if (message_end_of_array(m, m->rindex))
1965 if (bus_type_is_basic(c->signature[c->index])) {
1969 *type = c->signature[c->index];
1973 if (c->signature[c->index] == SD_BUS_TYPE_ARRAY) {
1979 r = signature_element_length(c->signature+c->index+1, &l);
1985 sig = strndup(c->signature + c->index + 1, l);
1989 free(m->peeked_signature);
1990 m->peeked_signature = sig;
1996 *type = SD_BUS_TYPE_ARRAY;
2001 if (c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ||
2002 c->signature[c->index] == SD_BUS_TYPE_DICT_ENTRY_BEGIN) {
2008 r = signature_element_length(c->signature+c->index, &l);
2013 sig = strndup(c->signature + c->index + 1, l - 2);
2017 free(m->peeked_signature);
2018 m->peeked_signature = sig;
2024 *type = c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY;
2029 if (c->signature[c->index] == SD_BUS_TYPE_VARIANT) {
2035 r = message_peek_body(m, &rindex, 1, 1, &q);
2042 r = message_peek_body(m, &rindex, 1, l+1, &q);
2048 if (!validate_signature(q, l))
2055 *type = SD_BUS_TYPE_VARIANT;
2064 *type = c->enclosing;
2070 int sd_bus_message_rewind(sd_bus_message *m, int complete) {
2071 struct bus_container *c;
2079 reset_containers(m);
2081 m->root_container.index = 0;
2083 c = message_get_container(m);
2085 c = message_get_container(m);
2088 m->rindex = c->begin;
2091 return !isempty(c->signature);
2100 static int type_stack_push(TypeStack *stack, unsigned max, unsigned *i, const char *types, unsigned n_struct, unsigned n_array) {
2107 stack[*i].types = types;
2108 stack[*i].n_struct = n_struct;
2109 stack[*i].n_array = n_array;
2115 static int type_stack_pop(TypeStack *stack, unsigned max, unsigned *i, const char **types, unsigned *n_struct, unsigned *n_array) {
2126 *types = stack[*i].types;
2127 *n_struct = stack[*i].n_struct;
2128 *n_array = stack[*i].n_array;
2133 static int message_read_ap(sd_bus_message *m, const char *types, va_list ap) {
2134 unsigned n_array, n_struct;
2135 TypeStack stack[BUS_CONTAINER_DEPTH];
2136 unsigned stack_ptr = 0;
2142 /* Ideally, we'd just call ourselves recursively on every
2143 * complex type. However, the state of a va_list that is
2144 * passed to a function is undefined after that function
2145 * returns. This means we need to docode the va_list linearly
2146 * in a single stackframe. We hence implement our own
2147 * home-grown stack in an array. */
2149 n_array = (unsigned) -1;
2150 n_struct = strlen(types);
2155 if (n_array == 0 || (n_struct == 0 && n_array == (unsigned) -1)) {
2156 r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
2162 r = sd_bus_message_exit_container(m);
2170 if (n_array != (unsigned) -1)
2179 case SD_BUS_TYPE_BYTE:
2180 case SD_BUS_TYPE_BOOLEAN:
2181 case SD_BUS_TYPE_INT16:
2182 case SD_BUS_TYPE_UINT16:
2183 case SD_BUS_TYPE_INT32:
2184 case SD_BUS_TYPE_UINT32:
2185 case SD_BUS_TYPE_INT64:
2186 case SD_BUS_TYPE_UINT64:
2187 case SD_BUS_TYPE_DOUBLE:
2188 case SD_BUS_TYPE_STRING:
2189 case SD_BUS_TYPE_OBJECT_PATH:
2190 case SD_BUS_TYPE_SIGNATURE:
2191 case SD_BUS_TYPE_UNIX_FD: {
2194 p = va_arg(ap, void*);
2195 r = sd_bus_message_read_basic(m, *t, p);
2204 case SD_BUS_TYPE_ARRAY: {
2207 r = signature_element_length(t + 1, &k);
2213 memcpy(s, t + 1, k);
2216 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, s);
2223 if (n_array == (unsigned) -1) {
2228 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2234 n_array = va_arg(ap, unsigned);
2239 case SD_BUS_TYPE_VARIANT: {
2242 s = va_arg(ap, const char *);
2246 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, s);
2252 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2257 n_struct = strlen(s);
2258 n_array = (unsigned) -1;
2263 case SD_BUS_TYPE_STRUCT_BEGIN:
2264 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
2267 r = signature_element_length(t, &k);
2273 memcpy(s, t + 1, k - 2);
2276 r = sd_bus_message_enter_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
2283 if (n_array == (unsigned) -1) {
2288 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2294 n_array = (unsigned) -1;
2307 int sd_bus_message_read(sd_bus_message *m, const char *types, ...) {
2318 va_start(ap, types);
2319 r = message_read_ap(m, types, ap);
2325 static int message_peek_fields(
2336 return buffer_peek(m->fields, BUS_MESSAGE_FIELDS_SIZE(m), rindex, align, nbytes, ret);
2339 static int message_peek_field_uint32(
2350 r = message_peek_fields(m, ri, 4, 4, &q);
2355 *ret = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2360 static int message_peek_field_string(
2362 bool (*validate)(const char *p),
2373 r = message_peek_field_uint32(m, ri, &l);
2377 r = message_peek_fields(m, ri, 1, l+1, &q);
2382 if (!validate_nul(q, l))
2388 if (!validate_string(q, l))
2398 static int message_peek_field_signature(
2410 r = message_peek_fields(m, ri, 1, 1, &q);
2415 r = message_peek_fields(m, ri, 1, l+1, &q);
2419 if (!validate_signature(q, l))
2428 static int message_skip_fields(
2431 uint32_t array_size,
2432 const char **signature) {
2434 size_t original_index;
2441 original_index = *ri;
2447 if (array_size != (uint32_t) -1 &&
2448 array_size <= *ri - original_index)
2455 if (t == SD_BUS_TYPE_STRING) {
2457 r = message_peek_field_string(m, NULL, ri, NULL);
2463 } else if (t == SD_BUS_TYPE_OBJECT_PATH) {
2465 r = message_peek_field_string(m, object_path_is_valid, ri, NULL);
2471 } else if (t == SD_BUS_TYPE_SIGNATURE) {
2473 r = message_peek_field_signature(m, ri, NULL);
2479 } else if (bus_type_is_basic(t)) {
2482 align = bus_type_get_alignment(t);
2483 k = bus_type_get_size(t);
2484 assert(align > 0 && k > 0);
2486 r = message_peek_fields(m, ri, align, k, NULL);
2492 } else if (t == SD_BUS_TYPE_ARRAY) {
2494 r = signature_element_length(*signature+1, &l);
2504 strncpy(sig, *signature + 1, l-1);
2507 alignment = bus_type_get_alignment(sig[0]);
2511 r = message_peek_field_uint32(m, ri, &nas);
2514 if (nas > BUS_ARRAY_MAX_SIZE)
2517 r = message_peek_fields(m, ri, alignment, 0, NULL);
2521 r = message_skip_fields(m, ri, nas, (const char**) &s);
2526 (*signature) += 1 + l;
2528 } else if (t == SD_BUS_TYPE_VARIANT) {
2531 r = message_peek_field_signature(m, ri, &s);
2535 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
2541 } else if (t == SD_BUS_TYPE_STRUCT ||
2542 t == SD_BUS_TYPE_DICT_ENTRY) {
2544 r = signature_element_length(*signature, &l);
2551 strncpy(sig, *signature + 1, l-1);
2554 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
2565 static int message_parse_fields(sd_bus_message *m) {
2568 uint32_t unix_fds = 0;
2572 for (ri = 0; ri < BUS_MESSAGE_FIELDS_SIZE(m); ) {
2573 const char *signature;
2576 r = message_peek_fields(m, &ri, 8, 1, (void**) &header);
2580 r = message_peek_field_signature(m, &ri, &signature);
2585 case _SD_BUS_MESSAGE_HEADER_INVALID:
2588 case SD_BUS_MESSAGE_HEADER_PATH:
2593 if (!streq(signature, "o"))
2596 r = message_peek_field_string(m, object_path_is_valid, &ri, &m->path);
2599 case SD_BUS_MESSAGE_HEADER_INTERFACE:
2604 if (!streq(signature, "s"))
2607 r = message_peek_field_string(m, interface_name_is_valid, &ri, &m->interface);
2610 case SD_BUS_MESSAGE_HEADER_MEMBER:
2615 if (!streq(signature, "s"))
2618 r = message_peek_field_string(m, member_name_is_valid, &ri, &m->member);
2621 case SD_BUS_MESSAGE_HEADER_ERROR_NAME:
2626 if (!streq(signature, "s"))
2629 r = message_peek_field_string(m, error_name_is_valid, &ri, &m->error.name);
2632 case SD_BUS_MESSAGE_HEADER_DESTINATION:
2637 if (!streq(signature, "s"))
2640 r = message_peek_field_string(m, service_name_is_valid, &ri, &m->destination);
2643 case SD_BUS_MESSAGE_HEADER_SENDER:
2648 if (!streq(signature, "s"))
2651 r = message_peek_field_string(m, service_name_is_valid, &ri, &m->sender);
2655 case SD_BUS_MESSAGE_HEADER_SIGNATURE: {
2659 if (m->root_container.signature)
2662 if (!streq(signature, "g"))
2665 r = message_peek_field_signature(m, &ri, &s);
2673 free(m->root_container.signature);
2674 m->root_container.signature = c;
2678 case SD_BUS_MESSAGE_HEADER_REPLY_SERIAL:
2679 if (m->reply_serial != 0)
2682 if (!streq(signature, "u"))
2685 r = message_peek_field_uint32(m, &ri, &m->reply_serial);
2689 if (m->reply_serial == 0)
2694 case SD_BUS_MESSAGE_HEADER_UNIX_FDS:
2698 if (!streq(signature, "u"))
2701 r = message_peek_field_uint32(m, &ri, &unix_fds);
2711 r = message_skip_fields(m, &ri, (uint32_t) -1, (const char **) &signature);
2718 if (m->n_fds != unix_fds)
2721 if (isempty(m->root_container.signature) != (BUS_MESSAGE_BODY_SIZE(m) == 0))
2724 switch (m->header->type) {
2726 case SD_BUS_MESSAGE_TYPE_SIGNAL:
2727 if (!m->path || !m->interface || !m->member)
2731 case SD_BUS_MESSAGE_TYPE_METHOD_CALL:
2733 if (!m->path || !m->member)
2738 case SD_BUS_MESSAGE_TYPE_METHOD_RETURN:
2740 if (m->reply_serial == 0)
2744 case SD_BUS_MESSAGE_TYPE_METHOD_ERROR:
2746 if (m->reply_serial == 0 || !m->error.name)
2751 /* Try to read the error message, but if we can't it's a non-issue */
2752 if (m->header->type == SD_BUS_MESSAGE_TYPE_METHOD_ERROR)
2753 sd_bus_message_read(m, "s", &m->error.message);
2758 static void setup_iovec(sd_bus_message *m) {
2765 m->iovec[m->n_iovec].iov_base = m->header;
2766 m->iovec[m->n_iovec].iov_len = sizeof(*m->header);
2767 m->size += m->iovec[m->n_iovec].iov_len;
2771 m->iovec[m->n_iovec].iov_base = m->fields;
2772 m->iovec[m->n_iovec].iov_len = m->header->fields_size;
2773 m->size += m->iovec[m->n_iovec].iov_len;
2776 if (m->header->fields_size % 8 != 0) {
2777 static const uint8_t padding[7] = { 0, 0, 0, 0, 0, 0, 0 };
2779 m->iovec[m->n_iovec].iov_base = (void*) padding;
2780 m->iovec[m->n_iovec].iov_len = 8 - m->header->fields_size % 8;
2781 m->size += m->iovec[m->n_iovec].iov_len;
2787 m->iovec[m->n_iovec].iov_base = m->body;
2788 m->iovec[m->n_iovec].iov_len = m->header->body_size;
2789 m->size += m->iovec[m->n_iovec].iov_len;
2794 int bus_message_seal(sd_bus_message *m, uint64_t serial) {
2802 if (m->n_containers > 0)
2805 /* If there's a non-trivial signature set, then add it in here */
2806 if (!isempty(m->root_container.signature)) {
2807 r = message_append_field_signature(m, SD_BUS_MESSAGE_HEADER_SIGNATURE, m->root_container.signature, NULL);
2813 r = message_append_field_uint32(m, SD_BUS_MESSAGE_HEADER_UNIX_FDS, m->n_fds);
2818 m->header->serial = serial;
2826 int sd_bus_message_set_destination(sd_bus_message *m, const char *destination) {
2836 return message_append_field_string(m, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &m->destination);
2839 int bus_message_dump(sd_bus_message *m) {
2845 printf("Message %p\n"
2852 "\tfields_size=%u\n"
2857 "\tdestination=%s\n"
2860 "\treply_serial=%u\n"
2862 "\terror.message=%s\n"
2870 BUS_MESSAGE_SERIAL(m),
2871 BUS_MESSAGE_FIELDS_SIZE(m),
2872 BUS_MESSAGE_BODY_SIZE(m),
2874 strna(m->interface),
2876 strna(m->destination),
2878 strna(m->root_container.signature),
2880 strna(m->error.name),
2881 strna(m->error.message),
2884 r = sd_bus_message_rewind(m, true);
2886 log_error("Failed to rewind: %s", strerror(-r));
2890 printf("BEGIN_MESSAGE \"%s\" {\n", strempty(m->root_container.signature));
2893 _cleanup_free_ char *prefix = NULL;
2894 const char *contents = NULL;
2909 r = sd_bus_message_peek_type(m, &type, &contents);
2911 log_error("Failed to peek type: %s", strerror(-r));
2918 r = sd_bus_message_exit_container(m);
2920 log_error("Failed to exit container: %s", strerror(-r));
2926 prefix = strrep("\t", level);
2930 if (type == SD_BUS_TYPE_ARRAY)
2931 printf("%s} END_ARRAY \n", prefix);
2932 else if (type == SD_BUS_TYPE_VARIANT)
2933 printf("%s} END_VARIANT\n", prefix);
2934 else if (type == SD_BUS_TYPE_STRUCT)
2935 printf("%s} END_STRUCT\n", prefix);
2936 else if (type == SD_BUS_TYPE_DICT_ENTRY)
2937 printf("%s} END_DICT_ENTRY\n", prefix);
2942 prefix = strrep("\t", level);
2946 if (bus_type_is_container(type) > 0) {
2947 r = sd_bus_message_enter_container(m, type, contents);
2949 log_error("Failed to enter container: %s", strerror(-r));
2953 if (type == SD_BUS_TYPE_ARRAY)
2954 printf("%sBEGIN_ARRAY \"%s\" {\n", prefix, contents);
2955 else if (type == SD_BUS_TYPE_VARIANT)
2956 printf("%sBEGIN_VARIANT \"%s\" {\n", prefix, contents);
2957 else if (type == SD_BUS_TYPE_STRUCT)
2958 printf("%sBEGIN_STRUCT \"%s\" {\n", prefix, contents);
2959 else if (type == SD_BUS_TYPE_DICT_ENTRY)
2960 printf("%sBEGIN_DICT_ENTRY \"%s\" {\n", prefix, contents);
2967 r = sd_bus_message_read_basic(m, type, &basic);
2969 log_error("Failed to get basic: %s", strerror(-r));
2975 case SD_BUS_TYPE_BYTE:
2976 printf("%sBYTE: %u\n", prefix, basic.u8);
2979 case SD_BUS_TYPE_BOOLEAN:
2980 printf("%sBOOLEAN: %s\n", prefix, yes_no(basic.i));
2983 case SD_BUS_TYPE_INT16:
2984 printf("%sINT16: %i\n", prefix, basic.s16);
2987 case SD_BUS_TYPE_UINT16:
2988 printf("%sUINT16: %u\n", prefix, basic.u16);
2991 case SD_BUS_TYPE_INT32:
2992 printf("%sINT32: %i\n", prefix, basic.s32);
2995 case SD_BUS_TYPE_UINT32:
2996 printf("%sUINT32: %u\n", prefix, basic.u32);
2999 case SD_BUS_TYPE_INT64:
3000 printf("%sINT64: %lli\n", prefix, (long long) basic.s64);
3003 case SD_BUS_TYPE_UINT64:
3004 printf("%sUINT64: %llu\n", prefix, (unsigned long long) basic.u64);
3007 case SD_BUS_TYPE_DOUBLE:
3008 printf("%sDOUBLE: %g\n", prefix, basic.d64);
3011 case SD_BUS_TYPE_STRING:
3012 printf("%sSTRING: \"%s\"\n", prefix, basic.string);
3015 case SD_BUS_TYPE_OBJECT_PATH:
3016 printf("%sOBJECT_PATH: \"%s\"\n", prefix, basic.string);
3019 case SD_BUS_TYPE_SIGNATURE:
3020 printf("%sSIGNATURE: \"%s\"\n", prefix, basic.string);
3023 case SD_BUS_TYPE_UNIX_FD:
3024 printf("%sUNIX_FD: %i\n", prefix, basic.i);
3028 assert_not_reached("Unknown basic type.");
3032 printf("} END_MESSAGE\n");
3036 int bus_message_get_blob(sd_bus_message *m, void **buffer, size_t *sz) {
3045 for (i = 0, total = 0; i < m->n_iovec; i++)
3046 total += m->iovec[i].iov_len;
3052 for (i = 0, e = p; i < m->n_iovec; i++)
3053 e = mempcpy(e, m->iovec[i].iov_base, m->iovec[i].iov_len);
3061 int bus_message_read_strv_extend(sd_bus_message *m, char ***l) {
3067 r = sd_bus_message_enter_container(m, 'a', "s");
3074 r = sd_bus_message_read_basic(m, 's', &s);
3080 r = strv_extend(l, s);
3085 r = sd_bus_message_exit_container(m);
3092 const char* bus_message_get_arg(sd_bus_message *m, unsigned i) {
3099 r = sd_bus_message_rewind(m, true);
3104 r = sd_bus_message_peek_type(m, &type, NULL);
3108 if (type != SD_BUS_TYPE_STRING &&
3109 type != SD_BUS_TYPE_OBJECT_PATH &&
3110 type != SD_BUS_TYPE_SIGNATURE)
3113 r = sd_bus_message_read_basic(m, type, &t);
3120 r = sd_bus_message_rewind(m, true);