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;
339 int sd_bus_message_new_signal(
342 const char *interface,
344 sd_bus_message **m) {
358 t = message_new(bus, SD_BUS_MESSAGE_TYPE_SIGNAL);
362 t->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
364 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_PATH, SD_BUS_TYPE_OBJECT_PATH, path, &t->path);
367 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_INTERFACE, SD_BUS_TYPE_STRING, interface, &t->interface);
370 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_MEMBER, SD_BUS_TYPE_STRING, member, &t->member);
378 sd_bus_message_unref(t);
382 int sd_bus_message_new_method_call(
384 const char *destination,
386 const char *interface,
388 sd_bus_message **m) {
400 t = message_new(bus, SD_BUS_MESSAGE_TYPE_METHOD_CALL);
404 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_PATH, SD_BUS_TYPE_OBJECT_PATH, path, &t->path);
407 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_MEMBER, SD_BUS_TYPE_STRING, member, &t->member);
412 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_INTERFACE, SD_BUS_TYPE_STRING, interface, &t->interface);
418 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &t->destination);
431 static int message_new_reply(
433 sd_bus_message *call,
435 sd_bus_message **m) {
444 if (call->header->type != SD_BUS_MESSAGE_TYPE_METHOD_CALL)
449 t = message_new(bus, type);
453 t->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
454 t->reply_serial = BUS_MESSAGE_SERIAL(call);
456 r = message_append_field_uint32(t, SD_BUS_MESSAGE_HEADER_REPLY_SERIAL, t->reply_serial);
461 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, call->sender, &t->sender);
466 t->dont_send = !!(call->header->flags & SD_BUS_MESSAGE_NO_REPLY_EXPECTED);
476 int sd_bus_message_new_method_return(
478 sd_bus_message *call,
479 sd_bus_message **m) {
481 return message_new_reply(bus, call, SD_BUS_MESSAGE_TYPE_METHOD_RETURN, m);
484 int sd_bus_message_new_method_error(
486 sd_bus_message *call,
487 const sd_bus_error *e,
488 sd_bus_message **m) {
493 if (!sd_bus_error_is_set(e))
498 r = message_new_reply(bus, call, SD_BUS_MESSAGE_TYPE_METHOD_ERROR, &t);
502 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_ERROR_NAME, SD_BUS_TYPE_STRING, e->name, &t->error.name);
507 r = message_append_basic(t, SD_BUS_TYPE_STRING, e->message, (const void**) &t->error.message);
520 sd_bus_message* sd_bus_message_ref(sd_bus_message *m) {
524 assert(m->n_ref > 0);
530 sd_bus_message* sd_bus_message_unref(sd_bus_message *m) {
534 assert(m->n_ref > 0);
543 int sd_bus_message_get_type(sd_bus_message *m, uint8_t *type) {
549 *type = m->header->type;
553 int sd_bus_message_get_serial(sd_bus_message *m, uint64_t *serial) {
558 if (m->header->serial == 0)
561 *serial = BUS_MESSAGE_SERIAL(m);
565 int sd_bus_message_get_reply_serial(sd_bus_message *m, uint64_t *serial) {
570 if (m->reply_serial == 0)
573 *serial = m->reply_serial;
577 int sd_bus_message_get_no_reply(sd_bus_message *m) {
581 return m->header->type == SD_BUS_MESSAGE_TYPE_METHOD_CALL ? !!(m->header->flags & SD_BUS_MESSAGE_NO_REPLY_EXPECTED) : 0;
584 const char *sd_bus_message_get_path(sd_bus_message *m) {
591 const char *sd_bus_message_get_interface(sd_bus_message *m) {
598 const char *sd_bus_message_get_member(sd_bus_message *m) {
604 const char *sd_bus_message_get_destination(sd_bus_message *m) {
608 return m->destination;
611 const char *sd_bus_message_get_sender(sd_bus_message *m) {
618 const sd_bus_error *sd_bus_message_get_error(sd_bus_message *m) {
622 if (!sd_bus_error_is_set(&m->error))
628 int sd_bus_message_get_uid(sd_bus_message *m, uid_t *uid) {
638 int sd_bus_message_get_gid(sd_bus_message *m, gid_t *gid) {
648 int sd_bus_message_get_pid(sd_bus_message *m, pid_t *pid) {
658 int sd_bus_message_get_tid(sd_bus_message *m, pid_t *tid) {
668 const char *sd_bus_message_get_label(sd_bus_message *m) {
675 int sd_bus_message_is_signal(sd_bus_message *m, const char *interface, const char *member) {
679 if (m->header->type != SD_BUS_MESSAGE_TYPE_SIGNAL)
682 if (interface && (!m->interface || !streq(m->interface, interface)))
685 if (member && (!m->member || !streq(m->member, member)))
691 int sd_bus_message_is_method_call(sd_bus_message *m, const char *interface, const char *member) {
695 if (m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_CALL)
698 if (interface && (!m->interface || !streq(m->interface, interface)))
701 if (member && (!m->member || !streq(m->member, member)))
707 int sd_bus_message_is_method_error(sd_bus_message *m, const char *name) {
711 if (m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_ERROR)
714 if (name && (!m->error.name || !streq(m->error.name, name)))
720 int sd_bus_message_set_no_reply(sd_bus_message *m, int b) {
725 if (m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_CALL)
729 m->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
731 m->header->flags &= ~SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
736 static struct bus_container *message_get_container(sd_bus_message *m) {
739 if (m->n_containers == 0)
740 return &m->root_container;
742 assert(m->containers);
743 return m->containers + m->n_containers - 1;
746 static void *message_extend_body(sd_bus_message *m, size_t align, size_t sz) {
749 struct bus_container *c;
755 added = m->header->body_size;
757 p = buffer_extend(&m->body, &m->header->body_size, align, sz);
761 added = m->header->body_size - added;
763 for (c = m->containers; c < m->containers + m->n_containers; c++)
765 c->array_size = (uint32_t*) ((uint8_t*) m->body + ((uint8_t*) c->array_size - (uint8_t*) o));
766 *c->array_size += added;
770 if (m->error.message)
771 m->error.message = (const char*) m->body + (m->error.message - (const char*) o);
779 int message_append_basic(sd_bus_message *m, char type, const void *p, const void **stored) {
780 struct bus_container *c;
795 if (!bus_type_is_basic(type))
798 c = message_get_container(m);
800 if (c->signature && c->signature[c->index]) {
801 /* Container signature is already set */
803 if (c->signature[c->index] != type)
806 /* Maybe we can append to the signature? But only if this is the top-level container*/
807 if (c->enclosing != 0)
810 e = strextend(&c->signature, CHAR_TO_STR(type), NULL);
817 case SD_BUS_TYPE_STRING:
818 case SD_BUS_TYPE_OBJECT_PATH:
821 sz = 4 + strlen(p) + 1;
824 case SD_BUS_TYPE_SIGNATURE:
827 sz = 1 + strlen(p) + 1;
830 case SD_BUS_TYPE_BOOLEAN:
833 assert_cc(sizeof(int) == sizeof(uint32_t));
839 case SD_BUS_TYPE_UNIX_FD: {
855 fd = fcntl(z, F_DUPFD_CLOEXEC, 3);
861 f = realloc(m->fds, sizeof(int) * (m->n_fds + 1));
875 align = bus_type_get_alignment(type);
876 sz = bus_type_get_size(type);
883 a = message_extend_body(m, align, sz);
889 if (type == SD_BUS_TYPE_STRING || type == SD_BUS_TYPE_OBJECT_PATH) {
890 *(uint32_t*) a = sz - 5;
891 memcpy((uint8_t*) a + 4, p, sz - 4);
894 *stored = (const uint8_t*) a + 4;
896 } else if (type == SD_BUS_TYPE_SIGNATURE) {
897 *(uint8_t*) a = sz - 1;
898 memcpy((uint8_t*) a + 1, p, sz - 1);
901 *stored = (const uint8_t*) a + 1;
902 } else if (type == SD_BUS_TYPE_UNIX_FD) {
903 *(uint32_t*) a = fdi;
917 if (c->enclosing != SD_BUS_TYPE_ARRAY)
923 /* Truncate extended signature again */
925 c->signature[c->index] = 0;
928 close_nointr_nofail(fd);
933 int sd_bus_message_append_basic(sd_bus_message *m, char type, const void *p) {
934 return message_append_basic(m, type, p, NULL);
937 static int bus_message_open_array(
939 struct bus_container *c,
940 const char *contents,
941 uint32_t **array_size) {
954 if (!signature_is_single(contents))
957 alignment = bus_type_get_alignment(contents[0]);
961 if (c->signature && c->signature[c->index]) {
963 /* Verify the existing signature */
965 if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
968 if (!startswith(c->signature + c->index + 1, contents))
971 nindex = c->index + 1 + strlen(contents);
973 if (c->enclosing != 0)
976 /* Extend the existing signature */
978 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_ARRAY), contents, NULL);
982 nindex = e - c->signature;
985 saved = m->header->body_size;
986 a = message_extend_body(m, 4, 4);
988 /* Truncate extended signature again */
990 c->signature[c->index] = 0;
996 if (!message_extend_body(m, alignment, 0)) {
997 /* Add alignment between size and first element */
999 c->signature[c->index] = 0;
1001 m->header->body_size = saved;
1005 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1008 /* m->body might have changed so let's readjust a */
1009 a = (uint8_t*) m->body + ((uint8_t*) a - (uint8_t*) b);
1016 static int bus_message_open_variant(
1018 struct bus_container *c,
1019 const char *contents) {
1029 if (!signature_is_single(contents))
1032 if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
1035 if (c->signature && c->signature[c->index]) {
1037 if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
1041 if (c->enclosing != 0)
1044 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_VARIANT), NULL);
1049 l = strlen(contents);
1050 a = message_extend_body(m, 1, 1 + l + 1);
1052 /* Truncate extended signature again */
1054 c->signature[c->index] = 0;
1060 memcpy((uint8_t*) a + 1, contents, l + 1);
1062 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1068 static int bus_message_open_struct(
1070 struct bus_container *c,
1071 const char *contents) {
1080 if (!signature_is_valid(contents, false))
1083 if (c->signature && c->signature[c->index]) {
1086 l = strlen(contents);
1088 if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
1089 !startswith(c->signature + c->index + 1, contents) ||
1090 c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
1093 nindex = c->index + 1 + l + 1;
1095 if (c->enclosing != 0)
1098 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_BEGIN), contents, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_END), NULL);
1102 nindex = e - c->signature;
1105 /* Align contents to 8 byte boundary */
1106 if (!message_extend_body(m, 8, 0)) {
1108 c->signature[c->index] = 0;
1113 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1119 static int bus_message_open_dict_entry(
1121 struct bus_container *c,
1122 const char *contents) {
1130 if (!signature_is_pair(contents))
1133 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1136 if (c->signature && c->signature[c->index]) {
1139 l = strlen(contents);
1141 if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
1142 !startswith(c->signature + c->index + 1, contents) ||
1143 c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
1146 nindex = c->index + 1 + l + 1;
1150 /* Align contents to 8 byte boundary */
1151 if (!message_extend_body(m, 8, 0))
1154 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1160 int sd_bus_message_open_container(
1163 const char *contents) {
1165 struct bus_container *c, *w;
1166 uint32_t *array_size = NULL;
1177 /* Make sure we have space for one more container */
1178 w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
1183 c = message_get_container(m);
1185 signature = strdup(contents);
1189 if (type == SD_BUS_TYPE_ARRAY)
1190 r = bus_message_open_array(m, c, contents, &array_size);
1191 else if (type == SD_BUS_TYPE_VARIANT)
1192 r = bus_message_open_variant(m, c, contents);
1193 else if (type == SD_BUS_TYPE_STRUCT)
1194 r = bus_message_open_struct(m, c, contents);
1195 else if (type == SD_BUS_TYPE_DICT_ENTRY)
1196 r = bus_message_open_dict_entry(m, c, contents);
1205 /* OK, let's fill it in */
1206 w += m->n_containers++;
1207 w->enclosing = type;
1208 w->signature = signature;
1210 w->array_size = array_size;
1216 int sd_bus_message_close_container(sd_bus_message *m) {
1217 struct bus_container *c;
1223 if (m->n_containers <= 0)
1226 c = message_get_container(m);
1227 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1228 if (c->signature && c->signature[c->index] != 0)
1237 static int message_append_ap(
1248 for (t = types; *t; t++) {
1251 case SD_BUS_TYPE_BYTE: {
1254 x = (uint8_t) va_arg(ap, int);
1255 r = sd_bus_message_append_basic(m, *t, &x);
1259 case SD_BUS_TYPE_BOOLEAN:
1260 case SD_BUS_TYPE_INT32:
1261 case SD_BUS_TYPE_UINT32:
1262 case SD_BUS_TYPE_UNIX_FD: {
1265 /* We assume a boolean is the same as int32_t */
1266 assert_cc(sizeof(int32_t) == sizeof(int));
1268 x = va_arg(ap, uint32_t);
1269 r = sd_bus_message_append_basic(m, *t, &x);
1273 case SD_BUS_TYPE_INT16:
1274 case SD_BUS_TYPE_UINT16: {
1277 x = (uint16_t) va_arg(ap, int);
1278 r = sd_bus_message_append_basic(m, *t, &x);
1282 case SD_BUS_TYPE_INT64:
1283 case SD_BUS_TYPE_UINT64:
1284 case SD_BUS_TYPE_DOUBLE: {
1287 x = va_arg(ap, uint64_t);
1288 r = sd_bus_message_append_basic(m, *t, &x);
1292 case SD_BUS_TYPE_STRING:
1293 case SD_BUS_TYPE_OBJECT_PATH:
1294 case SD_BUS_TYPE_SIGNATURE: {
1297 x = va_arg(ap, const char*);
1298 r = sd_bus_message_append_basic(m, *t, x);
1302 case SD_BUS_TYPE_ARRAY: {
1305 r = signature_element_length(t + 1, &k);
1313 memcpy(s, t + 1, k);
1317 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, s);
1321 n = va_arg(ap, unsigned);
1322 for (i = 0; i < n; i++) {
1323 r = message_append_ap(m, s, ap);
1328 r = sd_bus_message_close_container(m);
1334 case SD_BUS_TYPE_VARIANT: {
1337 s = va_arg(ap, const char*);
1341 r = sd_bus_message_open_container(m, SD_BUS_TYPE_VARIANT, s);
1345 r = message_append_ap(m, s, ap);
1349 r = sd_bus_message_close_container(m);
1353 case SD_BUS_TYPE_STRUCT_BEGIN:
1354 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
1357 r = signature_element_length(t, &k);
1364 memcpy(s, t + 1, k - 2);
1367 r = sd_bus_message_open_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
1373 r = message_append_ap(m, s, ap);
1377 r = sd_bus_message_close_container(m);
1394 int sd_bus_message_append(sd_bus_message *m, const char *types, ...) {
1405 va_start(ap, types);
1406 r = message_append_ap(m, types, ap);
1412 static int buffer_peek(const void *p, uint32_t sz, size_t *rindex, size_t align, size_t nbytes, void **r) {
1418 start = ALIGN_TO((size_t) *rindex, align);
1424 /* Verify that padding is 0 */
1425 for (k = *rindex; k < start; k++)
1426 if (((const uint8_t*) p)[k] != 0)
1430 *r = (uint8_t*) p + start;
1437 static bool message_end_of_array(sd_bus_message *m, size_t index) {
1438 struct bus_container *c;
1442 c = message_get_container(m);
1446 return index >= c->begin + BUS_MESSAGE_BSWAP32(m, *c->array_size);
1449 static int message_peek_body(sd_bus_message *m, size_t *rindex, size_t align, size_t nbytes, void **ret) {
1454 if (message_end_of_array(m, *rindex))
1457 return buffer_peek(m->body, BUS_MESSAGE_BODY_SIZE(m), rindex, align, nbytes, ret);
1460 static bool validate_nul(const char *s, size_t l) {
1462 /* Check for NUL chars in the string */
1463 if (memchr(s, 0, l))
1466 /* Check for NUL termination */
1473 static bool validate_string(const char *s, size_t l) {
1475 if (!validate_nul(s, l))
1478 /* Check if valid UTF8 */
1479 if (!utf8_is_valid(s))
1485 static bool validate_signature(const char *s, size_t l) {
1487 if (!validate_nul(s, l))
1490 /* Check if valid signature */
1491 if (!signature_is_valid(s, true))
1497 static bool validate_object_path(const char *s, size_t l) {
1499 if (!validate_nul(s, l))
1502 if (!object_path_is_valid(s))
1508 int sd_bus_message_read_basic(sd_bus_message *m, char type, void *p) {
1509 struct bus_container *c;
1517 if (!bus_type_is_basic(type))
1522 c = message_get_container(m);
1524 if (!c->signature || c->signature[c->index] == 0)
1527 if (c->signature[c->index] != type)
1532 case SD_BUS_TYPE_STRING:
1533 case SD_BUS_TYPE_OBJECT_PATH: {
1538 r = message_peek_body(m, &rindex, 4, 4, &q);
1542 l = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
1543 r = message_peek_body(m, &rindex, 1, l+1, &q);
1549 if (type == SD_BUS_TYPE_OBJECT_PATH) {
1550 if (!validate_object_path(q, l))
1553 if (!validate_string(q, l))
1558 *(const char**) p = q;
1562 case SD_BUS_TYPE_SIGNATURE: {
1567 r = message_peek_body(m, &rindex, 1, 1, &q);
1572 r = message_peek_body(m, &rindex, 1, l+1, &q);
1578 if (!validate_signature(q, l))
1582 *(const char**) p = q;
1587 size_t sz, align, rindex;
1589 align = bus_type_get_alignment(type);
1590 sz = bus_type_get_size(type);
1593 r = message_peek_body(m, &rindex, align, sz, &q);
1599 case SD_BUS_TYPE_BYTE:
1600 *(uint8_t*) p = *(uint8_t*) q;
1603 case SD_BUS_TYPE_BOOLEAN:
1604 *(int*) p = !!*(uint32_t*) q;
1607 case SD_BUS_TYPE_INT16:
1608 case SD_BUS_TYPE_UINT16:
1609 *(uint16_t*) p = BUS_MESSAGE_BSWAP16(m, *(uint16_t*) q);
1612 case SD_BUS_TYPE_INT32:
1613 case SD_BUS_TYPE_UINT32:
1614 *(uint32_t*) p = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
1617 case SD_BUS_TYPE_INT64:
1618 case SD_BUS_TYPE_UINT64:
1619 case SD_BUS_TYPE_DOUBLE:
1620 *(uint64_t*) p = BUS_MESSAGE_BSWAP64(m, *(uint64_t*) q);
1623 case SD_BUS_TYPE_UNIX_FD: {
1627 j = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
1631 copy = fcntl(m->fds[j], F_DUPFD_CLOEXEC, 3);
1640 assert_not_reached("Unknown basic type...");
1649 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1655 static int bus_message_enter_array(
1657 struct bus_container *c,
1658 const char *contents,
1659 uint32_t **array_size) {
1670 if (!signature_is_single(contents))
1673 alignment = bus_type_get_alignment(contents[0]);
1677 if (!c->signature || c->signature[c->index] == 0)
1680 if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
1683 if (!startswith(c->signature + c->index + 1, contents))
1687 r = message_peek_body(m, &rindex, 4, 4, &q);
1691 if (BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q) > BUS_ARRAY_MAX_SIZE)
1694 r = message_peek_body(m, &rindex, alignment, 0, NULL);
1700 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1701 c->index += 1 + strlen(contents);
1705 *array_size = (uint32_t*) q;
1710 static int bus_message_enter_variant(
1712 struct bus_container *c,
1713 const char *contents) {
1724 if (!signature_is_single(contents))
1727 if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
1730 if (!c->signature || c->signature[c->index] == 0)
1733 if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
1737 r = message_peek_body(m, &rindex, 1, 1, &q);
1742 r = message_peek_body(m, &rindex, 1, l+1, &q);
1748 if (!validate_signature(q, l))
1751 if (!streq(q, contents))
1754 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1762 static int bus_message_enter_struct(
1764 struct bus_container *c,
1765 const char *contents) {
1774 if (!signature_is_valid(contents, false))
1777 if (!c->signature || c->signature[c->index] == 0)
1780 l = strlen(contents);
1782 if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
1783 !startswith(c->signature + c->index + 1, contents) ||
1784 c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
1787 r = message_peek_body(m, &m->rindex, 8, 0, NULL);
1791 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1792 c->index += 1 + l + 1;
1797 static int bus_message_enter_dict_entry(
1799 struct bus_container *c,
1800 const char *contents) {
1809 if (!signature_is_pair(contents))
1812 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1815 if (!c->signature || c->signature[c->index] == 0)
1818 l = strlen(contents);
1820 if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
1821 !startswith(c->signature + c->index + 1, contents) ||
1822 c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
1825 r = message_peek_body(m, &m->rindex, 8, 0, NULL);
1829 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1830 c->index += 1 + l + 1;
1835 int sd_bus_message_enter_container(sd_bus_message *m, char type, const char *contents) {
1836 struct bus_container *c, *w;
1837 uint32_t *array_size = NULL;
1849 * We enforce a global limit on container depth, that is much
1850 * higher than the 32 structs and 32 arrays the specification
1851 * mandates. This is simpler to implement for us, and we need
1852 * this only to ensure our container array doesn't grow
1853 * without bounds. We are happy to return any data from a
1854 * message as long as the data itself is valid, even if the
1855 * overall message might be not.
1857 * Note that the message signature is validated when
1858 * parsing the headers, and that validation does check the
1861 * Note that the specification defines no limits on the depth
1862 * of stacked variants, but we do.
1864 if (m->n_containers >= BUS_CONTAINER_DEPTH)
1867 w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
1872 c = message_get_container(m);
1874 if (!c->signature || c->signature[c->index] == 0)
1877 signature = strdup(contents);
1881 if (type == SD_BUS_TYPE_ARRAY)
1882 r = bus_message_enter_array(m, c, contents, &array_size);
1883 else if (type == SD_BUS_TYPE_VARIANT)
1884 r = bus_message_enter_variant(m, c, contents);
1885 else if (type == SD_BUS_TYPE_STRUCT)
1886 r = bus_message_enter_struct(m, c, contents);
1887 else if (type == SD_BUS_TYPE_DICT_ENTRY)
1888 r = bus_message_enter_dict_entry(m, c, contents);
1897 /* OK, let's fill it in */
1898 w += m->n_containers++;
1899 w->enclosing = type;
1900 w->signature = signature;
1902 w->array_size = array_size;
1903 w->begin = m->rindex;
1908 int sd_bus_message_exit_container(sd_bus_message *m) {
1909 struct bus_container *c;
1915 if (m->n_containers <= 0)
1918 c = message_get_container(m);
1919 if (c->enclosing == SD_BUS_TYPE_ARRAY) {
1922 l = BUS_MESSAGE_BSWAP32(m, *c->array_size);
1923 if (c->begin + l != m->rindex)
1927 if (c->signature && c->signature[c->index] != 0)
1937 int sd_bus_message_peek_type(sd_bus_message *m, char *type, const char **contents) {
1938 struct bus_container *c;
1946 c = message_get_container(m);
1948 if (!c->signature || c->signature[c->index] == 0)
1951 if (message_end_of_array(m, m->rindex))
1954 if (bus_type_is_basic(c->signature[c->index])) {
1958 *type = c->signature[c->index];
1962 if (c->signature[c->index] == SD_BUS_TYPE_ARRAY) {
1968 r = signature_element_length(c->signature+c->index+1, &l);
1974 sig = strndup(c->signature + c->index + 1, l);
1978 free(m->peeked_signature);
1979 m->peeked_signature = sig;
1985 *type = SD_BUS_TYPE_ARRAY;
1990 if (c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ||
1991 c->signature[c->index] == SD_BUS_TYPE_DICT_ENTRY_BEGIN) {
1997 r = signature_element_length(c->signature+c->index, &l);
2002 sig = strndup(c->signature + c->index + 1, l - 2);
2006 free(m->peeked_signature);
2007 m->peeked_signature = sig;
2013 *type = c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY;
2018 if (c->signature[c->index] == SD_BUS_TYPE_VARIANT) {
2024 r = message_peek_body(m, &rindex, 1, 1, &q);
2031 r = message_peek_body(m, &rindex, 1, l+1, &q);
2037 if (!validate_signature(q, l))
2044 *type = SD_BUS_TYPE_VARIANT;
2053 *type = c->enclosing;
2059 int sd_bus_message_rewind(sd_bus_message *m, int complete) {
2060 struct bus_container *c;
2068 reset_containers(m);
2070 m->root_container.index = 0;
2072 c = message_get_container(m);
2074 c = message_get_container(m);
2077 m->rindex = c->begin;
2080 return !isempty(c->signature);
2083 static int message_read_ap(sd_bus_message *m, const char *types, va_list ap) {
2090 for (t = types; *t; t++) {
2093 case SD_BUS_TYPE_BYTE:
2094 case SD_BUS_TYPE_BOOLEAN:
2095 case SD_BUS_TYPE_INT16:
2096 case SD_BUS_TYPE_UINT16:
2097 case SD_BUS_TYPE_INT32:
2098 case SD_BUS_TYPE_UINT32:
2099 case SD_BUS_TYPE_INT64:
2100 case SD_BUS_TYPE_UINT64:
2101 case SD_BUS_TYPE_DOUBLE:
2102 case SD_BUS_TYPE_STRING:
2103 case SD_BUS_TYPE_OBJECT_PATH:
2104 case SD_BUS_TYPE_SIGNATURE:
2105 case SD_BUS_TYPE_UNIX_FD: {
2108 p = va_arg(ap, void*);
2109 r = sd_bus_message_read_basic(m, *t, p);
2113 case SD_BUS_TYPE_ARRAY: {
2116 r = signature_element_length(t + 1, &k);
2124 memcpy(s, t + 1, k);
2128 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, s);
2134 n = va_arg(ap, unsigned);
2135 for (i = 0; i < n; i++) {
2136 r = message_read_ap(m, s, ap);
2141 r = sd_bus_message_exit_container(m);
2147 case SD_BUS_TYPE_VARIANT: {
2150 s = va_arg(ap, const char *);
2154 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, s);
2160 r = message_read_ap(m, s, ap);
2166 r = sd_bus_message_exit_container(m);
2170 case SD_BUS_TYPE_STRUCT_BEGIN:
2171 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
2174 r = signature_element_length(t, &k);
2180 memcpy(s, t + 1, k - 2);
2183 r = sd_bus_message_enter_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
2191 r = message_read_ap(m, s, ap);
2197 r = sd_bus_message_exit_container(m);
2216 int sd_bus_message_read(sd_bus_message *m, const char *types, ...) {
2227 va_start(ap, types);
2228 r = message_read_ap(m, types, ap);
2234 static int message_peek_fields(
2245 return buffer_peek(m->fields, BUS_MESSAGE_FIELDS_SIZE(m), rindex, align, nbytes, ret);
2248 static int message_peek_field_uint32(
2259 r = message_peek_fields(m, ri, 4, 4, &q);
2264 *ret = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2269 static int message_peek_field_string(
2271 bool (*validate)(const char *p),
2282 r = message_peek_field_uint32(m, ri, &l);
2286 r = message_peek_fields(m, ri, 1, l+1, &q);
2291 if (!validate_nul(q, l))
2297 if (!validate_string(q, l))
2307 static int message_peek_field_signature(
2319 r = message_peek_fields(m, ri, 1, 1, &q);
2324 r = message_peek_fields(m, ri, 1, l+1, &q);
2328 if (!validate_signature(q, l))
2337 static int message_skip_fields(
2340 uint32_t array_size,
2341 const char **signature) {
2343 size_t original_index;
2350 original_index = *ri;
2356 if (array_size != (uint32_t) -1 &&
2357 array_size <= *ri - original_index)
2364 if (t == SD_BUS_TYPE_STRING) {
2366 r = message_peek_field_string(m, NULL, ri, NULL);
2372 } else if (t == SD_BUS_TYPE_OBJECT_PATH) {
2374 r = message_peek_field_string(m, object_path_is_valid, ri, NULL);
2380 } else if (t == SD_BUS_TYPE_SIGNATURE) {
2382 r = message_peek_field_signature(m, ri, NULL);
2388 } else if (bus_type_is_basic(t)) {
2391 align = bus_type_get_alignment(t);
2392 k = bus_type_get_size(t);
2394 r = message_peek_fields(m, ri, align, k, NULL);
2400 } else if (t == SD_BUS_TYPE_ARRAY) {
2402 r = signature_element_length(*signature+1, &l);
2412 strncpy(sig, *signature + 1, l-1);
2415 alignment = bus_type_get_alignment(sig[0]);
2419 r = message_peek_field_uint32(m, ri, &nas);
2422 if (nas > BUS_ARRAY_MAX_SIZE)
2425 r = message_peek_fields(m, ri, alignment, 0, NULL);
2429 r = message_skip_fields(m, ri, nas, (const char**) &s);
2434 (*signature) += 1 + l;
2436 } else if (t == SD_BUS_TYPE_VARIANT) {
2439 r = message_peek_field_signature(m, ri, &s);
2443 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
2449 } else if (t == SD_BUS_TYPE_STRUCT ||
2450 t == SD_BUS_TYPE_DICT_ENTRY) {
2452 r = signature_element_length(*signature, &l);
2459 strncpy(sig, *signature + 1, l-1);
2462 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
2473 static int message_parse_fields(sd_bus_message *m) {
2476 uint32_t unix_fds = 0;
2480 for (ri = 0; ri < BUS_MESSAGE_FIELDS_SIZE(m); ) {
2481 const char *signature;
2484 r = message_peek_fields(m, &ri, 8, 1, (void**) &header);
2488 r = message_peek_field_signature(m, &ri, &signature);
2493 case _SD_BUS_MESSAGE_HEADER_INVALID:
2496 case SD_BUS_MESSAGE_HEADER_PATH:
2501 if (!streq(signature, "o"))
2504 r = message_peek_field_string(m, object_path_is_valid, &ri, &m->path);
2507 case SD_BUS_MESSAGE_HEADER_INTERFACE:
2512 if (!streq(signature, "s"))
2515 r = message_peek_field_string(m, interface_name_is_valid, &ri, &m->interface);
2518 case SD_BUS_MESSAGE_HEADER_MEMBER:
2523 if (!streq(signature, "s"))
2526 r = message_peek_field_string(m, member_name_is_valid, &ri, &m->member);
2529 case SD_BUS_MESSAGE_HEADER_ERROR_NAME:
2534 if (!streq(signature, "s"))
2537 r = message_peek_field_string(m, error_name_is_valid, &ri, &m->error.name);
2540 case SD_BUS_MESSAGE_HEADER_DESTINATION:
2545 if (!streq(signature, "s"))
2548 r = message_peek_field_string(m, service_name_is_valid, &ri, &m->destination);
2551 case SD_BUS_MESSAGE_HEADER_SENDER:
2556 if (!streq(signature, "s"))
2559 r = message_peek_field_string(m, service_name_is_valid, &ri, &m->sender);
2563 case SD_BUS_MESSAGE_HEADER_SIGNATURE: {
2567 if (m->root_container.signature)
2570 if (!streq(signature, "g"))
2573 r = message_peek_field_signature(m, &ri, &s);
2581 free(m->root_container.signature);
2582 m->root_container.signature = c;
2586 case SD_BUS_MESSAGE_HEADER_REPLY_SERIAL:
2587 if (m->reply_serial != 0)
2590 if (!streq(signature, "u"))
2593 r = message_peek_field_uint32(m, &ri, &m->reply_serial);
2597 if (m->reply_serial == 0)
2602 case SD_BUS_MESSAGE_HEADER_UNIX_FDS:
2606 if (!streq(signature, "u"))
2609 r = message_peek_field_uint32(m, &ri, &unix_fds);
2619 r = message_skip_fields(m, &ri, (uint32_t) -1, (const char **) &signature);
2626 if (m->n_fds != unix_fds)
2629 if (isempty(m->root_container.signature) != (BUS_MESSAGE_BODY_SIZE(m) == 0))
2632 switch (m->header->type) {
2634 case SD_BUS_MESSAGE_TYPE_SIGNAL:
2635 if (!m->path || !m->interface || !m->member)
2639 case SD_BUS_MESSAGE_TYPE_METHOD_CALL:
2641 if (!m->path || !m->member)
2646 case SD_BUS_MESSAGE_TYPE_METHOD_RETURN:
2648 if (m->reply_serial == 0)
2652 case SD_BUS_MESSAGE_TYPE_METHOD_ERROR:
2654 if (m->reply_serial == 0 || !m->error.name)
2659 /* Try to read the error message, but if we can't it's a non-issue */
2660 if (m->header->type == SD_BUS_MESSAGE_TYPE_METHOD_ERROR)
2661 sd_bus_message_read(m, "s", &m->error.message);
2666 static void setup_iovec(sd_bus_message *m) {
2673 m->iovec[m->n_iovec].iov_base = m->header;
2674 m->iovec[m->n_iovec].iov_len = sizeof(*m->header);
2675 m->size += m->iovec[m->n_iovec].iov_len;
2679 m->iovec[m->n_iovec].iov_base = m->fields;
2680 m->iovec[m->n_iovec].iov_len = m->header->fields_size;
2681 m->size += m->iovec[m->n_iovec].iov_len;
2684 if (m->header->fields_size % 8 != 0) {
2685 static const uint8_t padding[7] = { 0, 0, 0, 0, 0, 0, 0 };
2687 m->iovec[m->n_iovec].iov_base = (void*) padding;
2688 m->iovec[m->n_iovec].iov_len = 8 - m->header->fields_size % 8;
2689 m->size += m->iovec[m->n_iovec].iov_len;
2695 m->iovec[m->n_iovec].iov_base = m->body;
2696 m->iovec[m->n_iovec].iov_len = m->header->body_size;
2697 m->size += m->iovec[m->n_iovec].iov_len;
2702 int bus_message_seal(sd_bus_message *m, uint64_t serial) {
2710 if (m->n_containers > 0)
2713 /* If there's a non-trivial signature set, then add it in here */
2714 if (!isempty(m->root_container.signature)) {
2715 r = message_append_field_signature(m, SD_BUS_MESSAGE_HEADER_SIGNATURE, m->root_container.signature, NULL);
2721 r = message_append_field_uint32(m, SD_BUS_MESSAGE_HEADER_UNIX_FDS, m->n_fds);
2726 m->header->serial = serial;
2734 int sd_bus_message_set_destination(sd_bus_message *m, const char *destination) {
2744 return message_append_field_string(m, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &m->destination);
2747 int bus_message_dump(sd_bus_message *m) {
2753 printf("Message %p\n"
2760 "\tfields_size=%u\n"
2765 "\tdestination=%s\n"
2768 "\treply_serial=%u\n"
2770 "\terror.message=%s\n"
2778 BUS_MESSAGE_SERIAL(m),
2779 BUS_MESSAGE_FIELDS_SIZE(m),
2780 BUS_MESSAGE_BODY_SIZE(m),
2782 strna(m->interface),
2784 strna(m->destination),
2786 strna(m->root_container.signature),
2788 strna(m->error.name),
2789 strna(m->error.message),
2792 r = sd_bus_message_rewind(m, true);
2794 log_error("Failed to rewind: %s", strerror(-r));
2798 printf("BEGIN_MESSAGE \"%s\" {\n", strempty(m->root_container.signature));
2801 _cleanup_free_ char *prefix = NULL;
2802 const char *contents = NULL;
2817 r = sd_bus_message_peek_type(m, &type, &contents);
2819 log_error("Failed to peek type: %s", strerror(-r));
2826 r = sd_bus_message_exit_container(m);
2828 log_error("Failed to exit container: %s", strerror(-r));
2834 prefix = strrep("\t", level);
2838 if (type == SD_BUS_TYPE_ARRAY)
2839 printf("%s} END_ARRAY \n", prefix);
2840 else if (type == SD_BUS_TYPE_VARIANT)
2841 printf("%s} END_VARIANT\n", prefix);
2842 else if (type == SD_BUS_TYPE_STRUCT)
2843 printf("%s} END_STRUCT\n", prefix);
2844 else if (type == SD_BUS_TYPE_DICT_ENTRY)
2845 printf("%s} END_DICT_ENTRY\n", prefix);
2850 prefix = strrep("\t", level);
2854 if (bus_type_is_container(type) > 0) {
2855 r = sd_bus_message_enter_container(m, type, contents);
2857 log_error("Failed to enter container: %s", strerror(-r));
2861 if (type == SD_BUS_TYPE_ARRAY)
2862 printf("%sBEGIN_ARRAY \"%s\" {\n", prefix, contents);
2863 else if (type == SD_BUS_TYPE_VARIANT)
2864 printf("%sBEGIN_VARIANT \"%s\" {\n", prefix, contents);
2865 else if (type == SD_BUS_TYPE_STRUCT)
2866 printf("%sBEGIN_STRUCT \"%s\" {\n", prefix, contents);
2867 else if (type == SD_BUS_TYPE_DICT_ENTRY)
2868 printf("%sBEGIN_DICT_ENTRY \"%s\" {\n", prefix, contents);
2875 r = sd_bus_message_read_basic(m, type, &basic);
2877 log_error("Failed to get basic: %s", strerror(-r));
2883 case SD_BUS_TYPE_BYTE:
2884 printf("%sBYTE: %u\n", prefix, basic.u8);
2887 case SD_BUS_TYPE_BOOLEAN:
2888 printf("%sBOOLEAN: %s\n", prefix, yes_no(basic.i));
2891 case SD_BUS_TYPE_INT16:
2892 printf("%sINT16: %i\n", prefix, basic.s16);
2895 case SD_BUS_TYPE_UINT16:
2896 printf("%sUINT16: %u\n", prefix, basic.u16);
2899 case SD_BUS_TYPE_INT32:
2900 printf("%sINT32: %i\n", prefix, basic.s32);
2903 case SD_BUS_TYPE_UINT32:
2904 printf("%sUINT32: %u\n", prefix, basic.u32);
2907 case SD_BUS_TYPE_INT64:
2908 printf("%sINT64: %lli\n", prefix, (long long) basic.s64);
2911 case SD_BUS_TYPE_UINT64:
2912 printf("%sUINT64: %llu\n", prefix, (unsigned long long) basic.u64);
2915 case SD_BUS_TYPE_DOUBLE:
2916 printf("%sDOUBLE: %g\n", prefix, basic.d64);
2919 case SD_BUS_TYPE_STRING:
2920 printf("%sSTRING: \"%s\"\n", prefix, basic.string);
2923 case SD_BUS_TYPE_OBJECT_PATH:
2924 printf("%sOBJECT_PATH: \"%s\"\n", prefix, basic.string);
2927 case SD_BUS_TYPE_SIGNATURE:
2928 printf("%sSIGNATURE: \"%s\"\n", prefix, basic.string);
2931 case SD_BUS_TYPE_UNIX_FD:
2932 printf("%sUNIX_FD: %i\n", prefix, basic.i);
2936 assert_not_reached("Unknown basic type.");
2940 printf("} END_MESSAGE\n");
2944 int bus_message_get_blob(sd_bus_message *m, void **buffer, size_t *sz) {
2953 for (i = 0, total = 0; i < m->n_iovec; i++)
2954 total += m->iovec[i].iov_len;
2960 for (i = 0, e = p; i < m->n_iovec; i++)
2961 e = mempcpy(e, m->iovec[i].iov_base, m->iovec[i].iov_len);
2969 int bus_message_read_strv_extend(sd_bus_message *m, char ***l) {
2975 r = sd_bus_message_enter_container(m, 'a', "s");
2982 r = sd_bus_message_read_basic(m, 's', &s);
2988 r = strv_extend(l, s);
2993 r = sd_bus_message_exit_container(m);