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/>.
29 #include "bus-message.h"
30 #include "bus-internal.h"
32 #include "bus-signature.h"
34 static int message_parse_fields(sd_bus_message *m);
35 static int message_append_basic(sd_bus_message *m, char type, const void *p, const void **stored);
37 static void reset_containers(sd_bus_message *m) {
42 for (i = 0; i < m->n_containers; i++)
43 free(m->containers[i].signature);
49 m->root_container.index = 0;
52 static void message_free(sd_bus_message *m) {
66 for (i = 0; i < m->n_fds; i++)
67 close_nointr_nofail(m->fds[i]);
70 free(m->root_container.signature);
72 free(m->peeked_signature);
76 static void* buffer_extend(void **p, uint32_t *sz, size_t align, size_t extend) {
84 start = ALIGN_TO((size_t) *sz, align);
88 return (uint8_t*) *p + start;
90 if (n > (size_t) ((uint32_t) -1))
97 /* Zero out padding */
99 memset((uint8_t*) k + *sz, 0, start - *sz);
104 return (uint8_t*) k + start;
107 static void *message_extend_fields(sd_bus_message *m, size_t align, size_t sz) {
113 p = buffer_extend(&m->fields, &m->header->fields_size, align, sz);
117 if (o != m->fields) {
118 /* Adjust quick access pointers */
121 m->path = (const char*) m->fields + (m->path - (const char*) o);
123 m->interface = (const char*) m->fields + (m->interface - (const char*) o);
125 m->member = (const char*) m->fields + (m->member - (const char*) o);
127 m->destination = (const char*) m->fields + (m->destination - (const char*) o);
129 m->sender = (const char*) m->fields + (m->sender - (const char*) o);
131 m->error.name = (const char*) m->fields + (m->error.name - (const char*) o);
134 m->free_fields = true;
139 static int message_append_field_string(
152 if (l > (size_t) (uint32_t) -1)
155 /* field id byte + signature length + signature 's' + NUL + string length + string + NUL */
156 p = message_extend_fields(m, 8, 4 + 4 + l + 1);
165 ((uint32_t*) p)[1] = l;
166 memcpy(p + 8, s, l + 1);
169 *ret = (const char*) p + 8;
174 static int message_append_field_signature(
189 /* field id byte + signature length + signature 'g' + NUL + string length + string + NUL */
190 p = message_extend_fields(m, 8, 4 + 1 + l + 1);
196 p[2] = SD_BUS_TYPE_SIGNATURE;
199 memcpy(p + 5, s, l + 1);
202 *ret = (const char*) p + 5;
207 static int message_append_field_uint32(sd_bus_message *m, uint8_t h, uint32_t x) {
212 /* field id byte + signature length + signature 'u' + NUL + value */
213 p = message_extend_fields(m, 8, 4 + 4);
219 p[2] = SD_BUS_TYPE_UINT32;
222 ((uint32_t*) p)[1] = x;
227 int bus_message_from_malloc(void *buffer, size_t length, sd_bus_message **ret) {
229 struct bus_header *h;
230 size_t total, fs, bs;
233 assert(buffer || length <= 0);
236 if (length < sizeof(struct bus_header))
246 if (h->type == _SD_BUS_MESSAGE_TYPE_INVALID)
249 if (h->endian == SD_BUS_NATIVE_ENDIAN) {
252 } else if (h->endian == SD_BUS_REVERSE_ENDIAN) {
253 fs = bswap_32(h->fields_size);
254 bs = bswap_32(h->body_size);
258 total = sizeof(struct bus_header) + ALIGN_TO(fs, 8) + bs;
262 m = new0(sd_bus_message, 1);
268 m->free_header = true;
269 m->fields = (uint8_t*) buffer + sizeof(struct bus_header);
270 m->body = (uint8_t*) buffer + sizeof(struct bus_header) + ALIGN_TO(fs, 8);
274 m->iovec[0].iov_base = buffer;
275 m->iovec[0].iov_len = length;
277 r = message_parse_fields(m);
287 static sd_bus_message *message_new(sd_bus *bus, uint8_t type) {
290 m = malloc0(ALIGN(sizeof(sd_bus_message)) + sizeof(struct bus_header));
295 m->header = (struct bus_header*) ((uint8_t*) m + ALIGN(sizeof(struct sd_bus_message)));
296 m->header->endian = SD_BUS_NATIVE_ENDIAN;
297 m->header->type = type;
298 m->header->version = bus ? bus->message_version : 1;
303 int sd_bus_message_new_signal(
306 const char *interface,
308 sd_bus_message **m) {
322 t = message_new(bus, SD_BUS_MESSAGE_TYPE_SIGNAL);
326 t->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
328 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_PATH, SD_BUS_TYPE_OBJECT_PATH, path, &t->path);
331 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_INTERFACE, SD_BUS_TYPE_STRING, interface, &t->interface);
334 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_MEMBER, SD_BUS_TYPE_STRING, member, &t->member);
342 sd_bus_message_unref(t);
346 int sd_bus_message_new_method_call(
348 const char *destination,
350 const char *interface,
352 sd_bus_message **m) {
364 t = message_new(bus, SD_BUS_MESSAGE_TYPE_METHOD_CALL);
368 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_PATH, SD_BUS_TYPE_OBJECT_PATH, path, &t->path);
371 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_MEMBER, SD_BUS_TYPE_STRING, member, &t->member);
376 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_INTERFACE, SD_BUS_TYPE_STRING, interface, &t->interface);
382 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &t->destination);
395 static int message_new_reply(
397 sd_bus_message *call,
399 sd_bus_message **m) {
408 if (call->header->type != SD_BUS_MESSAGE_TYPE_METHOD_CALL)
413 t = message_new(bus, type);
417 t->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
418 t->reply_serial = BUS_MESSAGE_SERIAL(call);
420 r = message_append_field_uint32(t, SD_BUS_MESSAGE_HEADER_REPLY_SERIAL, t->reply_serial);
425 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, call->sender, &t->sender);
430 t->dont_send = !!(call->header->flags & SD_BUS_MESSAGE_NO_REPLY_EXPECTED);
440 int sd_bus_message_new_method_return(
442 sd_bus_message *call,
443 sd_bus_message **m) {
445 return message_new_reply(bus, call, SD_BUS_MESSAGE_TYPE_METHOD_RETURN, m);
448 int sd_bus_message_new_method_error(
450 sd_bus_message *call,
451 const sd_bus_error *e,
452 sd_bus_message **m) {
457 if (!sd_bus_error_is_set(e))
462 r = message_new_reply(bus, call, SD_BUS_MESSAGE_TYPE_METHOD_ERROR, &t);
466 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_ERROR_NAME, SD_BUS_TYPE_STRING, e->name, &t->error.name);
471 r = message_append_basic(t, SD_BUS_TYPE_STRING, e->message, (const void**) &t->error.message);
484 sd_bus_message* sd_bus_message_ref(sd_bus_message *m) {
488 assert(m->n_ref > 0);
494 sd_bus_message* sd_bus_message_unref(sd_bus_message *m) {
498 assert(m->n_ref > 0);
507 int sd_bus_message_get_type(sd_bus_message *m, uint8_t *type) {
513 *type = m->header->type;
517 int sd_bus_message_get_serial(sd_bus_message *m, uint64_t *serial) {
522 if (m->header->serial == 0)
525 *serial = BUS_MESSAGE_SERIAL(m);
529 int sd_bus_message_get_reply_serial(sd_bus_message *m, uint64_t *serial) {
534 if (m->reply_serial == 0)
537 *serial = m->reply_serial;
541 int sd_bus_message_get_no_reply(sd_bus_message *m) {
545 return m->header->type == SD_BUS_MESSAGE_TYPE_METHOD_CALL ? !!(m->header->flags & SD_BUS_MESSAGE_NO_REPLY_EXPECTED) : 0;
548 const char *sd_bus_message_get_path(sd_bus_message *m) {
555 const char *sd_bus_message_get_interface(sd_bus_message *m) {
562 const char *sd_bus_message_get_member(sd_bus_message *m) {
568 const char *sd_bus_message_get_destination(sd_bus_message *m) {
572 return m->destination;
575 const char *sd_bus_message_get_sender(sd_bus_message *m) {
582 const sd_bus_error *sd_bus_message_get_error(sd_bus_message *m) {
586 if (!sd_bus_error_is_set(&m->error))
592 int sd_bus_message_get_uid(sd_bus_message *m, uid_t *uid) {
602 int sd_bus_message_get_gid(sd_bus_message *m, gid_t *gid) {
612 int sd_bus_message_get_pid(sd_bus_message *m, pid_t *pid) {
622 int sd_bus_message_get_tid(sd_bus_message *m, pid_t *tid) {
632 int sd_bus_message_is_signal(sd_bus_message *m, const char *interface, const char *member) {
636 if (m->header->type != SD_BUS_MESSAGE_TYPE_SIGNAL)
639 if (interface && (!m->interface || !streq(m->interface, interface)))
642 if (member && (!m->member || !streq(m->member, member)))
648 int sd_bus_message_is_method_call(sd_bus_message *m, const char *interface, const char *member) {
652 if (m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_CALL)
655 if (interface && (!m->interface || !streq(m->interface, interface)))
658 if (member && (!m->member || !streq(m->member, member)))
664 int sd_bus_message_is_method_error(sd_bus_message *m, const char *name) {
668 if (m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_ERROR)
671 if (name && (!m->error.name || !streq(m->error.name, name)))
677 int sd_bus_message_set_no_reply(sd_bus_message *m, int b) {
682 if (m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_CALL)
686 m->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
688 m->header->flags &= ~SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
693 static struct bus_container *message_get_container(sd_bus_message *m) {
696 if (m->n_containers == 0)
697 return &m->root_container;
699 assert(m->containers);
700 return m->containers + m->n_containers - 1;
703 static void *message_extend_body(sd_bus_message *m, size_t align, size_t sz) {
706 struct bus_container *c;
712 added = m->header->body_size;
714 p = buffer_extend(&m->body, &m->header->body_size, align, sz);
718 added = m->header->body_size - added;
720 for (c = m->containers; c < m->containers + m->n_containers; c++)
722 c->array_size = (uint32_t*) ((uint8_t*) m->body + ((uint8_t*) c->array_size - (uint8_t*) o));
723 *c->array_size += added;
727 if (m->error.message)
728 m->error.message = (const char*) m->body + (m->error.message - (const char*) o);
736 int message_append_basic(sd_bus_message *m, char type, const void *p, const void **stored) {
737 struct bus_container *c;
747 if (!bus_type_is_basic(type))
750 c = message_get_container(m);
752 if (c->signature && c->signature[c->index]) {
753 /* Container signature is already set */
755 if (c->signature[c->index] != type)
758 /* Maybe we can append to the signature? But only if this is the top-level container*/
759 if (c->enclosing != 0)
762 e = strextend(&c->signature, CHAR_TO_STR(type), NULL);
769 case SD_BUS_TYPE_STRING:
770 case SD_BUS_TYPE_OBJECT_PATH:
774 c->signature[c->index] = 0;
780 sz = 4 + strlen(p) + 1;
783 case SD_BUS_TYPE_SIGNATURE:
787 c->signature[c->index] = 0;
793 sz = 1 + strlen(p) + 1;
796 case SD_BUS_TYPE_BOOLEAN:
799 assert_cc(sizeof(int) == sizeof(uint32_t));
806 align = bus_type_get_alignment(type);
807 sz = bus_type_get_size(type);
814 a = message_extend_body(m, align, sz);
816 /* Truncate extended signature again */
818 c->signature[c->index] = 0;
823 if (type == SD_BUS_TYPE_STRING || type == SD_BUS_TYPE_OBJECT_PATH) {
824 *(uint32_t*) a = sz - 5;
825 memcpy((uint8_t*) a + 4, p, sz - 4);
828 *stored = (const uint8_t*) a + 4;
830 } else if (type == SD_BUS_TYPE_SIGNATURE) {
831 *(uint8_t*) a = sz - 1;
832 memcpy((uint8_t*) a + 1, p, sz - 1);
835 *stored = (const uint8_t*) a + 1;
844 if (c->enclosing != SD_BUS_TYPE_ARRAY)
850 int sd_bus_message_append_basic(sd_bus_message *m, char type, const void *p) {
851 return message_append_basic(m, type, p, NULL);
854 static int bus_message_open_array(
856 struct bus_container *c,
857 const char *contents,
858 uint32_t **array_size) {
871 if (!signature_is_single(contents))
874 alignment = bus_type_get_alignment(contents[0]);
878 if (c->signature && c->signature[c->index]) {
880 /* Verify the existing signature */
882 if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
885 if (!startswith(c->signature + c->index + 1, contents))
888 nindex = c->index + 1 + strlen(contents);
890 if (c->enclosing != 0)
893 /* Extend the existing signature */
895 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_ARRAY), contents, NULL);
899 nindex = e - c->signature;
902 saved = m->header->body_size;
903 a = message_extend_body(m, 4, 4);
905 /* Truncate extended signature again */
907 c->signature[c->index] = 0;
913 if (!message_extend_body(m, alignment, 0)) {
914 /* Add alignment between size and first element */
916 c->signature[c->index] = 0;
918 m->header->body_size = saved;
922 if (c->enclosing != SD_BUS_TYPE_ARRAY)
925 /* m->body might have changed so let's readjust a */
926 a = (uint8_t*) m->body + ((uint8_t*) a - (uint8_t*) b);
933 static int bus_message_open_variant(
935 struct bus_container *c,
936 const char *contents) {
946 if (!signature_is_single(contents))
949 if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
952 if (c->signature && c->signature[c->index]) {
954 if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
958 if (c->enclosing != 0)
961 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_VARIANT), NULL);
966 l = strlen(contents);
967 a = message_extend_body(m, 1, 1 + l + 1);
969 /* Truncate extended signature again */
971 c->signature[c->index] = 0;
977 memcpy((uint8_t*) a + 1, contents, l + 1);
979 if (c->enclosing != SD_BUS_TYPE_ARRAY)
985 static int bus_message_open_struct(
987 struct bus_container *c,
988 const char *contents) {
997 if (!signature_is_valid(contents, false))
1000 if (c->signature && c->signature[c->index]) {
1003 l = strlen(contents);
1005 if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
1006 !startswith(c->signature + c->index + 1, contents) ||
1007 c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
1010 nindex = c->index + 1 + l + 1;
1012 if (c->enclosing != 0)
1015 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_BEGIN), contents, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_END), NULL);
1019 nindex = e - c->signature;
1022 /* Align contents to 8 byte boundary */
1023 if (!message_extend_body(m, 8, 0)) {
1025 c->signature[c->index] = 0;
1030 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1036 static int bus_message_open_dict_entry(
1038 struct bus_container *c,
1039 const char *contents) {
1047 if (!signature_is_pair(contents))
1050 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1053 if (c->signature && c->signature[c->index]) {
1056 l = strlen(contents);
1058 if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
1059 !startswith(c->signature + c->index + 1, contents) ||
1060 c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
1063 nindex = c->index + 1 + l + 1;
1067 /* Align contents to 8 byte boundary */
1068 if (!message_extend_body(m, 8, 0))
1071 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1077 int sd_bus_message_open_container(
1080 const char *contents) {
1082 struct bus_container *c, *w;
1083 uint32_t *array_size = NULL;
1094 /* Make sure we have space for one more container */
1095 w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
1100 c = message_get_container(m);
1102 signature = strdup(contents);
1106 if (type == SD_BUS_TYPE_ARRAY)
1107 r = bus_message_open_array(m, c, contents, &array_size);
1108 else if (type == SD_BUS_TYPE_VARIANT)
1109 r = bus_message_open_variant(m, c, contents);
1110 else if (type == SD_BUS_TYPE_STRUCT)
1111 r = bus_message_open_struct(m, c, contents);
1112 else if (type == SD_BUS_TYPE_DICT_ENTRY)
1113 r = bus_message_open_dict_entry(m, c, contents);
1122 /* OK, let's fill it in */
1123 w += m->n_containers++;
1124 w->enclosing = type;
1125 w->signature = signature;
1127 w->array_size = array_size;
1133 int sd_bus_message_close_container(sd_bus_message *m) {
1134 struct bus_container *c;
1140 if (m->n_containers <= 0)
1143 c = message_get_container(m);
1144 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1145 if (c->signature && c->signature[c->index] != 0)
1154 static int message_append_ap(
1165 for (t = types; *t; t++) {
1168 case SD_BUS_TYPE_BYTE: {
1171 x = (uint8_t) va_arg(ap, int);
1172 r = sd_bus_message_append_basic(m, *t, &x);
1176 case SD_BUS_TYPE_BOOLEAN:
1177 case SD_BUS_TYPE_INT32:
1178 case SD_BUS_TYPE_UINT32:
1179 case SD_BUS_TYPE_UNIX_FD: {
1182 /* We assume a boolean is the same as int32_t */
1183 assert_cc(sizeof(int32_t) == sizeof(int));
1185 x = va_arg(ap, uint32_t);
1186 r = sd_bus_message_append_basic(m, *t, &x);
1190 case SD_BUS_TYPE_INT16:
1191 case SD_BUS_TYPE_UINT16: {
1194 x = (uint16_t) va_arg(ap, int);
1195 r = sd_bus_message_append_basic(m, *t, &x);
1199 case SD_BUS_TYPE_INT64:
1200 case SD_BUS_TYPE_UINT64:
1201 case SD_BUS_TYPE_DOUBLE: {
1204 x = va_arg(ap, uint64_t);
1205 r = sd_bus_message_append_basic(m, *t, &x);
1209 case SD_BUS_TYPE_STRING:
1210 case SD_BUS_TYPE_OBJECT_PATH:
1211 case SD_BUS_TYPE_SIGNATURE: {
1214 x = va_arg(ap, const char*);
1215 r = sd_bus_message_append_basic(m, *t, x);
1219 case SD_BUS_TYPE_ARRAY: {
1222 r = signature_element_length(t + 1, &k);
1230 memcpy(s, t + 1, k);
1234 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, s);
1238 n = va_arg(ap, unsigned);
1239 for (i = 0; i < n; i++) {
1240 r = message_append_ap(m, s, ap);
1245 r = sd_bus_message_close_container(m);
1251 case SD_BUS_TYPE_VARIANT: {
1254 s = va_arg(ap, const char*);
1258 r = sd_bus_message_open_container(m, SD_BUS_TYPE_VARIANT, s);
1262 r = message_append_ap(m, s, ap);
1266 r = sd_bus_message_close_container(m);
1270 case SD_BUS_TYPE_STRUCT_BEGIN:
1271 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
1274 r = signature_element_length(t, &k);
1281 memcpy(s, t + 1, k - 2);
1284 r = sd_bus_message_open_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
1290 r = message_append_ap(m, s, ap);
1294 r = sd_bus_message_close_container(m);
1311 int sd_bus_message_append(sd_bus_message *m, const char *types, ...) {
1322 va_start(ap, types);
1323 r = message_append_ap(m, types, ap);
1329 static int buffer_peek(const void *p, uint32_t sz, size_t *rindex, size_t align, size_t nbytes, void **r) {
1335 start = ALIGN_TO((size_t) *rindex, align);
1341 /* Verify that padding is 0 */
1342 for (k = *rindex; k < start; k++)
1343 if (((const uint8_t*) p)[k] != 0)
1347 *r = (uint8_t*) p + start;
1354 static bool message_end_of_array(sd_bus_message *m, size_t index) {
1355 struct bus_container *c;
1359 c = message_get_container(m);
1363 return index >= c->begin + BUS_MESSAGE_BSWAP32(m, *c->array_size);
1366 static int message_peek_body(sd_bus_message *m, size_t *rindex, size_t align, size_t nbytes, void **ret) {
1371 if (message_end_of_array(m, *rindex))
1374 return buffer_peek(m->body, BUS_MESSAGE_BODY_SIZE(m), rindex, align, nbytes, ret);
1377 static bool validate_nul(const char *s, size_t l) {
1379 /* Check for NUL chars in the string */
1380 if (memchr(s, 0, l))
1383 /* Check for NUL termination */
1390 static bool validate_string(const char *s, size_t l) {
1392 if (!validate_nul(s, l))
1395 /* Check if valid UTF8 */
1396 if (!utf8_is_valid(s))
1402 static bool validate_signature(const char *s, size_t l) {
1404 if (!validate_nul(s, l))
1407 /* Check if valid signature */
1408 if (!signature_is_valid(s, true))
1414 static bool validate_object_path(const char *s, size_t l) {
1416 if (!validate_nul(s, l))
1419 if (!object_path_is_valid(s))
1425 int sd_bus_message_read_basic(sd_bus_message *m, char type, void *p) {
1426 struct bus_container *c;
1434 if (!bus_type_is_basic(type))
1437 c = message_get_container(m);
1439 if (!c->signature || c->signature[c->index] == 0)
1442 if (c->signature[c->index] != type)
1447 case SD_BUS_TYPE_STRING:
1448 case SD_BUS_TYPE_OBJECT_PATH: {
1453 r = message_peek_body(m, &rindex, 4, 4, &q);
1457 l = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
1458 r = message_peek_body(m, &rindex, 1, l+1, &q);
1464 if (type == SD_BUS_TYPE_OBJECT_PATH) {
1465 if (!validate_object_path(q, l))
1468 if (!validate_string(q, l))
1473 *(const char**) p = q;
1477 case SD_BUS_TYPE_SIGNATURE: {
1482 r = message_peek_body(m, &rindex, 1, 1, &q);
1487 r = message_peek_body(m, &rindex, 1, l+1, &q);
1493 if (!validate_signature(q, l))
1497 *(const char**) p = q;
1504 align = bus_type_get_alignment(type);
1505 sz = bus_type_get_size(type);
1507 r = message_peek_body(m, &m->rindex, align, sz, &q);
1513 case SD_BUS_TYPE_BYTE:
1514 *(uint8_t*) p = *(uint8_t*) q;
1517 case SD_BUS_TYPE_BOOLEAN:
1518 *(int*) p = !!*(uint32_t*) q;
1521 case SD_BUS_TYPE_INT16:
1522 case SD_BUS_TYPE_UINT16:
1523 *(uint16_t*) p = BUS_MESSAGE_BSWAP16(m, *(uint16_t*) q);
1526 case SD_BUS_TYPE_INT32:
1527 case SD_BUS_TYPE_UINT32:
1528 *(uint32_t*) p = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
1531 case SD_BUS_TYPE_INT64:
1532 case SD_BUS_TYPE_UINT64:
1533 case SD_BUS_TYPE_DOUBLE:
1534 *(uint64_t*) p = BUS_MESSAGE_BSWAP64(m, *(uint64_t*) q);
1538 assert_not_reached("Unknown basic type...");
1545 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1551 static int bus_message_enter_array(
1553 struct bus_container *c,
1554 const char *contents,
1555 uint32_t **array_size) {
1566 if (!signature_is_single(contents))
1569 alignment = bus_type_get_alignment(contents[0]);
1573 if (!c->signature || c->signature[c->index] == 0)
1576 if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
1579 if (!startswith(c->signature + c->index + 1, contents))
1583 r = message_peek_body(m, &rindex, 4, 4, &q);
1587 if (BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q) > BUS_ARRAY_MAX_SIZE)
1590 r = message_peek_body(m, &rindex, alignment, 0, NULL);
1596 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1597 c->index += 1 + strlen(contents);
1601 *array_size = (uint32_t*) q;
1606 static int bus_message_enter_variant(
1608 struct bus_container *c,
1609 const char *contents) {
1620 if (!signature_is_single(contents))
1623 if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
1626 if (!c->signature || c->signature[c->index] == 0)
1629 if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
1633 r = message_peek_body(m, &rindex, 1, 1, &q);
1638 r = message_peek_body(m, &rindex, 1, l+1, &q);
1644 if (!validate_signature(q, l))
1647 if (!streq(q, contents))
1650 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1658 static int bus_message_enter_struct(
1660 struct bus_container *c,
1661 const char *contents) {
1670 if (!signature_is_valid(contents, false))
1673 if (!c->signature || c->signature[c->index] == 0)
1676 l = strlen(contents);
1678 if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
1679 !startswith(c->signature + c->index + 1, contents) ||
1680 c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
1683 r = message_peek_body(m, &m->rindex, 8, 0, NULL);
1687 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1688 c->index += 1 + l + 1;
1693 static int bus_message_enter_dict_entry(
1695 struct bus_container *c,
1696 const char *contents) {
1705 if (!signature_is_pair(contents))
1708 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1711 if (!c->signature || c->signature[c->index] == 0)
1714 l = strlen(contents);
1716 if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
1717 !startswith(c->signature + c->index + 1, contents) ||
1718 c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
1721 r = message_peek_body(m, &m->rindex, 8, 0, NULL);
1725 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1726 c->index += 1 + l + 1;
1731 int sd_bus_message_enter_container(sd_bus_message *m, char type, const char *contents) {
1732 struct bus_container *c, *w;
1733 uint32_t *array_size = NULL;
1744 w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
1749 c = message_get_container(m);
1751 if (!c->signature || c->signature[c->index] == 0)
1754 signature = strdup(contents);
1758 if (type == SD_BUS_TYPE_ARRAY)
1759 r = bus_message_enter_array(m, c, contents, &array_size);
1760 else if (type == SD_BUS_TYPE_VARIANT)
1761 r = bus_message_enter_variant(m, c, contents);
1762 else if (type == SD_BUS_TYPE_STRUCT)
1763 r = bus_message_enter_struct(m, c, contents);
1764 else if (type == SD_BUS_TYPE_DICT_ENTRY)
1765 r = bus_message_enter_dict_entry(m, c, contents);
1774 /* OK, let's fill it in */
1775 w += m->n_containers++;
1776 w->enclosing = type;
1777 w->signature = signature;
1779 w->array_size = array_size;
1780 w->begin = m->rindex;
1785 int sd_bus_message_exit_container(sd_bus_message *m) {
1786 struct bus_container *c;
1792 if (m->n_containers <= 0)
1795 c = message_get_container(m);
1796 if (c->enclosing == SD_BUS_TYPE_ARRAY) {
1799 l = BUS_MESSAGE_BSWAP32(m, *c->array_size);
1800 if (c->begin + l != m->rindex)
1804 if (c->signature && c->signature[c->index] != 0)
1814 int sd_bus_message_peek_type(sd_bus_message *m, char *type, const char **contents) {
1815 struct bus_container *c;
1823 c = message_get_container(m);
1825 if (!c->signature || c->signature[c->index] == 0)
1828 if (message_end_of_array(m, m->rindex))
1831 if (bus_type_is_basic(c->signature[c->index])) {
1835 *type = c->signature[c->index];
1839 if (c->signature[c->index] == SD_BUS_TYPE_ARRAY) {
1845 r = signature_element_length(c->signature+c->index+1, &l);
1851 sig = strndup(c->signature + c->index + 1, l);
1855 free(m->peeked_signature);
1856 m->peeked_signature = sig;
1862 *type = SD_BUS_TYPE_ARRAY;
1867 if (c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ||
1868 c->signature[c->index] == SD_BUS_TYPE_DICT_ENTRY_BEGIN) {
1874 r = signature_element_length(c->signature+c->index, &l);
1879 sig = strndup(c->signature + c->index + 1, l - 2);
1883 free(m->peeked_signature);
1884 m->peeked_signature = sig;
1890 *type = c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY;
1895 if (c->signature[c->index] == SD_BUS_TYPE_VARIANT) {
1901 r = message_peek_body(m, &rindex, 1, 1, &q);
1908 r = message_peek_body(m, &rindex, 1, l+1, &q);
1914 if (!validate_signature(q, l))
1921 *type = SD_BUS_TYPE_VARIANT;
1930 *type = c->enclosing;
1936 int sd_bus_message_rewind(sd_bus_message *m, int complete) {
1937 struct bus_container *c;
1945 reset_containers(m);
1947 m->root_container.index = 0;
1949 c = message_get_container(m);
1951 c = message_get_container(m);
1954 m->rindex = c->begin;
1957 return !isempty(c->signature);
1960 static int message_read_ap(sd_bus_message *m, const char *types, va_list ap) {
1967 for (t = types; *t; t++) {
1970 case SD_BUS_TYPE_BYTE:
1971 case SD_BUS_TYPE_BOOLEAN:
1972 case SD_BUS_TYPE_INT16:
1973 case SD_BUS_TYPE_UINT16:
1974 case SD_BUS_TYPE_INT32:
1975 case SD_BUS_TYPE_UINT32:
1976 case SD_BUS_TYPE_INT64:
1977 case SD_BUS_TYPE_UINT64:
1978 case SD_BUS_TYPE_DOUBLE:
1979 case SD_BUS_TYPE_STRING:
1980 case SD_BUS_TYPE_OBJECT_PATH:
1981 case SD_BUS_TYPE_SIGNATURE: {
1984 p = va_arg(ap, void*);
1985 r = sd_bus_message_read_basic(m, *t, p);
1989 case SD_BUS_TYPE_ARRAY: {
1992 r = signature_element_length(t + 1, &k);
2000 memcpy(s, t + 1, k);
2004 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, s);
2010 n = va_arg(ap, unsigned);
2011 for (i = 0; i < n; i++) {
2012 r = message_read_ap(m, s, ap);
2017 r = sd_bus_message_exit_container(m);
2023 case SD_BUS_TYPE_VARIANT: {
2026 s = va_arg(ap, const char *);
2030 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, s);
2036 r = message_read_ap(m, s, ap);
2042 r = sd_bus_message_exit_container(m);
2046 case SD_BUS_TYPE_STRUCT_BEGIN:
2047 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
2050 r = signature_element_length(t, &k);
2056 memcpy(s, t + 1, k - 2);
2059 r = sd_bus_message_enter_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
2067 r = message_read_ap(m, s, ap);
2073 r = sd_bus_message_exit_container(m);
2092 int sd_bus_message_read(sd_bus_message *m, const char *types, ...) {
2103 va_start(ap, types);
2104 r = message_read_ap(m, types, ap);
2110 static int message_peek_fields(
2121 return buffer_peek(m->fields, BUS_MESSAGE_FIELDS_SIZE(m), rindex, align, nbytes, ret);
2124 static int message_peek_field_string(
2126 bool (*validate)(const char *p),
2137 r = message_peek_fields(m, ri, 4, 4, &q);
2141 l = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2142 r = message_peek_fields(m, ri, 1, l+1, &q);
2147 if (!validate_nul(q, l))
2153 if (!validate_string(q, l))
2163 static int message_peek_field_signature(
2175 r = message_peek_fields(m, ri, 1, 1, &q);
2180 r = message_peek_fields(m, ri, 1, l+1, &q);
2184 if (!validate_signature(q, l))
2193 static int message_peek_field_uint32(
2204 r = message_peek_fields(m, ri, 4, 4, &q);
2209 *ret = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2214 static int message_skip_fields(
2217 uint32_t array_size,
2218 const char **signature) {
2220 size_t original_index;
2227 original_index = *ri;
2234 if (array_size != (uint32_t) -1 &&
2235 array_size <= *ri - original_index)
2242 if (t == SD_BUS_TYPE_STRING) {
2244 r = message_peek_field_string(m, NULL, ri, NULL);
2250 } else if (t == SD_BUS_TYPE_OBJECT_PATH) {
2252 r = message_peek_field_string(m, object_path_is_valid, ri, NULL);
2258 } else if (t == SD_BUS_TYPE_SIGNATURE) {
2260 r = message_peek_field_signature(m, ri, NULL);
2266 } else if (bus_type_is_basic(t)) {
2269 align = bus_type_get_alignment(t);
2270 k = bus_type_get_size(t);
2272 r = message_peek_fields(m, ri, align, k, NULL);
2278 } else if (t == SD_BUS_TYPE_ARRAY) {
2280 r = signature_element_length(*signature+1, &l);
2290 strncpy(sig, *signature + 1, l-1);
2293 alignment = bus_type_get_alignment(sig[0]);
2297 r = message_peek_fields(m, ri, 4, 4, &q);
2301 nas = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2302 if (nas > BUS_ARRAY_MAX_SIZE)
2305 r = message_peek_fields(m, ri, alignment, 0, NULL);
2309 r = message_skip_fields(m, ri, nas, (const char**) &s);
2314 (*signature) += 1 + l;
2316 } else if (t == SD_BUS_TYPE_VARIANT) {
2319 r = message_peek_field_signature(m, ri, &s);
2323 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
2329 } else if (t == SD_BUS_TYPE_STRUCT ||
2330 t == SD_BUS_TYPE_DICT_ENTRY) {
2332 r = signature_element_length(*signature, &l);
2339 strncpy(sig, *signature + 1, l-1);
2342 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
2353 static int message_parse_fields(sd_bus_message *m) {
2359 for (ri = 0; ri < BUS_MESSAGE_FIELDS_SIZE(m); ) {
2360 const char *signature;
2363 r = message_peek_fields(m, &ri, 8, 1, (void**) &header);
2367 r = message_peek_field_signature(m, &ri, &signature);
2372 case _SD_BUS_MESSAGE_HEADER_INVALID:
2375 case SD_BUS_MESSAGE_HEADER_PATH:
2376 if (!streq(signature, "o"))
2379 r = message_peek_field_string(m, object_path_is_valid, &ri, &m->path);
2382 case SD_BUS_MESSAGE_HEADER_INTERFACE:
2383 if (!streq(signature, "s"))
2386 r = message_peek_field_string(m, interface_name_is_valid, &ri, &m->interface);
2389 case SD_BUS_MESSAGE_HEADER_MEMBER:
2390 if (!streq(signature, "s"))
2393 r = message_peek_field_string(m, member_name_is_valid, &ri, &m->member);
2396 case SD_BUS_MESSAGE_HEADER_ERROR_NAME:
2397 if (!streq(signature, "s"))
2400 r = message_peek_field_string(m, error_name_is_valid, &ri, &m->error.name);
2403 case SD_BUS_MESSAGE_HEADER_DESTINATION:
2404 if (!streq(signature, "s"))
2407 r = message_peek_field_string(m, service_name_is_valid, &ri, &m->destination);
2410 case SD_BUS_MESSAGE_HEADER_SENDER:
2411 if (!streq(signature, "s"))
2414 r = message_peek_field_string(m, service_name_is_valid, &ri, &m->sender);
2418 case SD_BUS_MESSAGE_HEADER_SIGNATURE: {
2422 if (!streq(signature, "g"))
2425 r = message_peek_field_signature(m, &ri, &s);
2433 free(m->root_container.signature);
2434 m->root_container.signature = c;
2440 case SD_BUS_MESSAGE_HEADER_REPLY_SERIAL:
2441 if (!streq(signature, "u"))
2444 r = message_peek_field_uint32(m, &ri, &m->reply_serial);
2448 if (m->reply_serial == 0)
2454 r = message_skip_fields(m, &ri, (uint32_t) -1, (const char **) &signature);
2461 if (isempty(m->root_container.signature) != (BUS_MESSAGE_BODY_SIZE(m) == 0))
2464 switch (m->header->type) {
2466 case SD_BUS_MESSAGE_TYPE_SIGNAL:
2467 if (!m->path || !m->interface || !m->member)
2471 case SD_BUS_MESSAGE_TYPE_METHOD_CALL:
2473 if (!m->path || !m->member)
2478 case SD_BUS_MESSAGE_TYPE_METHOD_RETURN:
2480 if (m->reply_serial == 0)
2484 case SD_BUS_MESSAGE_TYPE_METHOD_ERROR:
2486 if (m->reply_serial == 0 || !m->error.name)
2491 /* Try to read the error message, but if we can't it's a non-issue */
2492 if (m->header->type == SD_BUS_MESSAGE_TYPE_METHOD_ERROR)
2493 sd_bus_message_read(m, "s", &m->error.message);
2498 static void setup_iovec(sd_bus_message *m) {
2505 m->iovec[m->n_iovec].iov_base = m->header;
2506 m->iovec[m->n_iovec].iov_len = sizeof(*m->header);
2507 m->size += m->iovec[m->n_iovec].iov_len;
2511 m->iovec[m->n_iovec].iov_base = m->fields;
2512 m->iovec[m->n_iovec].iov_len = m->header->fields_size;
2513 m->size += m->iovec[m->n_iovec].iov_len;
2516 if (m->header->fields_size % 8 != 0) {
2517 static const uint8_t padding[7] = { 0, 0, 0, 0, 0, 0, 0 };
2519 m->iovec[m->n_iovec].iov_base = (void*) padding;
2520 m->iovec[m->n_iovec].iov_len = 8 - m->header->fields_size % 8;
2521 m->size += m->iovec[m->n_iovec].iov_len;
2527 m->iovec[m->n_iovec].iov_base = m->body;
2528 m->iovec[m->n_iovec].iov_len = m->header->body_size;
2529 m->size += m->iovec[m->n_iovec].iov_len;
2534 int bus_message_seal(sd_bus_message *m, uint64_t serial) {
2542 if (m->n_containers > 0)
2545 /* If there's a non-trivial signature set, then add it in here */
2546 if (!isempty(m->root_container.signature)) {
2547 r = message_append_field_signature(m, SD_BUS_MESSAGE_HEADER_SIGNATURE, m->root_container.signature, NULL);
2553 r = message_append_field_uint32(m, SD_BUS_MESSAGE_HEADER_UNIX_FDS, m->n_fds);
2558 m->header->serial = serial;
2566 int sd_bus_message_set_destination(sd_bus_message *m, const char *destination) {
2576 return message_append_field_string(m, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &m->destination);
2579 int bus_message_dump(sd_bus_message *m) {
2585 printf("Message %p\n"
2592 "\tfields_size=%u\n"
2597 "\tdestination=%s\n"
2600 "\treply_serial=%u\n"
2602 "\terror.message=%s\n"
2610 BUS_MESSAGE_SERIAL(m),
2611 BUS_MESSAGE_FIELDS_SIZE(m),
2612 BUS_MESSAGE_BODY_SIZE(m),
2614 strna(m->interface),
2616 strna(m->destination),
2618 strna(m->root_container.signature),
2620 strna(m->error.name),
2621 strna(m->error.message),
2624 r = sd_bus_message_rewind(m, true);
2626 log_error("Failed to rewind: %s", strerror(-r));
2630 printf("BEGIN_MESSAGE \"%s\" {\n", strempty(m->root_container.signature));
2633 _cleanup_free_ char *prefix = NULL;
2634 const char *contents = NULL;
2649 r = sd_bus_message_peek_type(m, &type, &contents);
2651 log_error("Failed to peek type: %s", strerror(-r));
2658 r = sd_bus_message_exit_container(m);
2660 log_error("Failed to exit container: %s", strerror(-r));
2666 prefix = strrep("\t", level);
2670 if (type == SD_BUS_TYPE_ARRAY)
2671 printf("%s} END_ARRAY \n", prefix);
2672 else if (type == SD_BUS_TYPE_VARIANT)
2673 printf("%s} END_VARIANT\n", prefix);
2674 else if (type == SD_BUS_TYPE_STRUCT)
2675 printf("%s} END_STRUCT\n", prefix);
2676 else if (type == SD_BUS_TYPE_DICT_ENTRY)
2677 printf("%s} END_DICT_ENTRY\n", prefix);
2682 prefix = strrep("\t", level);
2686 if (bus_type_is_container(type) > 0) {
2687 r = sd_bus_message_enter_container(m, type, contents);
2689 log_error("Failed to enter container: %s", strerror(-r));
2693 if (type == SD_BUS_TYPE_ARRAY)
2694 printf("%sBEGIN_ARRAY \"%s\" {\n", prefix, contents);
2695 else if (type == SD_BUS_TYPE_VARIANT)
2696 printf("%sBEGIN_VARIANT \"%s\" {\n", prefix, contents);
2697 else if (type == SD_BUS_TYPE_STRUCT)
2698 printf("%sBEGIN_STRUCT \"%s\" {\n", prefix, contents);
2699 else if (type == SD_BUS_TYPE_DICT_ENTRY)
2700 printf("%sBEGIN_DICT_ENTRY \"%s\" {\n", prefix, contents);
2707 r = sd_bus_message_read_basic(m, type, &basic);
2709 log_error("Failed to get basic: %s", strerror(-r));
2715 case SD_BUS_TYPE_BYTE:
2716 printf("%sBYTE: %u\n", prefix, basic.u8);
2719 case SD_BUS_TYPE_BOOLEAN:
2720 printf("%sBOOLEAN: %s\n", prefix, yes_no(basic.i));
2723 case SD_BUS_TYPE_INT16:
2724 printf("%sINT16: %i\n", prefix, basic.s16);
2727 case SD_BUS_TYPE_UINT16:
2728 printf("%sUINT16: %u\n", prefix, basic.u16);
2731 case SD_BUS_TYPE_INT32:
2732 printf("%sINT32: %i\n", prefix, basic.s32);
2735 case SD_BUS_TYPE_UINT32:
2736 printf("%sUINT32: %u\n", prefix, basic.u32);
2739 case SD_BUS_TYPE_INT64:
2740 printf("%sINT64: %lli\n", prefix, (long long) basic.s64);
2743 case SD_BUS_TYPE_UINT64:
2744 printf("%sUINT64: %llu\n", prefix, (unsigned long long) basic.u64);
2747 case SD_BUS_TYPE_DOUBLE:
2748 printf("%sDOUBLE: %g\n", prefix, basic.d64);
2751 case SD_BUS_TYPE_STRING:
2752 printf("%sSTRING: \"%s\"\n", prefix, basic.string);
2755 case SD_BUS_TYPE_OBJECT_PATH:
2756 printf("%sOBJECT_PATH: \"%s\"\n", prefix, basic.string);
2759 case SD_BUS_TYPE_SIGNATURE:
2760 printf("%sSIGNATURE: \"%s\"\n", prefix, basic.string);
2763 case SD_BUS_TYPE_UNIX_FD:
2764 printf("%sUNIX_FD: %i\n", prefix, basic.i);
2768 assert_not_reached("Unknown basic type.");
2772 printf("} END_MESSAGE\n");
2776 int bus_message_get_blob(sd_bus_message *m, void **buffer, size_t *sz) {
2785 for (i = 0, total = 0; i < m->n_iovec; i++)
2786 total += m->iovec[i].iov_len;
2792 for (i = 0, e = p; i < m->n_iovec; i++)
2793 e = mempcpy(e, m->iovec[i].iov_base, m->iovec[i].iov_len);
2801 int bus_message_read_strv_extend(sd_bus_message *m, char ***l) {
2807 r = sd_bus_message_enter_container(m, 'a', "s");
2814 r = sd_bus_message_read_basic(m, 's', &s);
2820 r = strv_extend(l, s);
2825 r = sd_bus_message_exit_container(m);