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;
1596 align = bus_type_get_alignment(type);
1597 sz = bus_type_get_size(type);
1598 assert(align > 0 && sz > 0);
1601 r = message_peek_body(m, &rindex, align, sz, &q);
1607 case SD_BUS_TYPE_BYTE:
1608 *(uint8_t*) p = *(uint8_t*) q;
1611 case SD_BUS_TYPE_BOOLEAN:
1612 *(int*) p = !!*(uint32_t*) q;
1615 case SD_BUS_TYPE_INT16:
1616 case SD_BUS_TYPE_UINT16:
1617 *(uint16_t*) p = BUS_MESSAGE_BSWAP16(m, *(uint16_t*) q);
1620 case SD_BUS_TYPE_INT32:
1621 case SD_BUS_TYPE_UINT32:
1622 *(uint32_t*) p = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
1625 case SD_BUS_TYPE_INT64:
1626 case SD_BUS_TYPE_UINT64:
1627 case SD_BUS_TYPE_DOUBLE:
1628 *(uint64_t*) p = BUS_MESSAGE_BSWAP64(m, *(uint64_t*) q);
1631 case SD_BUS_TYPE_UNIX_FD: {
1635 j = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
1639 copy = fcntl(m->fds[j], F_DUPFD_CLOEXEC, 3);
1648 assert_not_reached("Unknown basic type...");
1657 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1663 static int bus_message_enter_array(
1665 struct bus_container *c,
1666 const char *contents,
1667 uint32_t **array_size) {
1678 if (!signature_is_single(contents))
1681 alignment = bus_type_get_alignment(contents[0]);
1685 if (!c->signature || c->signature[c->index] == 0)
1688 if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
1691 if (!startswith(c->signature + c->index + 1, contents))
1695 r = message_peek_body(m, &rindex, 4, 4, &q);
1699 if (BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q) > BUS_ARRAY_MAX_SIZE)
1702 r = message_peek_body(m, &rindex, alignment, 0, NULL);
1708 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1709 c->index += 1 + strlen(contents);
1713 *array_size = (uint32_t*) q;
1718 static int bus_message_enter_variant(
1720 struct bus_container *c,
1721 const char *contents) {
1732 if (!signature_is_single(contents))
1735 if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
1738 if (!c->signature || c->signature[c->index] == 0)
1741 if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
1745 r = message_peek_body(m, &rindex, 1, 1, &q);
1750 r = message_peek_body(m, &rindex, 1, l+1, &q);
1756 if (!validate_signature(q, l))
1759 if (!streq(q, contents))
1762 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1770 static int bus_message_enter_struct(
1772 struct bus_container *c,
1773 const char *contents) {
1782 if (!signature_is_valid(contents, false))
1785 if (!c->signature || c->signature[c->index] == 0)
1788 l = strlen(contents);
1790 if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
1791 !startswith(c->signature + c->index + 1, contents) ||
1792 c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
1795 r = message_peek_body(m, &m->rindex, 8, 0, NULL);
1799 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1800 c->index += 1 + l + 1;
1805 static int bus_message_enter_dict_entry(
1807 struct bus_container *c,
1808 const char *contents) {
1817 if (!signature_is_pair(contents))
1820 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1823 if (!c->signature || c->signature[c->index] == 0)
1826 l = strlen(contents);
1828 if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
1829 !startswith(c->signature + c->index + 1, contents) ||
1830 c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
1833 r = message_peek_body(m, &m->rindex, 8, 0, NULL);
1837 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1838 c->index += 1 + l + 1;
1843 int sd_bus_message_enter_container(sd_bus_message *m, char type, const char *contents) {
1844 struct bus_container *c, *w;
1845 uint32_t *array_size = NULL;
1857 * We enforce a global limit on container depth, that is much
1858 * higher than the 32 structs and 32 arrays the specification
1859 * mandates. This is simpler to implement for us, and we need
1860 * this only to ensure our container array doesn't grow
1861 * without bounds. We are happy to return any data from a
1862 * message as long as the data itself is valid, even if the
1863 * overall message might be not.
1865 * Note that the message signature is validated when
1866 * parsing the headers, and that validation does check the
1869 * Note that the specification defines no limits on the depth
1870 * of stacked variants, but we do.
1872 if (m->n_containers >= BUS_CONTAINER_DEPTH)
1875 w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
1880 c = message_get_container(m);
1882 if (!c->signature || c->signature[c->index] == 0)
1885 signature = strdup(contents);
1889 if (type == SD_BUS_TYPE_ARRAY)
1890 r = bus_message_enter_array(m, c, contents, &array_size);
1891 else if (type == SD_BUS_TYPE_VARIANT)
1892 r = bus_message_enter_variant(m, c, contents);
1893 else if (type == SD_BUS_TYPE_STRUCT)
1894 r = bus_message_enter_struct(m, c, contents);
1895 else if (type == SD_BUS_TYPE_DICT_ENTRY)
1896 r = bus_message_enter_dict_entry(m, c, contents);
1905 /* OK, let's fill it in */
1906 w += m->n_containers++;
1907 w->enclosing = type;
1908 w->signature = signature;
1910 w->array_size = array_size;
1911 w->begin = m->rindex;
1916 int sd_bus_message_exit_container(sd_bus_message *m) {
1917 struct bus_container *c;
1923 if (m->n_containers <= 0)
1926 c = message_get_container(m);
1927 if (c->enclosing == SD_BUS_TYPE_ARRAY) {
1930 l = BUS_MESSAGE_BSWAP32(m, *c->array_size);
1931 if (c->begin + l != m->rindex)
1935 if (c->signature && c->signature[c->index] != 0)
1945 int sd_bus_message_peek_type(sd_bus_message *m, char *type, const char **contents) {
1946 struct bus_container *c;
1954 c = message_get_container(m);
1956 if (!c->signature || c->signature[c->index] == 0)
1959 if (message_end_of_array(m, m->rindex))
1962 if (bus_type_is_basic(c->signature[c->index])) {
1966 *type = c->signature[c->index];
1970 if (c->signature[c->index] == SD_BUS_TYPE_ARRAY) {
1976 r = signature_element_length(c->signature+c->index+1, &l);
1982 sig = strndup(c->signature + c->index + 1, l);
1986 free(m->peeked_signature);
1987 m->peeked_signature = sig;
1993 *type = SD_BUS_TYPE_ARRAY;
1998 if (c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ||
1999 c->signature[c->index] == SD_BUS_TYPE_DICT_ENTRY_BEGIN) {
2005 r = signature_element_length(c->signature+c->index, &l);
2010 sig = strndup(c->signature + c->index + 1, l - 2);
2014 free(m->peeked_signature);
2015 m->peeked_signature = sig;
2021 *type = c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY;
2026 if (c->signature[c->index] == SD_BUS_TYPE_VARIANT) {
2032 r = message_peek_body(m, &rindex, 1, 1, &q);
2039 r = message_peek_body(m, &rindex, 1, l+1, &q);
2045 if (!validate_signature(q, l))
2052 *type = SD_BUS_TYPE_VARIANT;
2061 *type = c->enclosing;
2067 int sd_bus_message_rewind(sd_bus_message *m, int complete) {
2068 struct bus_container *c;
2076 reset_containers(m);
2078 m->root_container.index = 0;
2080 c = message_get_container(m);
2082 c = message_get_container(m);
2085 m->rindex = c->begin;
2088 return !isempty(c->signature);
2091 static int message_read_ap(sd_bus_message *m, const char *types, va_list ap) {
2098 for (t = types; *t; t++) {
2101 case SD_BUS_TYPE_BYTE:
2102 case SD_BUS_TYPE_BOOLEAN:
2103 case SD_BUS_TYPE_INT16:
2104 case SD_BUS_TYPE_UINT16:
2105 case SD_BUS_TYPE_INT32:
2106 case SD_BUS_TYPE_UINT32:
2107 case SD_BUS_TYPE_INT64:
2108 case SD_BUS_TYPE_UINT64:
2109 case SD_BUS_TYPE_DOUBLE:
2110 case SD_BUS_TYPE_STRING:
2111 case SD_BUS_TYPE_OBJECT_PATH:
2112 case SD_BUS_TYPE_SIGNATURE:
2113 case SD_BUS_TYPE_UNIX_FD: {
2116 p = va_arg(ap, void*);
2117 r = sd_bus_message_read_basic(m, *t, p);
2121 case SD_BUS_TYPE_ARRAY: {
2124 r = signature_element_length(t + 1, &k);
2132 memcpy(s, t + 1, k);
2136 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, s);
2142 n = va_arg(ap, unsigned);
2143 for (i = 0; i < n; i++) {
2144 r = message_read_ap(m, s, ap);
2149 r = sd_bus_message_exit_container(m);
2155 case SD_BUS_TYPE_VARIANT: {
2158 s = va_arg(ap, const char *);
2162 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, s);
2168 r = message_read_ap(m, s, ap);
2174 r = sd_bus_message_exit_container(m);
2178 case SD_BUS_TYPE_STRUCT_BEGIN:
2179 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
2182 r = signature_element_length(t, &k);
2188 memcpy(s, t + 1, k - 2);
2191 r = sd_bus_message_enter_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
2199 r = message_read_ap(m, s, ap);
2205 r = sd_bus_message_exit_container(m);
2224 int sd_bus_message_read(sd_bus_message *m, const char *types, ...) {
2235 va_start(ap, types);
2236 r = message_read_ap(m, types, ap);
2242 static int message_peek_fields(
2253 return buffer_peek(m->fields, BUS_MESSAGE_FIELDS_SIZE(m), rindex, align, nbytes, ret);
2256 static int message_peek_field_uint32(
2267 r = message_peek_fields(m, ri, 4, 4, &q);
2272 *ret = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2277 static int message_peek_field_string(
2279 bool (*validate)(const char *p),
2290 r = message_peek_field_uint32(m, ri, &l);
2294 r = message_peek_fields(m, ri, 1, l+1, &q);
2299 if (!validate_nul(q, l))
2305 if (!validate_string(q, l))
2315 static int message_peek_field_signature(
2327 r = message_peek_fields(m, ri, 1, 1, &q);
2332 r = message_peek_fields(m, ri, 1, l+1, &q);
2336 if (!validate_signature(q, l))
2345 static int message_skip_fields(
2348 uint32_t array_size,
2349 const char **signature) {
2351 size_t original_index;
2358 original_index = *ri;
2364 if (array_size != (uint32_t) -1 &&
2365 array_size <= *ri - original_index)
2372 if (t == SD_BUS_TYPE_STRING) {
2374 r = message_peek_field_string(m, NULL, ri, NULL);
2380 } else if (t == SD_BUS_TYPE_OBJECT_PATH) {
2382 r = message_peek_field_string(m, object_path_is_valid, ri, NULL);
2388 } else if (t == SD_BUS_TYPE_SIGNATURE) {
2390 r = message_peek_field_signature(m, ri, NULL);
2396 } else if (bus_type_is_basic(t)) {
2399 align = bus_type_get_alignment(t);
2400 k = bus_type_get_size(t);
2401 assert(align > 0 && k > 0);
2403 r = message_peek_fields(m, ri, align, k, NULL);
2409 } else if (t == SD_BUS_TYPE_ARRAY) {
2411 r = signature_element_length(*signature+1, &l);
2421 strncpy(sig, *signature + 1, l-1);
2424 alignment = bus_type_get_alignment(sig[0]);
2428 r = message_peek_field_uint32(m, ri, &nas);
2431 if (nas > BUS_ARRAY_MAX_SIZE)
2434 r = message_peek_fields(m, ri, alignment, 0, NULL);
2438 r = message_skip_fields(m, ri, nas, (const char**) &s);
2443 (*signature) += 1 + l;
2445 } else if (t == SD_BUS_TYPE_VARIANT) {
2448 r = message_peek_field_signature(m, ri, &s);
2452 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
2458 } else if (t == SD_BUS_TYPE_STRUCT ||
2459 t == SD_BUS_TYPE_DICT_ENTRY) {
2461 r = signature_element_length(*signature, &l);
2468 strncpy(sig, *signature + 1, l-1);
2471 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
2482 static int message_parse_fields(sd_bus_message *m) {
2485 uint32_t unix_fds = 0;
2489 for (ri = 0; ri < BUS_MESSAGE_FIELDS_SIZE(m); ) {
2490 const char *signature;
2493 r = message_peek_fields(m, &ri, 8, 1, (void**) &header);
2497 r = message_peek_field_signature(m, &ri, &signature);
2502 case _SD_BUS_MESSAGE_HEADER_INVALID:
2505 case SD_BUS_MESSAGE_HEADER_PATH:
2510 if (!streq(signature, "o"))
2513 r = message_peek_field_string(m, object_path_is_valid, &ri, &m->path);
2516 case SD_BUS_MESSAGE_HEADER_INTERFACE:
2521 if (!streq(signature, "s"))
2524 r = message_peek_field_string(m, interface_name_is_valid, &ri, &m->interface);
2527 case SD_BUS_MESSAGE_HEADER_MEMBER:
2532 if (!streq(signature, "s"))
2535 r = message_peek_field_string(m, member_name_is_valid, &ri, &m->member);
2538 case SD_BUS_MESSAGE_HEADER_ERROR_NAME:
2543 if (!streq(signature, "s"))
2546 r = message_peek_field_string(m, error_name_is_valid, &ri, &m->error.name);
2549 case SD_BUS_MESSAGE_HEADER_DESTINATION:
2554 if (!streq(signature, "s"))
2557 r = message_peek_field_string(m, service_name_is_valid, &ri, &m->destination);
2560 case SD_BUS_MESSAGE_HEADER_SENDER:
2565 if (!streq(signature, "s"))
2568 r = message_peek_field_string(m, service_name_is_valid, &ri, &m->sender);
2572 case SD_BUS_MESSAGE_HEADER_SIGNATURE: {
2576 if (m->root_container.signature)
2579 if (!streq(signature, "g"))
2582 r = message_peek_field_signature(m, &ri, &s);
2590 free(m->root_container.signature);
2591 m->root_container.signature = c;
2595 case SD_BUS_MESSAGE_HEADER_REPLY_SERIAL:
2596 if (m->reply_serial != 0)
2599 if (!streq(signature, "u"))
2602 r = message_peek_field_uint32(m, &ri, &m->reply_serial);
2606 if (m->reply_serial == 0)
2611 case SD_BUS_MESSAGE_HEADER_UNIX_FDS:
2615 if (!streq(signature, "u"))
2618 r = message_peek_field_uint32(m, &ri, &unix_fds);
2628 r = message_skip_fields(m, &ri, (uint32_t) -1, (const char **) &signature);
2635 if (m->n_fds != unix_fds)
2638 if (isempty(m->root_container.signature) != (BUS_MESSAGE_BODY_SIZE(m) == 0))
2641 switch (m->header->type) {
2643 case SD_BUS_MESSAGE_TYPE_SIGNAL:
2644 if (!m->path || !m->interface || !m->member)
2648 case SD_BUS_MESSAGE_TYPE_METHOD_CALL:
2650 if (!m->path || !m->member)
2655 case SD_BUS_MESSAGE_TYPE_METHOD_RETURN:
2657 if (m->reply_serial == 0)
2661 case SD_BUS_MESSAGE_TYPE_METHOD_ERROR:
2663 if (m->reply_serial == 0 || !m->error.name)
2668 /* Try to read the error message, but if we can't it's a non-issue */
2669 if (m->header->type == SD_BUS_MESSAGE_TYPE_METHOD_ERROR)
2670 sd_bus_message_read(m, "s", &m->error.message);
2675 static void setup_iovec(sd_bus_message *m) {
2682 m->iovec[m->n_iovec].iov_base = m->header;
2683 m->iovec[m->n_iovec].iov_len = sizeof(*m->header);
2684 m->size += m->iovec[m->n_iovec].iov_len;
2688 m->iovec[m->n_iovec].iov_base = m->fields;
2689 m->iovec[m->n_iovec].iov_len = m->header->fields_size;
2690 m->size += m->iovec[m->n_iovec].iov_len;
2693 if (m->header->fields_size % 8 != 0) {
2694 static const uint8_t padding[7] = { 0, 0, 0, 0, 0, 0, 0 };
2696 m->iovec[m->n_iovec].iov_base = (void*) padding;
2697 m->iovec[m->n_iovec].iov_len = 8 - m->header->fields_size % 8;
2698 m->size += m->iovec[m->n_iovec].iov_len;
2704 m->iovec[m->n_iovec].iov_base = m->body;
2705 m->iovec[m->n_iovec].iov_len = m->header->body_size;
2706 m->size += m->iovec[m->n_iovec].iov_len;
2711 int bus_message_seal(sd_bus_message *m, uint64_t serial) {
2719 if (m->n_containers > 0)
2722 /* If there's a non-trivial signature set, then add it in here */
2723 if (!isempty(m->root_container.signature)) {
2724 r = message_append_field_signature(m, SD_BUS_MESSAGE_HEADER_SIGNATURE, m->root_container.signature, NULL);
2730 r = message_append_field_uint32(m, SD_BUS_MESSAGE_HEADER_UNIX_FDS, m->n_fds);
2735 m->header->serial = serial;
2743 int sd_bus_message_set_destination(sd_bus_message *m, const char *destination) {
2753 return message_append_field_string(m, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &m->destination);
2756 int bus_message_dump(sd_bus_message *m) {
2762 printf("Message %p\n"
2769 "\tfields_size=%u\n"
2774 "\tdestination=%s\n"
2777 "\treply_serial=%u\n"
2779 "\terror.message=%s\n"
2787 BUS_MESSAGE_SERIAL(m),
2788 BUS_MESSAGE_FIELDS_SIZE(m),
2789 BUS_MESSAGE_BODY_SIZE(m),
2791 strna(m->interface),
2793 strna(m->destination),
2795 strna(m->root_container.signature),
2797 strna(m->error.name),
2798 strna(m->error.message),
2801 r = sd_bus_message_rewind(m, true);
2803 log_error("Failed to rewind: %s", strerror(-r));
2807 printf("BEGIN_MESSAGE \"%s\" {\n", strempty(m->root_container.signature));
2810 _cleanup_free_ char *prefix = NULL;
2811 const char *contents = NULL;
2826 r = sd_bus_message_peek_type(m, &type, &contents);
2828 log_error("Failed to peek type: %s", strerror(-r));
2835 r = sd_bus_message_exit_container(m);
2837 log_error("Failed to exit container: %s", strerror(-r));
2843 prefix = strrep("\t", level);
2847 if (type == SD_BUS_TYPE_ARRAY)
2848 printf("%s} END_ARRAY \n", prefix);
2849 else if (type == SD_BUS_TYPE_VARIANT)
2850 printf("%s} END_VARIANT\n", prefix);
2851 else if (type == SD_BUS_TYPE_STRUCT)
2852 printf("%s} END_STRUCT\n", prefix);
2853 else if (type == SD_BUS_TYPE_DICT_ENTRY)
2854 printf("%s} END_DICT_ENTRY\n", prefix);
2859 prefix = strrep("\t", level);
2863 if (bus_type_is_container(type) > 0) {
2864 r = sd_bus_message_enter_container(m, type, contents);
2866 log_error("Failed to enter container: %s", strerror(-r));
2870 if (type == SD_BUS_TYPE_ARRAY)
2871 printf("%sBEGIN_ARRAY \"%s\" {\n", prefix, contents);
2872 else if (type == SD_BUS_TYPE_VARIANT)
2873 printf("%sBEGIN_VARIANT \"%s\" {\n", prefix, contents);
2874 else if (type == SD_BUS_TYPE_STRUCT)
2875 printf("%sBEGIN_STRUCT \"%s\" {\n", prefix, contents);
2876 else if (type == SD_BUS_TYPE_DICT_ENTRY)
2877 printf("%sBEGIN_DICT_ENTRY \"%s\" {\n", prefix, contents);
2884 r = sd_bus_message_read_basic(m, type, &basic);
2886 log_error("Failed to get basic: %s", strerror(-r));
2892 case SD_BUS_TYPE_BYTE:
2893 printf("%sBYTE: %u\n", prefix, basic.u8);
2896 case SD_BUS_TYPE_BOOLEAN:
2897 printf("%sBOOLEAN: %s\n", prefix, yes_no(basic.i));
2900 case SD_BUS_TYPE_INT16:
2901 printf("%sINT16: %i\n", prefix, basic.s16);
2904 case SD_BUS_TYPE_UINT16:
2905 printf("%sUINT16: %u\n", prefix, basic.u16);
2908 case SD_BUS_TYPE_INT32:
2909 printf("%sINT32: %i\n", prefix, basic.s32);
2912 case SD_BUS_TYPE_UINT32:
2913 printf("%sUINT32: %u\n", prefix, basic.u32);
2916 case SD_BUS_TYPE_INT64:
2917 printf("%sINT64: %lli\n", prefix, (long long) basic.s64);
2920 case SD_BUS_TYPE_UINT64:
2921 printf("%sUINT64: %llu\n", prefix, (unsigned long long) basic.u64);
2924 case SD_BUS_TYPE_DOUBLE:
2925 printf("%sDOUBLE: %g\n", prefix, basic.d64);
2928 case SD_BUS_TYPE_STRING:
2929 printf("%sSTRING: \"%s\"\n", prefix, basic.string);
2932 case SD_BUS_TYPE_OBJECT_PATH:
2933 printf("%sOBJECT_PATH: \"%s\"\n", prefix, basic.string);
2936 case SD_BUS_TYPE_SIGNATURE:
2937 printf("%sSIGNATURE: \"%s\"\n", prefix, basic.string);
2940 case SD_BUS_TYPE_UNIX_FD:
2941 printf("%sUNIX_FD: %i\n", prefix, basic.i);
2945 assert_not_reached("Unknown basic type.");
2949 printf("} END_MESSAGE\n");
2953 int bus_message_get_blob(sd_bus_message *m, void **buffer, size_t *sz) {
2962 for (i = 0, total = 0; i < m->n_iovec; i++)
2963 total += m->iovec[i].iov_len;
2969 for (i = 0, e = p; i < m->n_iovec; i++)
2970 e = mempcpy(e, m->iovec[i].iov_base, m->iovec[i].iov_len);
2978 int bus_message_read_strv_extend(sd_bus_message *m, char ***l) {
2984 r = sd_bus_message_enter_container(m, 'a', "s");
2991 r = sd_bus_message_read_basic(m, 's', &s);
2997 r = strv_extend(l, s);
3002 r = sd_bus_message_exit_container(m);
3009 const char* bus_message_get_arg(sd_bus_message *m, unsigned i) {
3016 r = sd_bus_message_rewind(m, true);
3021 r = sd_bus_message_peek_type(m, &type, NULL);
3025 if (type != SD_BUS_TYPE_STRING &&
3026 type != SD_BUS_TYPE_OBJECT_PATH &&
3027 type != SD_BUS_TYPE_SIGNATURE)
3030 r = sd_bus_message_read_basic(m, type, &t);
3037 r = sd_bus_message_rewind(m, true);