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;
306 r = message_parse_fields(m);
310 /* We take possession of the memory and fds now */
311 m->free_header = true;
322 static sd_bus_message *message_new(sd_bus *bus, uint8_t type) {
325 m = malloc0(ALIGN(sizeof(sd_bus_message)) + sizeof(struct bus_header));
330 m->header = (struct bus_header*) ((uint8_t*) m + ALIGN(sizeof(struct sd_bus_message)));
331 m->header->endian = SD_BUS_NATIVE_ENDIAN;
332 m->header->type = type;
333 m->header->version = bus ? bus->message_version : 1;
334 m->allow_fds = !bus || bus->can_fds || (bus->state != BUS_HELLO && bus->state != BUS_RUNNING);
339 int sd_bus_message_new_signal(
342 const char *interface,
344 sd_bus_message **m) {
357 if (bus && bus->state == BUS_UNSET)
360 t = message_new(bus, SD_BUS_MESSAGE_TYPE_SIGNAL);
364 t->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
366 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_PATH, SD_BUS_TYPE_OBJECT_PATH, path, &t->path);
369 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_INTERFACE, SD_BUS_TYPE_STRING, interface, &t->interface);
372 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_MEMBER, SD_BUS_TYPE_STRING, member, &t->member);
380 sd_bus_message_unref(t);
384 int sd_bus_message_new_method_call(
386 const char *destination,
388 const char *interface,
390 sd_bus_message **m) {
401 if (bus && bus->state == BUS_UNSET)
404 t = message_new(bus, SD_BUS_MESSAGE_TYPE_METHOD_CALL);
408 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_PATH, SD_BUS_TYPE_OBJECT_PATH, path, &t->path);
411 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_MEMBER, SD_BUS_TYPE_STRING, member, &t->member);
416 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_INTERFACE, SD_BUS_TYPE_STRING, interface, &t->interface);
422 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &t->destination);
435 static int message_new_reply(
437 sd_bus_message *call,
439 sd_bus_message **m) {
448 if (call->header->type != SD_BUS_MESSAGE_TYPE_METHOD_CALL)
452 if (bus && bus->state == BUS_UNSET)
455 t = message_new(bus, type);
459 t->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
460 t->reply_serial = BUS_MESSAGE_SERIAL(call);
462 r = message_append_field_uint32(t, SD_BUS_MESSAGE_HEADER_REPLY_SERIAL, t->reply_serial);
467 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, call->sender, &t->sender);
472 t->dont_send = !!(call->header->flags & SD_BUS_MESSAGE_NO_REPLY_EXPECTED);
482 int sd_bus_message_new_method_return(
484 sd_bus_message *call,
485 sd_bus_message **m) {
487 return message_new_reply(bus, call, SD_BUS_MESSAGE_TYPE_METHOD_RETURN, m);
490 int sd_bus_message_new_method_error(
492 sd_bus_message *call,
493 const sd_bus_error *e,
494 sd_bus_message **m) {
499 if (!sd_bus_error_is_set(e))
504 r = message_new_reply(bus, call, SD_BUS_MESSAGE_TYPE_METHOD_ERROR, &t);
508 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_ERROR_NAME, SD_BUS_TYPE_STRING, e->name, &t->error.name);
513 r = message_append_basic(t, SD_BUS_TYPE_STRING, e->message, (const void**) &t->error.message);
526 sd_bus_message* sd_bus_message_ref(sd_bus_message *m) {
530 assert(m->n_ref > 0);
536 sd_bus_message* sd_bus_message_unref(sd_bus_message *m) {
540 assert(m->n_ref > 0);
549 int sd_bus_message_get_type(sd_bus_message *m, uint8_t *type) {
555 *type = m->header->type;
559 int sd_bus_message_get_serial(sd_bus_message *m, uint64_t *serial) {
564 if (m->header->serial == 0)
567 *serial = BUS_MESSAGE_SERIAL(m);
571 int sd_bus_message_get_reply_serial(sd_bus_message *m, uint64_t *serial) {
576 if (m->reply_serial == 0)
579 *serial = m->reply_serial;
583 int sd_bus_message_get_no_reply(sd_bus_message *m) {
587 return m->header->type == SD_BUS_MESSAGE_TYPE_METHOD_CALL ? !!(m->header->flags & SD_BUS_MESSAGE_NO_REPLY_EXPECTED) : 0;
590 const char *sd_bus_message_get_path(sd_bus_message *m) {
597 const char *sd_bus_message_get_interface(sd_bus_message *m) {
604 const char *sd_bus_message_get_member(sd_bus_message *m) {
610 const char *sd_bus_message_get_destination(sd_bus_message *m) {
614 return m->destination;
617 const char *sd_bus_message_get_sender(sd_bus_message *m) {
624 const sd_bus_error *sd_bus_message_get_error(sd_bus_message *m) {
628 if (!sd_bus_error_is_set(&m->error))
634 int sd_bus_message_get_uid(sd_bus_message *m, uid_t *uid) {
644 int sd_bus_message_get_gid(sd_bus_message *m, gid_t *gid) {
654 int sd_bus_message_get_pid(sd_bus_message *m, pid_t *pid) {
664 int sd_bus_message_get_tid(sd_bus_message *m, pid_t *tid) {
674 const char *sd_bus_message_get_label(sd_bus_message *m) {
681 int sd_bus_message_is_signal(sd_bus_message *m, const char *interface, const char *member) {
685 if (m->header->type != SD_BUS_MESSAGE_TYPE_SIGNAL)
688 if (interface && (!m->interface || !streq(m->interface, interface)))
691 if (member && (!m->member || !streq(m->member, member)))
697 int sd_bus_message_is_method_call(sd_bus_message *m, const char *interface, const char *member) {
701 if (m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_CALL)
704 if (interface && (!m->interface || !streq(m->interface, interface)))
707 if (member && (!m->member || !streq(m->member, member)))
713 int sd_bus_message_is_method_error(sd_bus_message *m, const char *name) {
717 if (m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_ERROR)
720 if (name && (!m->error.name || !streq(m->error.name, name)))
726 int sd_bus_message_set_no_reply(sd_bus_message *m, int b) {
731 if (m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_CALL)
735 m->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
737 m->header->flags &= ~SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
742 static struct bus_container *message_get_container(sd_bus_message *m) {
745 if (m->n_containers == 0)
746 return &m->root_container;
748 assert(m->containers);
749 return m->containers + m->n_containers - 1;
752 static void *message_extend_body(sd_bus_message *m, size_t align, size_t sz) {
755 struct bus_container *c;
761 added = m->header->body_size;
763 p = buffer_extend(&m->body, &m->header->body_size, align, sz);
767 added = m->header->body_size - added;
769 for (c = m->containers; c < m->containers + m->n_containers; c++)
771 c->array_size = (uint32_t*) ((uint8_t*) m->body + ((uint8_t*) c->array_size - (uint8_t*) o));
772 *c->array_size += added;
776 if (m->error.message)
777 m->error.message = (const char*) m->body + (m->error.message - (const char*) o);
785 int message_append_basic(sd_bus_message *m, char type, const void *p, const void **stored) {
786 struct bus_container *c;
801 if (!bus_type_is_basic(type))
804 c = message_get_container(m);
806 if (c->signature && c->signature[c->index]) {
807 /* Container signature is already set */
809 if (c->signature[c->index] != type)
812 /* Maybe we can append to the signature? But only if this is the top-level container*/
813 if (c->enclosing != 0)
816 e = strextend(&c->signature, CHAR_TO_STR(type), NULL);
823 case SD_BUS_TYPE_STRING:
824 case SD_BUS_TYPE_OBJECT_PATH:
827 sz = 4 + strlen(p) + 1;
830 case SD_BUS_TYPE_SIGNATURE:
833 sz = 1 + strlen(p) + 1;
836 case SD_BUS_TYPE_BOOLEAN:
839 assert_cc(sizeof(int) == sizeof(uint32_t));
845 case SD_BUS_TYPE_UNIX_FD: {
861 fd = fcntl(z, F_DUPFD_CLOEXEC, 3);
867 f = realloc(m->fds, sizeof(int) * (m->n_fds + 1));
881 align = bus_type_get_alignment(type);
882 sz = bus_type_get_size(type);
889 a = message_extend_body(m, align, sz);
895 if (type == SD_BUS_TYPE_STRING || type == SD_BUS_TYPE_OBJECT_PATH) {
896 *(uint32_t*) a = sz - 5;
897 memcpy((uint8_t*) a + 4, p, sz - 4);
900 *stored = (const uint8_t*) a + 4;
902 } else if (type == SD_BUS_TYPE_SIGNATURE) {
903 *(uint8_t*) a = sz - 1;
904 memcpy((uint8_t*) a + 1, p, sz - 1);
907 *stored = (const uint8_t*) a + 1;
908 } else if (type == SD_BUS_TYPE_UNIX_FD) {
909 *(uint32_t*) a = fdi;
923 if (c->enclosing != SD_BUS_TYPE_ARRAY)
929 /* Truncate extended signature again */
931 c->signature[c->index] = 0;
934 close_nointr_nofail(fd);
939 int sd_bus_message_append_basic(sd_bus_message *m, char type, const void *p) {
940 return message_append_basic(m, type, p, NULL);
943 static int bus_message_open_array(
945 struct bus_container *c,
946 const char *contents,
947 uint32_t **array_size) {
960 if (!signature_is_single(contents))
963 alignment = bus_type_get_alignment(contents[0]);
967 if (c->signature && c->signature[c->index]) {
969 /* Verify the existing signature */
971 if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
974 if (!startswith(c->signature + c->index + 1, contents))
977 nindex = c->index + 1 + strlen(contents);
979 if (c->enclosing != 0)
982 /* Extend the existing signature */
984 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_ARRAY), contents, NULL);
988 nindex = e - c->signature;
991 saved = m->header->body_size;
992 a = message_extend_body(m, 4, 4);
994 /* Truncate extended signature again */
996 c->signature[c->index] = 0;
1002 if (!message_extend_body(m, alignment, 0)) {
1003 /* Add alignment between size and first element */
1005 c->signature[c->index] = 0;
1007 m->header->body_size = saved;
1011 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1014 /* m->body might have changed so let's readjust a */
1015 a = (uint8_t*) m->body + ((uint8_t*) a - (uint8_t*) b);
1022 static int bus_message_open_variant(
1024 struct bus_container *c,
1025 const char *contents) {
1035 if (!signature_is_single(contents))
1038 if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
1041 if (c->signature && c->signature[c->index]) {
1043 if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
1047 if (c->enclosing != 0)
1050 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_VARIANT), NULL);
1055 l = strlen(contents);
1056 a = message_extend_body(m, 1, 1 + l + 1);
1058 /* Truncate extended signature again */
1060 c->signature[c->index] = 0;
1066 memcpy((uint8_t*) a + 1, contents, l + 1);
1068 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1074 static int bus_message_open_struct(
1076 struct bus_container *c,
1077 const char *contents) {
1086 if (!signature_is_valid(contents, false))
1089 if (c->signature && c->signature[c->index]) {
1092 l = strlen(contents);
1094 if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
1095 !startswith(c->signature + c->index + 1, contents) ||
1096 c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
1099 nindex = c->index + 1 + l + 1;
1101 if (c->enclosing != 0)
1104 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_BEGIN), contents, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_END), NULL);
1108 nindex = e - c->signature;
1111 /* Align contents to 8 byte boundary */
1112 if (!message_extend_body(m, 8, 0)) {
1114 c->signature[c->index] = 0;
1119 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1125 static int bus_message_open_dict_entry(
1127 struct bus_container *c,
1128 const char *contents) {
1136 if (!signature_is_pair(contents))
1139 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1142 if (c->signature && c->signature[c->index]) {
1145 l = strlen(contents);
1147 if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
1148 !startswith(c->signature + c->index + 1, contents) ||
1149 c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
1152 nindex = c->index + 1 + l + 1;
1156 /* Align contents to 8 byte boundary */
1157 if (!message_extend_body(m, 8, 0))
1160 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1166 int sd_bus_message_open_container(
1169 const char *contents) {
1171 struct bus_container *c, *w;
1172 uint32_t *array_size = NULL;
1183 /* Make sure we have space for one more container */
1184 w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
1189 c = message_get_container(m);
1191 signature = strdup(contents);
1195 if (type == SD_BUS_TYPE_ARRAY)
1196 r = bus_message_open_array(m, c, contents, &array_size);
1197 else if (type == SD_BUS_TYPE_VARIANT)
1198 r = bus_message_open_variant(m, c, contents);
1199 else if (type == SD_BUS_TYPE_STRUCT)
1200 r = bus_message_open_struct(m, c, contents);
1201 else if (type == SD_BUS_TYPE_DICT_ENTRY)
1202 r = bus_message_open_dict_entry(m, c, contents);
1211 /* OK, let's fill it in */
1212 w += m->n_containers++;
1213 w->enclosing = type;
1214 w->signature = signature;
1216 w->array_size = array_size;
1222 int sd_bus_message_close_container(sd_bus_message *m) {
1223 struct bus_container *c;
1229 if (m->n_containers <= 0)
1232 c = message_get_container(m);
1233 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1234 if (c->signature && c->signature[c->index] != 0)
1243 static int message_append_ap(
1254 for (t = types; *t; t++) {
1257 case SD_BUS_TYPE_BYTE: {
1260 x = (uint8_t) va_arg(ap, int);
1261 r = sd_bus_message_append_basic(m, *t, &x);
1265 case SD_BUS_TYPE_BOOLEAN:
1266 case SD_BUS_TYPE_INT32:
1267 case SD_BUS_TYPE_UINT32:
1268 case SD_BUS_TYPE_UNIX_FD: {
1271 /* We assume a boolean is the same as int32_t */
1272 assert_cc(sizeof(int32_t) == sizeof(int));
1274 x = va_arg(ap, uint32_t);
1275 r = sd_bus_message_append_basic(m, *t, &x);
1279 case SD_BUS_TYPE_INT16:
1280 case SD_BUS_TYPE_UINT16: {
1283 x = (uint16_t) va_arg(ap, int);
1284 r = sd_bus_message_append_basic(m, *t, &x);
1288 case SD_BUS_TYPE_INT64:
1289 case SD_BUS_TYPE_UINT64:
1290 case SD_BUS_TYPE_DOUBLE: {
1293 x = va_arg(ap, uint64_t);
1294 r = sd_bus_message_append_basic(m, *t, &x);
1298 case SD_BUS_TYPE_STRING:
1299 case SD_BUS_TYPE_OBJECT_PATH:
1300 case SD_BUS_TYPE_SIGNATURE: {
1303 x = va_arg(ap, const char*);
1304 r = sd_bus_message_append_basic(m, *t, x);
1308 case SD_BUS_TYPE_ARRAY: {
1311 r = signature_element_length(t + 1, &k);
1319 memcpy(s, t + 1, k);
1323 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, s);
1327 n = va_arg(ap, unsigned);
1328 for (i = 0; i < n; i++) {
1329 r = message_append_ap(m, s, ap);
1334 r = sd_bus_message_close_container(m);
1340 case SD_BUS_TYPE_VARIANT: {
1343 s = va_arg(ap, const char*);
1347 r = sd_bus_message_open_container(m, SD_BUS_TYPE_VARIANT, s);
1351 r = message_append_ap(m, s, ap);
1355 r = sd_bus_message_close_container(m);
1359 case SD_BUS_TYPE_STRUCT_BEGIN:
1360 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
1363 r = signature_element_length(t, &k);
1370 memcpy(s, t + 1, k - 2);
1373 r = sd_bus_message_open_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
1379 r = message_append_ap(m, s, ap);
1383 r = sd_bus_message_close_container(m);
1400 int sd_bus_message_append(sd_bus_message *m, const char *types, ...) {
1411 va_start(ap, types);
1412 r = message_append_ap(m, types, ap);
1418 static int buffer_peek(const void *p, uint32_t sz, size_t *rindex, size_t align, size_t nbytes, void **r) {
1424 start = ALIGN_TO((size_t) *rindex, align);
1430 /* Verify that padding is 0 */
1431 for (k = *rindex; k < start; k++)
1432 if (((const uint8_t*) p)[k] != 0)
1436 *r = (uint8_t*) p + start;
1443 static bool message_end_of_array(sd_bus_message *m, size_t index) {
1444 struct bus_container *c;
1448 c = message_get_container(m);
1452 return index >= c->begin + BUS_MESSAGE_BSWAP32(m, *c->array_size);
1455 static int message_peek_body(sd_bus_message *m, size_t *rindex, size_t align, size_t nbytes, void **ret) {
1460 if (message_end_of_array(m, *rindex))
1463 return buffer_peek(m->body, BUS_MESSAGE_BODY_SIZE(m), rindex, align, nbytes, ret);
1466 static bool validate_nul(const char *s, size_t l) {
1468 /* Check for NUL chars in the string */
1469 if (memchr(s, 0, l))
1472 /* Check for NUL termination */
1479 static bool validate_string(const char *s, size_t l) {
1481 if (!validate_nul(s, l))
1484 /* Check if valid UTF8 */
1485 if (!utf8_is_valid(s))
1491 static bool validate_signature(const char *s, size_t l) {
1493 if (!validate_nul(s, l))
1496 /* Check if valid signature */
1497 if (!signature_is_valid(s, true))
1503 static bool validate_object_path(const char *s, size_t l) {
1505 if (!validate_nul(s, l))
1508 if (!object_path_is_valid(s))
1514 int sd_bus_message_read_basic(sd_bus_message *m, char type, void *p) {
1515 struct bus_container *c;
1523 if (!bus_type_is_basic(type))
1528 c = message_get_container(m);
1530 if (!c->signature || c->signature[c->index] == 0)
1533 if (c->signature[c->index] != type)
1538 case SD_BUS_TYPE_STRING:
1539 case SD_BUS_TYPE_OBJECT_PATH: {
1544 r = message_peek_body(m, &rindex, 4, 4, &q);
1548 l = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
1549 r = message_peek_body(m, &rindex, 1, l+1, &q);
1555 if (type == SD_BUS_TYPE_OBJECT_PATH) {
1556 if (!validate_object_path(q, l))
1559 if (!validate_string(q, l))
1564 *(const char**) p = q;
1568 case SD_BUS_TYPE_SIGNATURE: {
1573 r = message_peek_body(m, &rindex, 1, 1, &q);
1578 r = message_peek_body(m, &rindex, 1, l+1, &q);
1584 if (!validate_signature(q, l))
1588 *(const char**) p = q;
1593 size_t sz, align, rindex;
1595 align = bus_type_get_alignment(type);
1596 sz = bus_type_get_size(type);
1599 r = message_peek_body(m, &rindex, align, sz, &q);
1605 case SD_BUS_TYPE_BYTE:
1606 *(uint8_t*) p = *(uint8_t*) q;
1609 case SD_BUS_TYPE_BOOLEAN:
1610 *(int*) p = !!*(uint32_t*) q;
1613 case SD_BUS_TYPE_INT16:
1614 case SD_BUS_TYPE_UINT16:
1615 *(uint16_t*) p = BUS_MESSAGE_BSWAP16(m, *(uint16_t*) q);
1618 case SD_BUS_TYPE_INT32:
1619 case SD_BUS_TYPE_UINT32:
1620 *(uint32_t*) p = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
1623 case SD_BUS_TYPE_INT64:
1624 case SD_BUS_TYPE_UINT64:
1625 case SD_BUS_TYPE_DOUBLE:
1626 *(uint64_t*) p = BUS_MESSAGE_BSWAP64(m, *(uint64_t*) q);
1629 case SD_BUS_TYPE_UNIX_FD: {
1633 j = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
1637 copy = fcntl(m->fds[j], F_DUPFD_CLOEXEC, 3);
1646 assert_not_reached("Unknown basic type...");
1655 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1661 static int bus_message_enter_array(
1663 struct bus_container *c,
1664 const char *contents,
1665 uint32_t **array_size) {
1676 if (!signature_is_single(contents))
1679 alignment = bus_type_get_alignment(contents[0]);
1683 if (!c->signature || c->signature[c->index] == 0)
1686 if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
1689 if (!startswith(c->signature + c->index + 1, contents))
1693 r = message_peek_body(m, &rindex, 4, 4, &q);
1697 if (BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q) > BUS_ARRAY_MAX_SIZE)
1700 r = message_peek_body(m, &rindex, alignment, 0, NULL);
1706 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1707 c->index += 1 + strlen(contents);
1711 *array_size = (uint32_t*) q;
1716 static int bus_message_enter_variant(
1718 struct bus_container *c,
1719 const char *contents) {
1730 if (!signature_is_single(contents))
1733 if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
1736 if (!c->signature || c->signature[c->index] == 0)
1739 if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
1743 r = message_peek_body(m, &rindex, 1, 1, &q);
1748 r = message_peek_body(m, &rindex, 1, l+1, &q);
1754 if (!validate_signature(q, l))
1757 if (!streq(q, contents))
1760 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1768 static int bus_message_enter_struct(
1770 struct bus_container *c,
1771 const char *contents) {
1780 if (!signature_is_valid(contents, false))
1783 if (!c->signature || c->signature[c->index] == 0)
1786 l = strlen(contents);
1788 if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
1789 !startswith(c->signature + c->index + 1, contents) ||
1790 c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
1793 r = message_peek_body(m, &m->rindex, 8, 0, NULL);
1797 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1798 c->index += 1 + l + 1;
1803 static int bus_message_enter_dict_entry(
1805 struct bus_container *c,
1806 const char *contents) {
1815 if (!signature_is_pair(contents))
1818 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1821 if (!c->signature || c->signature[c->index] == 0)
1824 l = strlen(contents);
1826 if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
1827 !startswith(c->signature + c->index + 1, contents) ||
1828 c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
1831 r = message_peek_body(m, &m->rindex, 8, 0, NULL);
1835 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1836 c->index += 1 + l + 1;
1841 int sd_bus_message_enter_container(sd_bus_message *m, char type, const char *contents) {
1842 struct bus_container *c, *w;
1843 uint32_t *array_size = NULL;
1855 * We enforce a global limit on container depth, that is much
1856 * higher than the 32 structs and 32 arrays the specification
1857 * mandates. This is simpler to implement for us, and we need
1858 * this only to ensure our container array doesn't grow
1859 * without bounds. We are happy to return any data from a
1860 * message as long as the data itself is valid, even if the
1861 * overall message might be not.
1863 * Note that the message signature is validated when
1864 * parsing the headers, and that validation does check the
1867 * Note that the specification defines no limits on the depth
1868 * of stacked variants, but we do.
1870 if (m->n_containers >= BUS_CONTAINER_DEPTH)
1873 w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
1878 c = message_get_container(m);
1880 if (!c->signature || c->signature[c->index] == 0)
1883 signature = strdup(contents);
1887 if (type == SD_BUS_TYPE_ARRAY)
1888 r = bus_message_enter_array(m, c, contents, &array_size);
1889 else if (type == SD_BUS_TYPE_VARIANT)
1890 r = bus_message_enter_variant(m, c, contents);
1891 else if (type == SD_BUS_TYPE_STRUCT)
1892 r = bus_message_enter_struct(m, c, contents);
1893 else if (type == SD_BUS_TYPE_DICT_ENTRY)
1894 r = bus_message_enter_dict_entry(m, c, contents);
1903 /* OK, let's fill it in */
1904 w += m->n_containers++;
1905 w->enclosing = type;
1906 w->signature = signature;
1908 w->array_size = array_size;
1909 w->begin = m->rindex;
1914 int sd_bus_message_exit_container(sd_bus_message *m) {
1915 struct bus_container *c;
1921 if (m->n_containers <= 0)
1924 c = message_get_container(m);
1925 if (c->enclosing == SD_BUS_TYPE_ARRAY) {
1928 l = BUS_MESSAGE_BSWAP32(m, *c->array_size);
1929 if (c->begin + l != m->rindex)
1933 if (c->signature && c->signature[c->index] != 0)
1943 int sd_bus_message_peek_type(sd_bus_message *m, char *type, const char **contents) {
1944 struct bus_container *c;
1952 c = message_get_container(m);
1954 if (!c->signature || c->signature[c->index] == 0)
1957 if (message_end_of_array(m, m->rindex))
1960 if (bus_type_is_basic(c->signature[c->index])) {
1964 *type = c->signature[c->index];
1968 if (c->signature[c->index] == SD_BUS_TYPE_ARRAY) {
1974 r = signature_element_length(c->signature+c->index+1, &l);
1980 sig = strndup(c->signature + c->index + 1, l);
1984 free(m->peeked_signature);
1985 m->peeked_signature = sig;
1991 *type = SD_BUS_TYPE_ARRAY;
1996 if (c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ||
1997 c->signature[c->index] == SD_BUS_TYPE_DICT_ENTRY_BEGIN) {
2003 r = signature_element_length(c->signature+c->index, &l);
2008 sig = strndup(c->signature + c->index + 1, l - 2);
2012 free(m->peeked_signature);
2013 m->peeked_signature = sig;
2019 *type = c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY;
2024 if (c->signature[c->index] == SD_BUS_TYPE_VARIANT) {
2030 r = message_peek_body(m, &rindex, 1, 1, &q);
2037 r = message_peek_body(m, &rindex, 1, l+1, &q);
2043 if (!validate_signature(q, l))
2050 *type = SD_BUS_TYPE_VARIANT;
2059 *type = c->enclosing;
2065 int sd_bus_message_rewind(sd_bus_message *m, int complete) {
2066 struct bus_container *c;
2074 reset_containers(m);
2076 m->root_container.index = 0;
2078 c = message_get_container(m);
2080 c = message_get_container(m);
2083 m->rindex = c->begin;
2086 return !isempty(c->signature);
2089 static int message_read_ap(sd_bus_message *m, const char *types, va_list ap) {
2096 for (t = types; *t; t++) {
2099 case SD_BUS_TYPE_BYTE:
2100 case SD_BUS_TYPE_BOOLEAN:
2101 case SD_BUS_TYPE_INT16:
2102 case SD_BUS_TYPE_UINT16:
2103 case SD_BUS_TYPE_INT32:
2104 case SD_BUS_TYPE_UINT32:
2105 case SD_BUS_TYPE_INT64:
2106 case SD_BUS_TYPE_UINT64:
2107 case SD_BUS_TYPE_DOUBLE:
2108 case SD_BUS_TYPE_STRING:
2109 case SD_BUS_TYPE_OBJECT_PATH:
2110 case SD_BUS_TYPE_SIGNATURE:
2111 case SD_BUS_TYPE_UNIX_FD: {
2114 p = va_arg(ap, void*);
2115 r = sd_bus_message_read_basic(m, *t, p);
2119 case SD_BUS_TYPE_ARRAY: {
2122 r = signature_element_length(t + 1, &k);
2130 memcpy(s, t + 1, k);
2134 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, s);
2140 n = va_arg(ap, unsigned);
2141 for (i = 0; i < n; i++) {
2142 r = message_read_ap(m, s, ap);
2147 r = sd_bus_message_exit_container(m);
2153 case SD_BUS_TYPE_VARIANT: {
2156 s = va_arg(ap, const char *);
2160 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, s);
2166 r = message_read_ap(m, s, ap);
2172 r = sd_bus_message_exit_container(m);
2176 case SD_BUS_TYPE_STRUCT_BEGIN:
2177 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
2180 r = signature_element_length(t, &k);
2186 memcpy(s, t + 1, k - 2);
2189 r = sd_bus_message_enter_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
2197 r = message_read_ap(m, s, ap);
2203 r = sd_bus_message_exit_container(m);
2222 int sd_bus_message_read(sd_bus_message *m, const char *types, ...) {
2233 va_start(ap, types);
2234 r = message_read_ap(m, types, ap);
2240 static int message_peek_fields(
2251 return buffer_peek(m->fields, BUS_MESSAGE_FIELDS_SIZE(m), rindex, align, nbytes, ret);
2254 static int message_peek_field_uint32(
2265 r = message_peek_fields(m, ri, 4, 4, &q);
2270 *ret = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2275 static int message_peek_field_string(
2277 bool (*validate)(const char *p),
2288 r = message_peek_field_uint32(m, ri, &l);
2292 r = message_peek_fields(m, ri, 1, l+1, &q);
2297 if (!validate_nul(q, l))
2303 if (!validate_string(q, l))
2313 static int message_peek_field_signature(
2325 r = message_peek_fields(m, ri, 1, 1, &q);
2330 r = message_peek_fields(m, ri, 1, l+1, &q);
2334 if (!validate_signature(q, l))
2343 static int message_skip_fields(
2346 uint32_t array_size,
2347 const char **signature) {
2349 size_t original_index;
2356 original_index = *ri;
2362 if (array_size != (uint32_t) -1 &&
2363 array_size <= *ri - original_index)
2370 if (t == SD_BUS_TYPE_STRING) {
2372 r = message_peek_field_string(m, NULL, ri, NULL);
2378 } else if (t == SD_BUS_TYPE_OBJECT_PATH) {
2380 r = message_peek_field_string(m, object_path_is_valid, ri, NULL);
2386 } else if (t == SD_BUS_TYPE_SIGNATURE) {
2388 r = message_peek_field_signature(m, ri, NULL);
2394 } else if (bus_type_is_basic(t)) {
2397 align = bus_type_get_alignment(t);
2398 k = bus_type_get_size(t);
2400 r = message_peek_fields(m, ri, align, k, NULL);
2406 } else if (t == SD_BUS_TYPE_ARRAY) {
2408 r = signature_element_length(*signature+1, &l);
2418 strncpy(sig, *signature + 1, l-1);
2421 alignment = bus_type_get_alignment(sig[0]);
2425 r = message_peek_field_uint32(m, ri, &nas);
2428 if (nas > BUS_ARRAY_MAX_SIZE)
2431 r = message_peek_fields(m, ri, alignment, 0, NULL);
2435 r = message_skip_fields(m, ri, nas, (const char**) &s);
2440 (*signature) += 1 + l;
2442 } else if (t == SD_BUS_TYPE_VARIANT) {
2445 r = message_peek_field_signature(m, ri, &s);
2449 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
2455 } else if (t == SD_BUS_TYPE_STRUCT ||
2456 t == SD_BUS_TYPE_DICT_ENTRY) {
2458 r = signature_element_length(*signature, &l);
2465 strncpy(sig, *signature + 1, l-1);
2468 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
2479 static int message_parse_fields(sd_bus_message *m) {
2482 uint32_t unix_fds = 0;
2486 for (ri = 0; ri < BUS_MESSAGE_FIELDS_SIZE(m); ) {
2487 const char *signature;
2490 r = message_peek_fields(m, &ri, 8, 1, (void**) &header);
2494 r = message_peek_field_signature(m, &ri, &signature);
2499 case _SD_BUS_MESSAGE_HEADER_INVALID:
2502 case SD_BUS_MESSAGE_HEADER_PATH:
2507 if (!streq(signature, "o"))
2510 r = message_peek_field_string(m, object_path_is_valid, &ri, &m->path);
2513 case SD_BUS_MESSAGE_HEADER_INTERFACE:
2518 if (!streq(signature, "s"))
2521 r = message_peek_field_string(m, interface_name_is_valid, &ri, &m->interface);
2524 case SD_BUS_MESSAGE_HEADER_MEMBER:
2529 if (!streq(signature, "s"))
2532 r = message_peek_field_string(m, member_name_is_valid, &ri, &m->member);
2535 case SD_BUS_MESSAGE_HEADER_ERROR_NAME:
2540 if (!streq(signature, "s"))
2543 r = message_peek_field_string(m, error_name_is_valid, &ri, &m->error.name);
2546 case SD_BUS_MESSAGE_HEADER_DESTINATION:
2551 if (!streq(signature, "s"))
2554 r = message_peek_field_string(m, service_name_is_valid, &ri, &m->destination);
2557 case SD_BUS_MESSAGE_HEADER_SENDER:
2562 if (!streq(signature, "s"))
2565 r = message_peek_field_string(m, service_name_is_valid, &ri, &m->sender);
2569 case SD_BUS_MESSAGE_HEADER_SIGNATURE: {
2573 if (m->root_container.signature)
2576 if (!streq(signature, "g"))
2579 r = message_peek_field_signature(m, &ri, &s);
2587 free(m->root_container.signature);
2588 m->root_container.signature = c;
2592 case SD_BUS_MESSAGE_HEADER_REPLY_SERIAL:
2593 if (m->reply_serial != 0)
2596 if (!streq(signature, "u"))
2599 r = message_peek_field_uint32(m, &ri, &m->reply_serial);
2603 if (m->reply_serial == 0)
2608 case SD_BUS_MESSAGE_HEADER_UNIX_FDS:
2612 if (!streq(signature, "u"))
2615 r = message_peek_field_uint32(m, &ri, &unix_fds);
2625 r = message_skip_fields(m, &ri, (uint32_t) -1, (const char **) &signature);
2632 if (m->n_fds != unix_fds)
2635 if (isempty(m->root_container.signature) != (BUS_MESSAGE_BODY_SIZE(m) == 0))
2638 switch (m->header->type) {
2640 case SD_BUS_MESSAGE_TYPE_SIGNAL:
2641 if (!m->path || !m->interface || !m->member)
2645 case SD_BUS_MESSAGE_TYPE_METHOD_CALL:
2647 if (!m->path || !m->member)
2652 case SD_BUS_MESSAGE_TYPE_METHOD_RETURN:
2654 if (m->reply_serial == 0)
2658 case SD_BUS_MESSAGE_TYPE_METHOD_ERROR:
2660 if (m->reply_serial == 0 || !m->error.name)
2665 /* Try to read the error message, but if we can't it's a non-issue */
2666 if (m->header->type == SD_BUS_MESSAGE_TYPE_METHOD_ERROR)
2667 sd_bus_message_read(m, "s", &m->error.message);
2672 static void setup_iovec(sd_bus_message *m) {
2679 m->iovec[m->n_iovec].iov_base = m->header;
2680 m->iovec[m->n_iovec].iov_len = sizeof(*m->header);
2681 m->size += m->iovec[m->n_iovec].iov_len;
2685 m->iovec[m->n_iovec].iov_base = m->fields;
2686 m->iovec[m->n_iovec].iov_len = m->header->fields_size;
2687 m->size += m->iovec[m->n_iovec].iov_len;
2690 if (m->header->fields_size % 8 != 0) {
2691 static const uint8_t padding[7] = { 0, 0, 0, 0, 0, 0, 0 };
2693 m->iovec[m->n_iovec].iov_base = (void*) padding;
2694 m->iovec[m->n_iovec].iov_len = 8 - m->header->fields_size % 8;
2695 m->size += m->iovec[m->n_iovec].iov_len;
2701 m->iovec[m->n_iovec].iov_base = m->body;
2702 m->iovec[m->n_iovec].iov_len = m->header->body_size;
2703 m->size += m->iovec[m->n_iovec].iov_len;
2708 int bus_message_seal(sd_bus_message *m, uint64_t serial) {
2716 if (m->n_containers > 0)
2719 /* If there's a non-trivial signature set, then add it in here */
2720 if (!isempty(m->root_container.signature)) {
2721 r = message_append_field_signature(m, SD_BUS_MESSAGE_HEADER_SIGNATURE, m->root_container.signature, NULL);
2727 r = message_append_field_uint32(m, SD_BUS_MESSAGE_HEADER_UNIX_FDS, m->n_fds);
2732 m->header->serial = serial;
2740 int sd_bus_message_set_destination(sd_bus_message *m, const char *destination) {
2750 return message_append_field_string(m, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &m->destination);
2753 int bus_message_dump(sd_bus_message *m) {
2759 printf("Message %p\n"
2766 "\tfields_size=%u\n"
2771 "\tdestination=%s\n"
2774 "\treply_serial=%u\n"
2776 "\terror.message=%s\n"
2784 BUS_MESSAGE_SERIAL(m),
2785 BUS_MESSAGE_FIELDS_SIZE(m),
2786 BUS_MESSAGE_BODY_SIZE(m),
2788 strna(m->interface),
2790 strna(m->destination),
2792 strna(m->root_container.signature),
2794 strna(m->error.name),
2795 strna(m->error.message),
2798 r = sd_bus_message_rewind(m, true);
2800 log_error("Failed to rewind: %s", strerror(-r));
2804 printf("BEGIN_MESSAGE \"%s\" {\n", strempty(m->root_container.signature));
2807 _cleanup_free_ char *prefix = NULL;
2808 const char *contents = NULL;
2823 r = sd_bus_message_peek_type(m, &type, &contents);
2825 log_error("Failed to peek type: %s", strerror(-r));
2832 r = sd_bus_message_exit_container(m);
2834 log_error("Failed to exit container: %s", strerror(-r));
2840 prefix = strrep("\t", level);
2844 if (type == SD_BUS_TYPE_ARRAY)
2845 printf("%s} END_ARRAY \n", prefix);
2846 else if (type == SD_BUS_TYPE_VARIANT)
2847 printf("%s} END_VARIANT\n", prefix);
2848 else if (type == SD_BUS_TYPE_STRUCT)
2849 printf("%s} END_STRUCT\n", prefix);
2850 else if (type == SD_BUS_TYPE_DICT_ENTRY)
2851 printf("%s} END_DICT_ENTRY\n", prefix);
2856 prefix = strrep("\t", level);
2860 if (bus_type_is_container(type) > 0) {
2861 r = sd_bus_message_enter_container(m, type, contents);
2863 log_error("Failed to enter container: %s", strerror(-r));
2867 if (type == SD_BUS_TYPE_ARRAY)
2868 printf("%sBEGIN_ARRAY \"%s\" {\n", prefix, contents);
2869 else if (type == SD_BUS_TYPE_VARIANT)
2870 printf("%sBEGIN_VARIANT \"%s\" {\n", prefix, contents);
2871 else if (type == SD_BUS_TYPE_STRUCT)
2872 printf("%sBEGIN_STRUCT \"%s\" {\n", prefix, contents);
2873 else if (type == SD_BUS_TYPE_DICT_ENTRY)
2874 printf("%sBEGIN_DICT_ENTRY \"%s\" {\n", prefix, contents);
2881 r = sd_bus_message_read_basic(m, type, &basic);
2883 log_error("Failed to get basic: %s", strerror(-r));
2889 case SD_BUS_TYPE_BYTE:
2890 printf("%sBYTE: %u\n", prefix, basic.u8);
2893 case SD_BUS_TYPE_BOOLEAN:
2894 printf("%sBOOLEAN: %s\n", prefix, yes_no(basic.i));
2897 case SD_BUS_TYPE_INT16:
2898 printf("%sINT16: %i\n", prefix, basic.s16);
2901 case SD_BUS_TYPE_UINT16:
2902 printf("%sUINT16: %u\n", prefix, basic.u16);
2905 case SD_BUS_TYPE_INT32:
2906 printf("%sINT32: %i\n", prefix, basic.s32);
2909 case SD_BUS_TYPE_UINT32:
2910 printf("%sUINT32: %u\n", prefix, basic.u32);
2913 case SD_BUS_TYPE_INT64:
2914 printf("%sINT64: %lli\n", prefix, (long long) basic.s64);
2917 case SD_BUS_TYPE_UINT64:
2918 printf("%sUINT64: %llu\n", prefix, (unsigned long long) basic.u64);
2921 case SD_BUS_TYPE_DOUBLE:
2922 printf("%sDOUBLE: %g\n", prefix, basic.d64);
2925 case SD_BUS_TYPE_STRING:
2926 printf("%sSTRING: \"%s\"\n", prefix, basic.string);
2929 case SD_BUS_TYPE_OBJECT_PATH:
2930 printf("%sOBJECT_PATH: \"%s\"\n", prefix, basic.string);
2933 case SD_BUS_TYPE_SIGNATURE:
2934 printf("%sSIGNATURE: \"%s\"\n", prefix, basic.string);
2937 case SD_BUS_TYPE_UNIX_FD:
2938 printf("%sUNIX_FD: %i\n", prefix, basic.i);
2942 assert_not_reached("Unknown basic type.");
2946 printf("} END_MESSAGE\n");
2950 int bus_message_get_blob(sd_bus_message *m, void **buffer, size_t *sz) {
2959 for (i = 0, total = 0; i < m->n_iovec; i++)
2960 total += m->iovec[i].iov_len;
2966 for (i = 0, e = p; i < m->n_iovec; i++)
2967 e = mempcpy(e, m->iovec[i].iov_base, m->iovec[i].iov_len);
2975 int bus_message_read_strv_extend(sd_bus_message *m, char ***l) {
2981 r = sd_bus_message_enter_container(m, 'a', "s");
2988 r = sd_bus_message_read_basic(m, 's', &s);
2994 r = strv_extend(l, s);
2999 r = sd_bus_message_exit_container(m);