1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2013 Lennart Poettering
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
30 #include "bus-message.h"
31 #include "bus-internal.h"
33 #include "bus-signature.h"
35 static int message_parse_fields(sd_bus_message *m);
36 static int message_append_basic(sd_bus_message *m, char type, const void *p, const void **stored);
38 static void reset_containers(sd_bus_message *m) {
43 for (i = 0; i < m->n_containers; i++)
44 free(m->containers[i].signature);
50 m->root_container.index = 0;
53 static void message_free(sd_bus_message *m) {
66 close_many(m->fds, m->n_fds);
71 free(m->root_container.signature);
73 free(m->peeked_signature);
77 static void* buffer_extend(void **p, uint32_t *sz, size_t align, size_t extend) {
85 start = ALIGN_TO((size_t) *sz, align);
89 return (uint8_t*) *p + start;
91 if (n > (size_t) ((uint32_t) -1))
98 /* Zero out padding */
100 memset((uint8_t*) k + *sz, 0, start - *sz);
105 return (uint8_t*) k + start;
108 static void *message_extend_fields(sd_bus_message *m, size_t align, size_t sz) {
114 p = buffer_extend(&m->fields, &m->header->fields_size, align, sz);
118 if (o != m->fields) {
119 /* Adjust quick access pointers */
122 m->path = (const char*) m->fields + (m->path - (const char*) o);
124 m->interface = (const char*) m->fields + (m->interface - (const char*) o);
126 m->member = (const char*) m->fields + (m->member - (const char*) o);
128 m->destination = (const char*) m->fields + (m->destination - (const char*) o);
130 m->sender = (const char*) m->fields + (m->sender - (const char*) o);
132 m->error.name = (const char*) m->fields + (m->error.name - (const char*) o);
135 m->free_fields = true;
140 static int message_append_field_string(
153 if (l > (size_t) (uint32_t) -1)
156 /* field id byte + signature length + signature 's' + NUL + string length + string + NUL */
157 p = message_extend_fields(m, 8, 4 + 4 + l + 1);
166 ((uint32_t*) p)[1] = l;
167 memcpy(p + 8, s, l + 1);
170 *ret = (const char*) p + 8;
175 static int message_append_field_signature(
190 /* field id byte + signature length + signature 'g' + NUL + string length + string + NUL */
191 p = message_extend_fields(m, 8, 4 + 1 + l + 1);
197 p[2] = SD_BUS_TYPE_SIGNATURE;
200 memcpy(p + 5, s, l + 1);
203 *ret = (const char*) p + 5;
208 static int message_append_field_uint32(sd_bus_message *m, uint8_t h, uint32_t x) {
213 /* field id byte + signature length + signature 'u' + NUL + value */
214 p = message_extend_fields(m, 8, 4 + 4);
220 p[2] = SD_BUS_TYPE_UINT32;
223 ((uint32_t*) p)[1] = x;
228 int bus_message_from_malloc(
233 const struct ucred *ucred,
235 sd_bus_message **ret) {
238 struct bus_header *h;
239 size_t total, fs, bs, label_sz, a;
242 assert(buffer || length <= 0);
243 assert(fds || n_fds <= 0);
246 if (length < sizeof(struct bus_header))
256 if (h->type == _SD_BUS_MESSAGE_TYPE_INVALID)
259 if (h->endian == SD_BUS_NATIVE_ENDIAN) {
262 } else if (h->endian == SD_BUS_REVERSE_ENDIAN) {
263 fs = bswap_32(h->fields_size);
264 bs = bswap_32(h->body_size);
268 total = sizeof(struct bus_header) + ALIGN_TO(fs, 8) + bs;
273 label_sz = strlen(label);
274 a = ALIGN(sizeof(sd_bus_message)) + label_sz + 1;
276 a = sizeof(sd_bus_message);
285 m->fields = (uint8_t*) buffer + sizeof(struct bus_header);
286 m->body = (uint8_t*) buffer + sizeof(struct bus_header) + ALIGN_TO(fs, 8);
294 m->uid_valid = m->gid_valid = true;
298 m->label = (char*) m + ALIGN(sizeof(sd_bus_message));
299 memcpy(m->label, label, label_sz + 1);
303 m->iovec[0].iov_base = buffer;
304 m->iovec[0].iov_len = length;
307 r = message_parse_fields(m);
311 /* We take possession of the memory and fds now */
312 m->free_header = true;
323 static sd_bus_message *message_new(sd_bus *bus, uint8_t type) {
326 m = malloc0(ALIGN(sizeof(sd_bus_message)) + sizeof(struct bus_header));
331 m->header = (struct bus_header*) ((uint8_t*) m + ALIGN(sizeof(struct sd_bus_message)));
332 m->header->endian = SD_BUS_NATIVE_ENDIAN;
333 m->header->type = type;
334 m->header->version = bus ? bus->message_version : 1;
335 m->allow_fds = !bus || bus->can_fds || (bus->state != BUS_HELLO && bus->state != BUS_RUNNING);
340 int sd_bus_message_new_signal(
343 const char *interface,
345 sd_bus_message **m) {
358 if (bus && bus->state == BUS_UNSET)
361 t = message_new(bus, SD_BUS_MESSAGE_TYPE_SIGNAL);
365 t->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
367 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_PATH, SD_BUS_TYPE_OBJECT_PATH, path, &t->path);
370 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_INTERFACE, SD_BUS_TYPE_STRING, interface, &t->interface);
373 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_MEMBER, SD_BUS_TYPE_STRING, member, &t->member);
381 sd_bus_message_unref(t);
385 int sd_bus_message_new_method_call(
387 const char *destination,
389 const char *interface,
391 sd_bus_message **m) {
402 if (bus && bus->state == BUS_UNSET)
405 t = message_new(bus, SD_BUS_MESSAGE_TYPE_METHOD_CALL);
409 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_PATH, SD_BUS_TYPE_OBJECT_PATH, path, &t->path);
412 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_MEMBER, SD_BUS_TYPE_STRING, member, &t->member);
417 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_INTERFACE, SD_BUS_TYPE_STRING, interface, &t->interface);
423 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &t->destination);
436 static int message_new_reply(
438 sd_bus_message *call,
440 sd_bus_message **m) {
449 if (call->header->type != SD_BUS_MESSAGE_TYPE_METHOD_CALL)
453 if (bus && bus->state == BUS_UNSET)
456 t = message_new(bus, type);
460 t->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
461 t->reply_serial = BUS_MESSAGE_SERIAL(call);
463 r = message_append_field_uint32(t, SD_BUS_MESSAGE_HEADER_REPLY_SERIAL, t->reply_serial);
468 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, call->sender, &t->sender);
473 t->dont_send = !!(call->header->flags & SD_BUS_MESSAGE_NO_REPLY_EXPECTED);
483 int sd_bus_message_new_method_return(
485 sd_bus_message *call,
486 sd_bus_message **m) {
488 return message_new_reply(bus, call, SD_BUS_MESSAGE_TYPE_METHOD_RETURN, m);
491 int sd_bus_message_new_method_error(
493 sd_bus_message *call,
494 const sd_bus_error *e,
495 sd_bus_message **m) {
500 if (!sd_bus_error_is_set(e))
505 r = message_new_reply(bus, call, SD_BUS_MESSAGE_TYPE_METHOD_ERROR, &t);
509 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_ERROR_NAME, SD_BUS_TYPE_STRING, e->name, &t->error.name);
514 r = message_append_basic(t, SD_BUS_TYPE_STRING, e->message, (const void**) &t->error.message);
527 sd_bus_message* sd_bus_message_ref(sd_bus_message *m) {
531 assert(m->n_ref > 0);
537 sd_bus_message* sd_bus_message_unref(sd_bus_message *m) {
541 assert(m->n_ref > 0);
550 int sd_bus_message_get_type(sd_bus_message *m, uint8_t *type) {
556 *type = m->header->type;
560 int sd_bus_message_get_serial(sd_bus_message *m, uint64_t *serial) {
565 if (m->header->serial == 0)
568 *serial = BUS_MESSAGE_SERIAL(m);
572 int sd_bus_message_get_reply_serial(sd_bus_message *m, uint64_t *serial) {
577 if (m->reply_serial == 0)
580 *serial = m->reply_serial;
584 int sd_bus_message_get_no_reply(sd_bus_message *m) {
588 return m->header->type == SD_BUS_MESSAGE_TYPE_METHOD_CALL ? !!(m->header->flags & SD_BUS_MESSAGE_NO_REPLY_EXPECTED) : 0;
591 const char *sd_bus_message_get_path(sd_bus_message *m) {
598 const char *sd_bus_message_get_interface(sd_bus_message *m) {
605 const char *sd_bus_message_get_member(sd_bus_message *m) {
611 const char *sd_bus_message_get_destination(sd_bus_message *m) {
615 return m->destination;
618 const char *sd_bus_message_get_sender(sd_bus_message *m) {
625 const sd_bus_error *sd_bus_message_get_error(sd_bus_message *m) {
629 if (!sd_bus_error_is_set(&m->error))
635 int sd_bus_message_get_uid(sd_bus_message *m, uid_t *uid) {
645 int sd_bus_message_get_gid(sd_bus_message *m, gid_t *gid) {
655 int sd_bus_message_get_pid(sd_bus_message *m, pid_t *pid) {
665 int sd_bus_message_get_tid(sd_bus_message *m, pid_t *tid) {
675 const char *sd_bus_message_get_label(sd_bus_message *m) {
682 int sd_bus_message_is_signal(sd_bus_message *m, const char *interface, const char *member) {
686 if (m->header->type != SD_BUS_MESSAGE_TYPE_SIGNAL)
689 if (interface && (!m->interface || !streq(m->interface, interface)))
692 if (member && (!m->member || !streq(m->member, member)))
698 int sd_bus_message_is_method_call(sd_bus_message *m, const char *interface, const char *member) {
702 if (m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_CALL)
705 if (interface && (!m->interface || !streq(m->interface, interface)))
708 if (member && (!m->member || !streq(m->member, member)))
714 int sd_bus_message_is_method_error(sd_bus_message *m, const char *name) {
718 if (m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_ERROR)
721 if (name && (!m->error.name || !streq(m->error.name, name)))
727 int sd_bus_message_set_no_reply(sd_bus_message *m, int b) {
732 if (m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_CALL)
736 m->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
738 m->header->flags &= ~SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
743 static struct bus_container *message_get_container(sd_bus_message *m) {
746 if (m->n_containers == 0)
747 return &m->root_container;
749 assert(m->containers);
750 return m->containers + m->n_containers - 1;
753 static void *message_extend_body(sd_bus_message *m, size_t align, size_t sz) {
756 struct bus_container *c;
762 added = m->header->body_size;
764 p = buffer_extend(&m->body, &m->header->body_size, align, sz);
768 added = m->header->body_size - added;
770 for (c = m->containers; c < m->containers + m->n_containers; c++)
772 c->array_size = (uint32_t*) ((uint8_t*) m->body + ((uint8_t*) c->array_size - (uint8_t*) o));
773 *c->array_size += added;
777 if (m->error.message)
778 m->error.message = (const char*) m->body + (m->error.message - (const char*) o);
786 int message_append_basic(sd_bus_message *m, char type, const void *p, const void **stored) {
787 struct bus_container *c;
802 if (!bus_type_is_basic(type))
805 c = message_get_container(m);
807 if (c->signature && c->signature[c->index]) {
808 /* Container signature is already set */
810 if (c->signature[c->index] != type)
813 /* Maybe we can append to the signature? But only if this is the top-level container*/
814 if (c->enclosing != 0)
817 e = strextend(&c->signature, CHAR_TO_STR(type), NULL);
824 case SD_BUS_TYPE_STRING:
825 case SD_BUS_TYPE_OBJECT_PATH:
828 sz = 4 + strlen(p) + 1;
831 case SD_BUS_TYPE_SIGNATURE:
834 sz = 1 + strlen(p) + 1;
837 case SD_BUS_TYPE_BOOLEAN:
840 assert_cc(sizeof(int) == sizeof(uint32_t));
846 case SD_BUS_TYPE_UNIX_FD: {
862 fd = fcntl(z, F_DUPFD_CLOEXEC, 3);
868 f = realloc(m->fds, sizeof(int) * (m->n_fds + 1));
882 align = bus_type_get_alignment(type);
883 sz = bus_type_get_size(type);
890 a = message_extend_body(m, align, sz);
896 if (type == SD_BUS_TYPE_STRING || type == SD_BUS_TYPE_OBJECT_PATH) {
897 *(uint32_t*) a = sz - 5;
898 memcpy((uint8_t*) a + 4, p, sz - 4);
901 *stored = (const uint8_t*) a + 4;
903 } else if (type == SD_BUS_TYPE_SIGNATURE) {
904 *(uint8_t*) a = sz - 1;
905 memcpy((uint8_t*) a + 1, p, sz - 1);
908 *stored = (const uint8_t*) a + 1;
909 } else if (type == SD_BUS_TYPE_UNIX_FD) {
910 *(uint32_t*) a = fdi;
924 if (c->enclosing != SD_BUS_TYPE_ARRAY)
930 /* Truncate extended signature again */
932 c->signature[c->index] = 0;
935 close_nointr_nofail(fd);
940 int sd_bus_message_append_basic(sd_bus_message *m, char type, const void *p) {
941 return message_append_basic(m, type, p, NULL);
944 static int bus_message_open_array(
946 struct bus_container *c,
947 const char *contents,
948 uint32_t **array_size) {
961 if (!signature_is_single(contents))
964 alignment = bus_type_get_alignment(contents[0]);
968 if (c->signature && c->signature[c->index]) {
970 /* Verify the existing signature */
972 if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
975 if (!startswith(c->signature + c->index + 1, contents))
978 nindex = c->index + 1 + strlen(contents);
980 if (c->enclosing != 0)
983 /* Extend the existing signature */
985 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_ARRAY), contents, NULL);
989 nindex = e - c->signature;
992 saved = m->header->body_size;
993 a = message_extend_body(m, 4, 4);
995 /* Truncate extended signature again */
997 c->signature[c->index] = 0;
1003 if (!message_extend_body(m, alignment, 0)) {
1004 /* Add alignment between size and first element */
1006 c->signature[c->index] = 0;
1008 m->header->body_size = saved;
1012 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1015 /* m->body might have changed so let's readjust a */
1016 a = (uint8_t*) m->body + ((uint8_t*) a - (uint8_t*) b);
1023 static int bus_message_open_variant(
1025 struct bus_container *c,
1026 const char *contents) {
1036 if (!signature_is_single(contents))
1039 if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
1042 if (c->signature && c->signature[c->index]) {
1044 if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
1048 if (c->enclosing != 0)
1051 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_VARIANT), NULL);
1056 l = strlen(contents);
1057 a = message_extend_body(m, 1, 1 + l + 1);
1059 /* Truncate extended signature again */
1061 c->signature[c->index] = 0;
1067 memcpy((uint8_t*) a + 1, contents, l + 1);
1069 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1075 static int bus_message_open_struct(
1077 struct bus_container *c,
1078 const char *contents) {
1087 if (!signature_is_valid(contents, false))
1090 if (c->signature && c->signature[c->index]) {
1093 l = strlen(contents);
1095 if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
1096 !startswith(c->signature + c->index + 1, contents) ||
1097 c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
1100 nindex = c->index + 1 + l + 1;
1102 if (c->enclosing != 0)
1105 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_BEGIN), contents, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_END), NULL);
1109 nindex = e - c->signature;
1112 /* Align contents to 8 byte boundary */
1113 if (!message_extend_body(m, 8, 0)) {
1115 c->signature[c->index] = 0;
1120 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1126 static int bus_message_open_dict_entry(
1128 struct bus_container *c,
1129 const char *contents) {
1137 if (!signature_is_pair(contents))
1140 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1143 if (c->signature && c->signature[c->index]) {
1146 l = strlen(contents);
1148 if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
1149 !startswith(c->signature + c->index + 1, contents) ||
1150 c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
1153 nindex = c->index + 1 + l + 1;
1157 /* Align contents to 8 byte boundary */
1158 if (!message_extend_body(m, 8, 0))
1161 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1167 int sd_bus_message_open_container(
1170 const char *contents) {
1172 struct bus_container *c, *w;
1173 uint32_t *array_size = NULL;
1184 /* Make sure we have space for one more container */
1185 w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
1190 c = message_get_container(m);
1192 signature = strdup(contents);
1196 if (type == SD_BUS_TYPE_ARRAY)
1197 r = bus_message_open_array(m, c, contents, &array_size);
1198 else if (type == SD_BUS_TYPE_VARIANT)
1199 r = bus_message_open_variant(m, c, contents);
1200 else if (type == SD_BUS_TYPE_STRUCT)
1201 r = bus_message_open_struct(m, c, contents);
1202 else if (type == SD_BUS_TYPE_DICT_ENTRY)
1203 r = bus_message_open_dict_entry(m, c, contents);
1212 /* OK, let's fill it in */
1213 w += m->n_containers++;
1214 w->enclosing = type;
1215 w->signature = signature;
1217 w->array_size = array_size;
1223 int sd_bus_message_close_container(sd_bus_message *m) {
1224 struct bus_container *c;
1230 if (m->n_containers <= 0)
1233 c = message_get_container(m);
1234 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1235 if (c->signature && c->signature[c->index] != 0)
1244 static int message_append_ap(
1255 for (t = types; *t; t++) {
1258 case SD_BUS_TYPE_BYTE: {
1261 x = (uint8_t) va_arg(ap, int);
1262 r = sd_bus_message_append_basic(m, *t, &x);
1266 case SD_BUS_TYPE_BOOLEAN:
1267 case SD_BUS_TYPE_INT32:
1268 case SD_BUS_TYPE_UINT32:
1269 case SD_BUS_TYPE_UNIX_FD: {
1272 /* We assume a boolean is the same as int32_t */
1273 assert_cc(sizeof(int32_t) == sizeof(int));
1275 x = va_arg(ap, uint32_t);
1276 r = sd_bus_message_append_basic(m, *t, &x);
1280 case SD_BUS_TYPE_INT16:
1281 case SD_BUS_TYPE_UINT16: {
1284 x = (uint16_t) va_arg(ap, int);
1285 r = sd_bus_message_append_basic(m, *t, &x);
1289 case SD_BUS_TYPE_INT64:
1290 case SD_BUS_TYPE_UINT64:
1291 case SD_BUS_TYPE_DOUBLE: {
1294 x = va_arg(ap, uint64_t);
1295 r = sd_bus_message_append_basic(m, *t, &x);
1299 case SD_BUS_TYPE_STRING:
1300 case SD_BUS_TYPE_OBJECT_PATH:
1301 case SD_BUS_TYPE_SIGNATURE: {
1304 x = va_arg(ap, const char*);
1305 r = sd_bus_message_append_basic(m, *t, x);
1309 case SD_BUS_TYPE_ARRAY: {
1312 r = signature_element_length(t + 1, &k);
1320 memcpy(s, t + 1, k);
1324 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, s);
1328 n = va_arg(ap, unsigned);
1329 for (i = 0; i < n; i++) {
1330 r = message_append_ap(m, s, ap);
1335 r = sd_bus_message_close_container(m);
1341 case SD_BUS_TYPE_VARIANT: {
1344 s = va_arg(ap, const char*);
1348 r = sd_bus_message_open_container(m, SD_BUS_TYPE_VARIANT, s);
1352 r = message_append_ap(m, s, ap);
1356 r = sd_bus_message_close_container(m);
1360 case SD_BUS_TYPE_STRUCT_BEGIN:
1361 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
1364 r = signature_element_length(t, &k);
1371 memcpy(s, t + 1, k - 2);
1374 r = sd_bus_message_open_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
1380 r = message_append_ap(m, s, ap);
1384 r = sd_bus_message_close_container(m);
1401 int sd_bus_message_append(sd_bus_message *m, const char *types, ...) {
1412 va_start(ap, types);
1413 r = message_append_ap(m, types, ap);
1419 static int buffer_peek(const void *p, uint32_t sz, size_t *rindex, size_t align, size_t nbytes, void **r) {
1425 start = ALIGN_TO((size_t) *rindex, align);
1431 /* Verify that padding is 0 */
1432 for (k = *rindex; k < start; k++)
1433 if (((const uint8_t*) p)[k] != 0)
1437 *r = (uint8_t*) p + start;
1444 static bool message_end_of_array(sd_bus_message *m, size_t index) {
1445 struct bus_container *c;
1449 c = message_get_container(m);
1453 return index >= c->begin + BUS_MESSAGE_BSWAP32(m, *c->array_size);
1456 static int message_peek_body(sd_bus_message *m, size_t *rindex, size_t align, size_t nbytes, void **ret) {
1461 if (message_end_of_array(m, *rindex))
1464 return buffer_peek(m->body, BUS_MESSAGE_BODY_SIZE(m), rindex, align, nbytes, ret);
1467 static bool validate_nul(const char *s, size_t l) {
1469 /* Check for NUL chars in the string */
1470 if (memchr(s, 0, l))
1473 /* Check for NUL termination */
1480 static bool validate_string(const char *s, size_t l) {
1482 if (!validate_nul(s, l))
1485 /* Check if valid UTF8 */
1486 if (!utf8_is_valid(s))
1492 static bool validate_signature(const char *s, size_t l) {
1494 if (!validate_nul(s, l))
1497 /* Check if valid signature */
1498 if (!signature_is_valid(s, true))
1504 static bool validate_object_path(const char *s, size_t l) {
1506 if (!validate_nul(s, l))
1509 if (!object_path_is_valid(s))
1515 int sd_bus_message_read_basic(sd_bus_message *m, char type, void *p) {
1516 struct bus_container *c;
1524 if (!bus_type_is_basic(type))
1529 c = message_get_container(m);
1531 if (!c->signature || c->signature[c->index] == 0)
1534 if (c->signature[c->index] != type)
1539 case SD_BUS_TYPE_STRING:
1540 case SD_BUS_TYPE_OBJECT_PATH: {
1545 r = message_peek_body(m, &rindex, 4, 4, &q);
1549 l = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
1550 r = message_peek_body(m, &rindex, 1, l+1, &q);
1556 if (type == SD_BUS_TYPE_OBJECT_PATH) {
1557 if (!validate_object_path(q, l))
1560 if (!validate_string(q, l))
1565 *(const char**) p = q;
1569 case SD_BUS_TYPE_SIGNATURE: {
1574 r = message_peek_body(m, &rindex, 1, 1, &q);
1579 r = message_peek_body(m, &rindex, 1, l+1, &q);
1585 if (!validate_signature(q, l))
1589 *(const char**) p = q;
1597 align = bus_type_get_alignment(type);
1598 sz = bus_type_get_size(type);
1599 assert(align > 0 && sz > 0);
1602 r = message_peek_body(m, &rindex, align, sz, &q);
1608 case SD_BUS_TYPE_BYTE:
1609 *(uint8_t*) p = *(uint8_t*) q;
1612 case SD_BUS_TYPE_BOOLEAN:
1613 *(int*) p = !!*(uint32_t*) q;
1616 case SD_BUS_TYPE_INT16:
1617 case SD_BUS_TYPE_UINT16:
1618 *(uint16_t*) p = BUS_MESSAGE_BSWAP16(m, *(uint16_t*) q);
1621 case SD_BUS_TYPE_INT32:
1622 case SD_BUS_TYPE_UINT32:
1623 *(uint32_t*) p = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
1626 case SD_BUS_TYPE_INT64:
1627 case SD_BUS_TYPE_UINT64:
1628 case SD_BUS_TYPE_DOUBLE:
1629 *(uint64_t*) p = BUS_MESSAGE_BSWAP64(m, *(uint64_t*) q);
1632 case SD_BUS_TYPE_UNIX_FD: {
1636 j = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
1640 copy = fcntl(m->fds[j], F_DUPFD_CLOEXEC, 3);
1649 assert_not_reached("Unknown basic type...");
1658 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1664 static int bus_message_enter_array(
1666 struct bus_container *c,
1667 const char *contents,
1668 uint32_t **array_size) {
1679 if (!signature_is_single(contents))
1682 alignment = bus_type_get_alignment(contents[0]);
1686 if (!c->signature || c->signature[c->index] == 0)
1689 if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
1692 if (!startswith(c->signature + c->index + 1, contents))
1696 r = message_peek_body(m, &rindex, 4, 4, &q);
1700 if (BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q) > BUS_ARRAY_MAX_SIZE)
1703 r = message_peek_body(m, &rindex, alignment, 0, NULL);
1709 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1710 c->index += 1 + strlen(contents);
1714 *array_size = (uint32_t*) q;
1719 static int bus_message_enter_variant(
1721 struct bus_container *c,
1722 const char *contents) {
1733 if (!signature_is_single(contents))
1736 if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
1739 if (!c->signature || c->signature[c->index] == 0)
1742 if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
1746 r = message_peek_body(m, &rindex, 1, 1, &q);
1751 r = message_peek_body(m, &rindex, 1, l+1, &q);
1757 if (!validate_signature(q, l))
1760 if (!streq(q, contents))
1763 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1771 static int bus_message_enter_struct(
1773 struct bus_container *c,
1774 const char *contents) {
1783 if (!signature_is_valid(contents, false))
1786 if (!c->signature || c->signature[c->index] == 0)
1789 l = strlen(contents);
1791 if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
1792 !startswith(c->signature + c->index + 1, contents) ||
1793 c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
1796 r = message_peek_body(m, &m->rindex, 8, 0, NULL);
1800 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1801 c->index += 1 + l + 1;
1806 static int bus_message_enter_dict_entry(
1808 struct bus_container *c,
1809 const char *contents) {
1818 if (!signature_is_pair(contents))
1821 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1824 if (!c->signature || c->signature[c->index] == 0)
1827 l = strlen(contents);
1829 if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
1830 !startswith(c->signature + c->index + 1, contents) ||
1831 c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
1834 r = message_peek_body(m, &m->rindex, 8, 0, NULL);
1838 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1839 c->index += 1 + l + 1;
1844 int sd_bus_message_enter_container(sd_bus_message *m, char type, const char *contents) {
1845 struct bus_container *c, *w;
1846 uint32_t *array_size = NULL;
1858 * We enforce a global limit on container depth, that is much
1859 * higher than the 32 structs and 32 arrays the specification
1860 * mandates. This is simpler to implement for us, and we need
1861 * this only to ensure our container array doesn't grow
1862 * without bounds. We are happy to return any data from a
1863 * message as long as the data itself is valid, even if the
1864 * overall message might be not.
1866 * Note that the message signature is validated when
1867 * parsing the headers, and that validation does check the
1870 * Note that the specification defines no limits on the depth
1871 * of stacked variants, but we do.
1873 if (m->n_containers >= BUS_CONTAINER_DEPTH)
1876 w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
1881 c = message_get_container(m);
1883 if (!c->signature || c->signature[c->index] == 0)
1886 signature = strdup(contents);
1890 if (type == SD_BUS_TYPE_ARRAY)
1891 r = bus_message_enter_array(m, c, contents, &array_size);
1892 else if (type == SD_BUS_TYPE_VARIANT)
1893 r = bus_message_enter_variant(m, c, contents);
1894 else if (type == SD_BUS_TYPE_STRUCT)
1895 r = bus_message_enter_struct(m, c, contents);
1896 else if (type == SD_BUS_TYPE_DICT_ENTRY)
1897 r = bus_message_enter_dict_entry(m, c, contents);
1906 /* OK, let's fill it in */
1907 w += m->n_containers++;
1908 w->enclosing = type;
1909 w->signature = signature;
1911 w->array_size = array_size;
1912 w->begin = m->rindex;
1917 int sd_bus_message_exit_container(sd_bus_message *m) {
1918 struct bus_container *c;
1924 if (m->n_containers <= 0)
1927 c = message_get_container(m);
1928 if (c->enclosing == SD_BUS_TYPE_ARRAY) {
1931 l = BUS_MESSAGE_BSWAP32(m, *c->array_size);
1932 if (c->begin + l != m->rindex)
1936 if (c->signature && c->signature[c->index] != 0)
1946 int sd_bus_message_peek_type(sd_bus_message *m, char *type, const char **contents) {
1947 struct bus_container *c;
1955 c = message_get_container(m);
1957 if (!c->signature || c->signature[c->index] == 0)
1960 if (message_end_of_array(m, m->rindex))
1963 if (bus_type_is_basic(c->signature[c->index])) {
1967 *type = c->signature[c->index];
1971 if (c->signature[c->index] == SD_BUS_TYPE_ARRAY) {
1977 r = signature_element_length(c->signature+c->index+1, &l);
1983 sig = strndup(c->signature + c->index + 1, l);
1987 free(m->peeked_signature);
1988 m->peeked_signature = sig;
1994 *type = SD_BUS_TYPE_ARRAY;
1999 if (c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ||
2000 c->signature[c->index] == SD_BUS_TYPE_DICT_ENTRY_BEGIN) {
2006 r = signature_element_length(c->signature+c->index, &l);
2011 sig = strndup(c->signature + c->index + 1, l - 2);
2015 free(m->peeked_signature);
2016 m->peeked_signature = sig;
2022 *type = c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY;
2027 if (c->signature[c->index] == SD_BUS_TYPE_VARIANT) {
2033 r = message_peek_body(m, &rindex, 1, 1, &q);
2040 r = message_peek_body(m, &rindex, 1, l+1, &q);
2046 if (!validate_signature(q, l))
2053 *type = SD_BUS_TYPE_VARIANT;
2062 *type = c->enclosing;
2068 int sd_bus_message_rewind(sd_bus_message *m, int complete) {
2069 struct bus_container *c;
2077 reset_containers(m);
2079 m->root_container.index = 0;
2081 c = message_get_container(m);
2083 c = message_get_container(m);
2086 m->rindex = c->begin;
2089 return !isempty(c->signature);
2092 static int message_read_ap(sd_bus_message *m, const char *types, va_list ap) {
2099 for (t = types; *t; t++) {
2102 case SD_BUS_TYPE_BYTE:
2103 case SD_BUS_TYPE_BOOLEAN:
2104 case SD_BUS_TYPE_INT16:
2105 case SD_BUS_TYPE_UINT16:
2106 case SD_BUS_TYPE_INT32:
2107 case SD_BUS_TYPE_UINT32:
2108 case SD_BUS_TYPE_INT64:
2109 case SD_BUS_TYPE_UINT64:
2110 case SD_BUS_TYPE_DOUBLE:
2111 case SD_BUS_TYPE_STRING:
2112 case SD_BUS_TYPE_OBJECT_PATH:
2113 case SD_BUS_TYPE_SIGNATURE:
2114 case SD_BUS_TYPE_UNIX_FD: {
2117 p = va_arg(ap, void*);
2118 r = sd_bus_message_read_basic(m, *t, p);
2122 case SD_BUS_TYPE_ARRAY: {
2125 r = signature_element_length(t + 1, &k);
2133 memcpy(s, t + 1, k);
2137 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, s);
2143 n = va_arg(ap, unsigned);
2144 for (i = 0; i < n; i++) {
2145 r = message_read_ap(m, s, ap);
2150 r = sd_bus_message_exit_container(m);
2156 case SD_BUS_TYPE_VARIANT: {
2159 s = va_arg(ap, const char *);
2163 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, s);
2169 r = message_read_ap(m, s, ap);
2175 r = sd_bus_message_exit_container(m);
2179 case SD_BUS_TYPE_STRUCT_BEGIN:
2180 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
2183 r = signature_element_length(t, &k);
2189 memcpy(s, t + 1, k - 2);
2192 r = sd_bus_message_enter_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
2200 r = message_read_ap(m, s, ap);
2206 r = sd_bus_message_exit_container(m);
2225 int sd_bus_message_read(sd_bus_message *m, const char *types, ...) {
2236 va_start(ap, types);
2237 r = message_read_ap(m, types, ap);
2243 static int message_peek_fields(
2254 return buffer_peek(m->fields, BUS_MESSAGE_FIELDS_SIZE(m), rindex, align, nbytes, ret);
2257 static int message_peek_field_uint32(
2268 r = message_peek_fields(m, ri, 4, 4, &q);
2273 *ret = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2278 static int message_peek_field_string(
2280 bool (*validate)(const char *p),
2291 r = message_peek_field_uint32(m, ri, &l);
2295 r = message_peek_fields(m, ri, 1, l+1, &q);
2300 if (!validate_nul(q, l))
2306 if (!validate_string(q, l))
2316 static int message_peek_field_signature(
2328 r = message_peek_fields(m, ri, 1, 1, &q);
2333 r = message_peek_fields(m, ri, 1, l+1, &q);
2337 if (!validate_signature(q, l))
2346 static int message_skip_fields(
2349 uint32_t array_size,
2350 const char **signature) {
2352 size_t original_index;
2359 original_index = *ri;
2365 if (array_size != (uint32_t) -1 &&
2366 array_size <= *ri - original_index)
2373 if (t == SD_BUS_TYPE_STRING) {
2375 r = message_peek_field_string(m, NULL, ri, NULL);
2381 } else if (t == SD_BUS_TYPE_OBJECT_PATH) {
2383 r = message_peek_field_string(m, object_path_is_valid, ri, NULL);
2389 } else if (t == SD_BUS_TYPE_SIGNATURE) {
2391 r = message_peek_field_signature(m, ri, NULL);
2397 } else if (bus_type_is_basic(t)) {
2400 align = bus_type_get_alignment(t);
2401 k = bus_type_get_size(t);
2402 assert(align > 0 && k > 0);
2404 r = message_peek_fields(m, ri, align, k, NULL);
2410 } else if (t == SD_BUS_TYPE_ARRAY) {
2412 r = signature_element_length(*signature+1, &l);
2422 strncpy(sig, *signature + 1, l-1);
2425 alignment = bus_type_get_alignment(sig[0]);
2429 r = message_peek_field_uint32(m, ri, &nas);
2432 if (nas > BUS_ARRAY_MAX_SIZE)
2435 r = message_peek_fields(m, ri, alignment, 0, NULL);
2439 r = message_skip_fields(m, ri, nas, (const char**) &s);
2444 (*signature) += 1 + l;
2446 } else if (t == SD_BUS_TYPE_VARIANT) {
2449 r = message_peek_field_signature(m, ri, &s);
2453 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
2459 } else if (t == SD_BUS_TYPE_STRUCT ||
2460 t == SD_BUS_TYPE_DICT_ENTRY) {
2462 r = signature_element_length(*signature, &l);
2469 strncpy(sig, *signature + 1, l-1);
2472 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
2483 static int message_parse_fields(sd_bus_message *m) {
2486 uint32_t unix_fds = 0;
2490 for (ri = 0; ri < BUS_MESSAGE_FIELDS_SIZE(m); ) {
2491 const char *signature;
2494 r = message_peek_fields(m, &ri, 8, 1, (void**) &header);
2498 r = message_peek_field_signature(m, &ri, &signature);
2503 case _SD_BUS_MESSAGE_HEADER_INVALID:
2506 case SD_BUS_MESSAGE_HEADER_PATH:
2511 if (!streq(signature, "o"))
2514 r = message_peek_field_string(m, object_path_is_valid, &ri, &m->path);
2517 case SD_BUS_MESSAGE_HEADER_INTERFACE:
2522 if (!streq(signature, "s"))
2525 r = message_peek_field_string(m, interface_name_is_valid, &ri, &m->interface);
2528 case SD_BUS_MESSAGE_HEADER_MEMBER:
2533 if (!streq(signature, "s"))
2536 r = message_peek_field_string(m, member_name_is_valid, &ri, &m->member);
2539 case SD_BUS_MESSAGE_HEADER_ERROR_NAME:
2544 if (!streq(signature, "s"))
2547 r = message_peek_field_string(m, error_name_is_valid, &ri, &m->error.name);
2550 case SD_BUS_MESSAGE_HEADER_DESTINATION:
2555 if (!streq(signature, "s"))
2558 r = message_peek_field_string(m, service_name_is_valid, &ri, &m->destination);
2561 case SD_BUS_MESSAGE_HEADER_SENDER:
2566 if (!streq(signature, "s"))
2569 r = message_peek_field_string(m, service_name_is_valid, &ri, &m->sender);
2573 case SD_BUS_MESSAGE_HEADER_SIGNATURE: {
2577 if (m->root_container.signature)
2580 if (!streq(signature, "g"))
2583 r = message_peek_field_signature(m, &ri, &s);
2591 free(m->root_container.signature);
2592 m->root_container.signature = c;
2596 case SD_BUS_MESSAGE_HEADER_REPLY_SERIAL:
2597 if (m->reply_serial != 0)
2600 if (!streq(signature, "u"))
2603 r = message_peek_field_uint32(m, &ri, &m->reply_serial);
2607 if (m->reply_serial == 0)
2612 case SD_BUS_MESSAGE_HEADER_UNIX_FDS:
2616 if (!streq(signature, "u"))
2619 r = message_peek_field_uint32(m, &ri, &unix_fds);
2629 r = message_skip_fields(m, &ri, (uint32_t) -1, (const char **) &signature);
2636 if (m->n_fds != unix_fds)
2639 if (isempty(m->root_container.signature) != (BUS_MESSAGE_BODY_SIZE(m) == 0))
2642 switch (m->header->type) {
2644 case SD_BUS_MESSAGE_TYPE_SIGNAL:
2645 if (!m->path || !m->interface || !m->member)
2649 case SD_BUS_MESSAGE_TYPE_METHOD_CALL:
2651 if (!m->path || !m->member)
2656 case SD_BUS_MESSAGE_TYPE_METHOD_RETURN:
2658 if (m->reply_serial == 0)
2662 case SD_BUS_MESSAGE_TYPE_METHOD_ERROR:
2664 if (m->reply_serial == 0 || !m->error.name)
2669 /* Try to read the error message, but if we can't it's a non-issue */
2670 if (m->header->type == SD_BUS_MESSAGE_TYPE_METHOD_ERROR)
2671 sd_bus_message_read(m, "s", &m->error.message);
2676 static void setup_iovec(sd_bus_message *m) {
2683 m->iovec[m->n_iovec].iov_base = m->header;
2684 m->iovec[m->n_iovec].iov_len = sizeof(*m->header);
2685 m->size += m->iovec[m->n_iovec].iov_len;
2689 m->iovec[m->n_iovec].iov_base = m->fields;
2690 m->iovec[m->n_iovec].iov_len = m->header->fields_size;
2691 m->size += m->iovec[m->n_iovec].iov_len;
2694 if (m->header->fields_size % 8 != 0) {
2695 static const uint8_t padding[7] = { 0, 0, 0, 0, 0, 0, 0 };
2697 m->iovec[m->n_iovec].iov_base = (void*) padding;
2698 m->iovec[m->n_iovec].iov_len = 8 - m->header->fields_size % 8;
2699 m->size += m->iovec[m->n_iovec].iov_len;
2705 m->iovec[m->n_iovec].iov_base = m->body;
2706 m->iovec[m->n_iovec].iov_len = m->header->body_size;
2707 m->size += m->iovec[m->n_iovec].iov_len;
2712 int bus_message_seal(sd_bus_message *m, uint64_t serial) {
2720 if (m->n_containers > 0)
2723 /* If there's a non-trivial signature set, then add it in here */
2724 if (!isempty(m->root_container.signature)) {
2725 r = message_append_field_signature(m, SD_BUS_MESSAGE_HEADER_SIGNATURE, m->root_container.signature, NULL);
2731 r = message_append_field_uint32(m, SD_BUS_MESSAGE_HEADER_UNIX_FDS, m->n_fds);
2736 m->header->serial = serial;
2744 int sd_bus_message_set_destination(sd_bus_message *m, const char *destination) {
2754 return message_append_field_string(m, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &m->destination);
2757 int bus_message_dump(sd_bus_message *m) {
2763 printf("Message %p\n"
2770 "\tfields_size=%u\n"
2775 "\tdestination=%s\n"
2778 "\treply_serial=%u\n"
2780 "\terror.message=%s\n"
2788 BUS_MESSAGE_SERIAL(m),
2789 BUS_MESSAGE_FIELDS_SIZE(m),
2790 BUS_MESSAGE_BODY_SIZE(m),
2792 strna(m->interface),
2794 strna(m->destination),
2796 strna(m->root_container.signature),
2798 strna(m->error.name),
2799 strna(m->error.message),
2802 r = sd_bus_message_rewind(m, true);
2804 log_error("Failed to rewind: %s", strerror(-r));
2808 printf("BEGIN_MESSAGE \"%s\" {\n", strempty(m->root_container.signature));
2811 _cleanup_free_ char *prefix = NULL;
2812 const char *contents = NULL;
2827 r = sd_bus_message_peek_type(m, &type, &contents);
2829 log_error("Failed to peek type: %s", strerror(-r));
2836 r = sd_bus_message_exit_container(m);
2838 log_error("Failed to exit container: %s", strerror(-r));
2844 prefix = strrep("\t", level);
2848 if (type == SD_BUS_TYPE_ARRAY)
2849 printf("%s} END_ARRAY \n", prefix);
2850 else if (type == SD_BUS_TYPE_VARIANT)
2851 printf("%s} END_VARIANT\n", prefix);
2852 else if (type == SD_BUS_TYPE_STRUCT)
2853 printf("%s} END_STRUCT\n", prefix);
2854 else if (type == SD_BUS_TYPE_DICT_ENTRY)
2855 printf("%s} END_DICT_ENTRY\n", prefix);
2860 prefix = strrep("\t", level);
2864 if (bus_type_is_container(type) > 0) {
2865 r = sd_bus_message_enter_container(m, type, contents);
2867 log_error("Failed to enter container: %s", strerror(-r));
2871 if (type == SD_BUS_TYPE_ARRAY)
2872 printf("%sBEGIN_ARRAY \"%s\" {\n", prefix, contents);
2873 else if (type == SD_BUS_TYPE_VARIANT)
2874 printf("%sBEGIN_VARIANT \"%s\" {\n", prefix, contents);
2875 else if (type == SD_BUS_TYPE_STRUCT)
2876 printf("%sBEGIN_STRUCT \"%s\" {\n", prefix, contents);
2877 else if (type == SD_BUS_TYPE_DICT_ENTRY)
2878 printf("%sBEGIN_DICT_ENTRY \"%s\" {\n", prefix, contents);
2885 r = sd_bus_message_read_basic(m, type, &basic);
2887 log_error("Failed to get basic: %s", strerror(-r));
2893 case SD_BUS_TYPE_BYTE:
2894 printf("%sBYTE: %u\n", prefix, basic.u8);
2897 case SD_BUS_TYPE_BOOLEAN:
2898 printf("%sBOOLEAN: %s\n", prefix, yes_no(basic.i));
2901 case SD_BUS_TYPE_INT16:
2902 printf("%sINT16: %i\n", prefix, basic.s16);
2905 case SD_BUS_TYPE_UINT16:
2906 printf("%sUINT16: %u\n", prefix, basic.u16);
2909 case SD_BUS_TYPE_INT32:
2910 printf("%sINT32: %i\n", prefix, basic.s32);
2913 case SD_BUS_TYPE_UINT32:
2914 printf("%sUINT32: %u\n", prefix, basic.u32);
2917 case SD_BUS_TYPE_INT64:
2918 printf("%sINT64: %lli\n", prefix, (long long) basic.s64);
2921 case SD_BUS_TYPE_UINT64:
2922 printf("%sUINT64: %llu\n", prefix, (unsigned long long) basic.u64);
2925 case SD_BUS_TYPE_DOUBLE:
2926 printf("%sDOUBLE: %g\n", prefix, basic.d64);
2929 case SD_BUS_TYPE_STRING:
2930 printf("%sSTRING: \"%s\"\n", prefix, basic.string);
2933 case SD_BUS_TYPE_OBJECT_PATH:
2934 printf("%sOBJECT_PATH: \"%s\"\n", prefix, basic.string);
2937 case SD_BUS_TYPE_SIGNATURE:
2938 printf("%sSIGNATURE: \"%s\"\n", prefix, basic.string);
2941 case SD_BUS_TYPE_UNIX_FD:
2942 printf("%sUNIX_FD: %i\n", prefix, basic.i);
2946 assert_not_reached("Unknown basic type.");
2950 printf("} END_MESSAGE\n");
2954 int bus_message_get_blob(sd_bus_message *m, void **buffer, size_t *sz) {
2963 for (i = 0, total = 0; i < m->n_iovec; i++)
2964 total += m->iovec[i].iov_len;
2970 for (i = 0, e = p; i < m->n_iovec; i++)
2971 e = mempcpy(e, m->iovec[i].iov_base, m->iovec[i].iov_len);
2979 int bus_message_read_strv_extend(sd_bus_message *m, char ***l) {
2985 r = sd_bus_message_enter_container(m, 'a', "s");
2992 r = sd_bus_message_read_basic(m, 's', &s);
2998 r = strv_extend(l, s);
3003 r = sd_bus_message_exit_container(m);
3010 const char* bus_message_get_arg(sd_bus_message *m, unsigned i) {
3017 r = sd_bus_message_rewind(m, true);
3022 r = sd_bus_message_peek_type(m, &type, NULL);
3026 if (type != SD_BUS_TYPE_STRING &&
3027 type != SD_BUS_TYPE_OBJECT_PATH &&
3028 type != SD_BUS_TYPE_SIGNATURE)
3031 r = sd_bus_message_read_basic(m, type, &t);
3038 r = sd_bus_message_rewind(m, true);