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;
1745 * We enforce a global limit on container depth, that is much
1746 * higher than the 32 structs and 32 arrays the specification
1747 * mandates. This is simpler to implement for us, and we need
1748 * this only to ensure our container array doesn't grow
1749 * without bounds. We are happy to return any data from a
1750 * message as long as the data itself is valid, even if the
1751 * overall message might be not.
1753 * Note that the message signature is validated when
1754 * parsing the headers, and that validation does check the
1757 * Note that the specification defines no limits on the depth
1758 * of stacked variants, but we do.
1760 if (m->n_containers >= BUS_CONTAINER_DEPTH)
1763 w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
1768 c = message_get_container(m);
1770 if (!c->signature || c->signature[c->index] == 0)
1773 signature = strdup(contents);
1777 if (type == SD_BUS_TYPE_ARRAY)
1778 r = bus_message_enter_array(m, c, contents, &array_size);
1779 else if (type == SD_BUS_TYPE_VARIANT)
1780 r = bus_message_enter_variant(m, c, contents);
1781 else if (type == SD_BUS_TYPE_STRUCT)
1782 r = bus_message_enter_struct(m, c, contents);
1783 else if (type == SD_BUS_TYPE_DICT_ENTRY)
1784 r = bus_message_enter_dict_entry(m, c, contents);
1793 /* OK, let's fill it in */
1794 w += m->n_containers++;
1795 w->enclosing = type;
1796 w->signature = signature;
1798 w->array_size = array_size;
1799 w->begin = m->rindex;
1804 int sd_bus_message_exit_container(sd_bus_message *m) {
1805 struct bus_container *c;
1811 if (m->n_containers <= 0)
1814 c = message_get_container(m);
1815 if (c->enclosing == SD_BUS_TYPE_ARRAY) {
1818 l = BUS_MESSAGE_BSWAP32(m, *c->array_size);
1819 if (c->begin + l != m->rindex)
1823 if (c->signature && c->signature[c->index] != 0)
1833 int sd_bus_message_peek_type(sd_bus_message *m, char *type, const char **contents) {
1834 struct bus_container *c;
1842 c = message_get_container(m);
1844 if (!c->signature || c->signature[c->index] == 0)
1847 if (message_end_of_array(m, m->rindex))
1850 if (bus_type_is_basic(c->signature[c->index])) {
1854 *type = c->signature[c->index];
1858 if (c->signature[c->index] == SD_BUS_TYPE_ARRAY) {
1864 r = signature_element_length(c->signature+c->index+1, &l);
1870 sig = strndup(c->signature + c->index + 1, l);
1874 free(m->peeked_signature);
1875 m->peeked_signature = sig;
1881 *type = SD_BUS_TYPE_ARRAY;
1886 if (c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ||
1887 c->signature[c->index] == SD_BUS_TYPE_DICT_ENTRY_BEGIN) {
1893 r = signature_element_length(c->signature+c->index, &l);
1898 sig = strndup(c->signature + c->index + 1, l - 2);
1902 free(m->peeked_signature);
1903 m->peeked_signature = sig;
1909 *type = c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY;
1914 if (c->signature[c->index] == SD_BUS_TYPE_VARIANT) {
1920 r = message_peek_body(m, &rindex, 1, 1, &q);
1927 r = message_peek_body(m, &rindex, 1, l+1, &q);
1933 if (!validate_signature(q, l))
1940 *type = SD_BUS_TYPE_VARIANT;
1949 *type = c->enclosing;
1955 int sd_bus_message_rewind(sd_bus_message *m, int complete) {
1956 struct bus_container *c;
1964 reset_containers(m);
1966 m->root_container.index = 0;
1968 c = message_get_container(m);
1970 c = message_get_container(m);
1973 m->rindex = c->begin;
1976 return !isempty(c->signature);
1979 static int message_read_ap(sd_bus_message *m, const char *types, va_list ap) {
1986 for (t = types; *t; t++) {
1989 case SD_BUS_TYPE_BYTE:
1990 case SD_BUS_TYPE_BOOLEAN:
1991 case SD_BUS_TYPE_INT16:
1992 case SD_BUS_TYPE_UINT16:
1993 case SD_BUS_TYPE_INT32:
1994 case SD_BUS_TYPE_UINT32:
1995 case SD_BUS_TYPE_INT64:
1996 case SD_BUS_TYPE_UINT64:
1997 case SD_BUS_TYPE_DOUBLE:
1998 case SD_BUS_TYPE_STRING:
1999 case SD_BUS_TYPE_OBJECT_PATH:
2000 case SD_BUS_TYPE_SIGNATURE: {
2003 p = va_arg(ap, void*);
2004 r = sd_bus_message_read_basic(m, *t, p);
2008 case SD_BUS_TYPE_ARRAY: {
2011 r = signature_element_length(t + 1, &k);
2019 memcpy(s, t + 1, k);
2023 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, s);
2029 n = va_arg(ap, unsigned);
2030 for (i = 0; i < n; i++) {
2031 r = message_read_ap(m, s, ap);
2036 r = sd_bus_message_exit_container(m);
2042 case SD_BUS_TYPE_VARIANT: {
2045 s = va_arg(ap, const char *);
2049 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, s);
2055 r = message_read_ap(m, s, ap);
2061 r = sd_bus_message_exit_container(m);
2065 case SD_BUS_TYPE_STRUCT_BEGIN:
2066 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
2069 r = signature_element_length(t, &k);
2075 memcpy(s, t + 1, k - 2);
2078 r = sd_bus_message_enter_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
2086 r = message_read_ap(m, s, ap);
2092 r = sd_bus_message_exit_container(m);
2111 int sd_bus_message_read(sd_bus_message *m, const char *types, ...) {
2122 va_start(ap, types);
2123 r = message_read_ap(m, types, ap);
2129 static int message_peek_fields(
2140 return buffer_peek(m->fields, BUS_MESSAGE_FIELDS_SIZE(m), rindex, align, nbytes, ret);
2143 static int message_peek_field_uint32(
2154 r = message_peek_fields(m, ri, 4, 4, &q);
2159 *ret = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2164 static int message_peek_field_string(
2166 bool (*validate)(const char *p),
2177 r = message_peek_field_uint32(m, ri, &l);
2181 r = message_peek_fields(m, ri, 1, l+1, &q);
2186 if (!validate_nul(q, l))
2192 if (!validate_string(q, l))
2202 static int message_peek_field_signature(
2214 r = message_peek_fields(m, ri, 1, 1, &q);
2219 r = message_peek_fields(m, ri, 1, l+1, &q);
2223 if (!validate_signature(q, l))
2232 static int message_skip_fields(
2235 uint32_t array_size,
2236 const char **signature) {
2238 size_t original_index;
2245 original_index = *ri;
2251 if (array_size != (uint32_t) -1 &&
2252 array_size <= *ri - original_index)
2259 if (t == SD_BUS_TYPE_STRING) {
2261 r = message_peek_field_string(m, NULL, ri, NULL);
2267 } else if (t == SD_BUS_TYPE_OBJECT_PATH) {
2269 r = message_peek_field_string(m, object_path_is_valid, ri, NULL);
2275 } else if (t == SD_BUS_TYPE_SIGNATURE) {
2277 r = message_peek_field_signature(m, ri, NULL);
2283 } else if (bus_type_is_basic(t)) {
2286 align = bus_type_get_alignment(t);
2287 k = bus_type_get_size(t);
2289 r = message_peek_fields(m, ri, align, k, NULL);
2295 } else if (t == SD_BUS_TYPE_ARRAY) {
2297 r = signature_element_length(*signature+1, &l);
2307 strncpy(sig, *signature + 1, l-1);
2310 alignment = bus_type_get_alignment(sig[0]);
2314 r = message_peek_field_uint32(m, ri, &nas);
2317 if (nas > BUS_ARRAY_MAX_SIZE)
2320 r = message_peek_fields(m, ri, alignment, 0, NULL);
2324 r = message_skip_fields(m, ri, nas, (const char**) &s);
2329 (*signature) += 1 + l;
2331 } else if (t == SD_BUS_TYPE_VARIANT) {
2334 r = message_peek_field_signature(m, ri, &s);
2338 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
2344 } else if (t == SD_BUS_TYPE_STRUCT ||
2345 t == SD_BUS_TYPE_DICT_ENTRY) {
2347 r = signature_element_length(*signature, &l);
2354 strncpy(sig, *signature + 1, l-1);
2357 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
2368 static int message_parse_fields(sd_bus_message *m) {
2374 for (ri = 0; ri < BUS_MESSAGE_FIELDS_SIZE(m); ) {
2375 const char *signature;
2378 r = message_peek_fields(m, &ri, 8, 1, (void**) &header);
2382 r = message_peek_field_signature(m, &ri, &signature);
2387 case _SD_BUS_MESSAGE_HEADER_INVALID:
2390 case SD_BUS_MESSAGE_HEADER_PATH:
2391 if (!streq(signature, "o"))
2394 r = message_peek_field_string(m, object_path_is_valid, &ri, &m->path);
2397 case SD_BUS_MESSAGE_HEADER_INTERFACE:
2398 if (!streq(signature, "s"))
2401 r = message_peek_field_string(m, interface_name_is_valid, &ri, &m->interface);
2404 case SD_BUS_MESSAGE_HEADER_MEMBER:
2405 if (!streq(signature, "s"))
2408 r = message_peek_field_string(m, member_name_is_valid, &ri, &m->member);
2411 case SD_BUS_MESSAGE_HEADER_ERROR_NAME:
2412 if (!streq(signature, "s"))
2415 r = message_peek_field_string(m, error_name_is_valid, &ri, &m->error.name);
2418 case SD_BUS_MESSAGE_HEADER_DESTINATION:
2419 if (!streq(signature, "s"))
2422 r = message_peek_field_string(m, service_name_is_valid, &ri, &m->destination);
2425 case SD_BUS_MESSAGE_HEADER_SENDER:
2426 if (!streq(signature, "s"))
2429 r = message_peek_field_string(m, service_name_is_valid, &ri, &m->sender);
2433 case SD_BUS_MESSAGE_HEADER_SIGNATURE: {
2437 if (!streq(signature, "g"))
2440 r = message_peek_field_signature(m, &ri, &s);
2448 free(m->root_container.signature);
2449 m->root_container.signature = c;
2453 case SD_BUS_MESSAGE_HEADER_REPLY_SERIAL:
2454 if (!streq(signature, "u"))
2457 r = message_peek_field_uint32(m, &ri, &m->reply_serial);
2461 if (m->reply_serial == 0)
2467 r = message_skip_fields(m, &ri, (uint32_t) -1, (const char **) &signature);
2474 if (isempty(m->root_container.signature) != (BUS_MESSAGE_BODY_SIZE(m) == 0))
2477 switch (m->header->type) {
2479 case SD_BUS_MESSAGE_TYPE_SIGNAL:
2480 if (!m->path || !m->interface || !m->member)
2484 case SD_BUS_MESSAGE_TYPE_METHOD_CALL:
2486 if (!m->path || !m->member)
2491 case SD_BUS_MESSAGE_TYPE_METHOD_RETURN:
2493 if (m->reply_serial == 0)
2497 case SD_BUS_MESSAGE_TYPE_METHOD_ERROR:
2499 if (m->reply_serial == 0 || !m->error.name)
2504 /* Try to read the error message, but if we can't it's a non-issue */
2505 if (m->header->type == SD_BUS_MESSAGE_TYPE_METHOD_ERROR)
2506 sd_bus_message_read(m, "s", &m->error.message);
2511 static void setup_iovec(sd_bus_message *m) {
2518 m->iovec[m->n_iovec].iov_base = m->header;
2519 m->iovec[m->n_iovec].iov_len = sizeof(*m->header);
2520 m->size += m->iovec[m->n_iovec].iov_len;
2524 m->iovec[m->n_iovec].iov_base = m->fields;
2525 m->iovec[m->n_iovec].iov_len = m->header->fields_size;
2526 m->size += m->iovec[m->n_iovec].iov_len;
2529 if (m->header->fields_size % 8 != 0) {
2530 static const uint8_t padding[7] = { 0, 0, 0, 0, 0, 0, 0 };
2532 m->iovec[m->n_iovec].iov_base = (void*) padding;
2533 m->iovec[m->n_iovec].iov_len = 8 - m->header->fields_size % 8;
2534 m->size += m->iovec[m->n_iovec].iov_len;
2540 m->iovec[m->n_iovec].iov_base = m->body;
2541 m->iovec[m->n_iovec].iov_len = m->header->body_size;
2542 m->size += m->iovec[m->n_iovec].iov_len;
2547 int bus_message_seal(sd_bus_message *m, uint64_t serial) {
2555 if (m->n_containers > 0)
2558 /* If there's a non-trivial signature set, then add it in here */
2559 if (!isempty(m->root_container.signature)) {
2560 r = message_append_field_signature(m, SD_BUS_MESSAGE_HEADER_SIGNATURE, m->root_container.signature, NULL);
2566 r = message_append_field_uint32(m, SD_BUS_MESSAGE_HEADER_UNIX_FDS, m->n_fds);
2571 m->header->serial = serial;
2579 int sd_bus_message_set_destination(sd_bus_message *m, const char *destination) {
2589 return message_append_field_string(m, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &m->destination);
2592 int bus_message_dump(sd_bus_message *m) {
2598 printf("Message %p\n"
2605 "\tfields_size=%u\n"
2610 "\tdestination=%s\n"
2613 "\treply_serial=%u\n"
2615 "\terror.message=%s\n"
2623 BUS_MESSAGE_SERIAL(m),
2624 BUS_MESSAGE_FIELDS_SIZE(m),
2625 BUS_MESSAGE_BODY_SIZE(m),
2627 strna(m->interface),
2629 strna(m->destination),
2631 strna(m->root_container.signature),
2633 strna(m->error.name),
2634 strna(m->error.message),
2637 r = sd_bus_message_rewind(m, true);
2639 log_error("Failed to rewind: %s", strerror(-r));
2643 printf("BEGIN_MESSAGE \"%s\" {\n", strempty(m->root_container.signature));
2646 _cleanup_free_ char *prefix = NULL;
2647 const char *contents = NULL;
2662 r = sd_bus_message_peek_type(m, &type, &contents);
2664 log_error("Failed to peek type: %s", strerror(-r));
2671 r = sd_bus_message_exit_container(m);
2673 log_error("Failed to exit container: %s", strerror(-r));
2679 prefix = strrep("\t", level);
2683 if (type == SD_BUS_TYPE_ARRAY)
2684 printf("%s} END_ARRAY \n", prefix);
2685 else if (type == SD_BUS_TYPE_VARIANT)
2686 printf("%s} END_VARIANT\n", prefix);
2687 else if (type == SD_BUS_TYPE_STRUCT)
2688 printf("%s} END_STRUCT\n", prefix);
2689 else if (type == SD_BUS_TYPE_DICT_ENTRY)
2690 printf("%s} END_DICT_ENTRY\n", prefix);
2695 prefix = strrep("\t", level);
2699 if (bus_type_is_container(type) > 0) {
2700 r = sd_bus_message_enter_container(m, type, contents);
2702 log_error("Failed to enter container: %s", strerror(-r));
2706 if (type == SD_BUS_TYPE_ARRAY)
2707 printf("%sBEGIN_ARRAY \"%s\" {\n", prefix, contents);
2708 else if (type == SD_BUS_TYPE_VARIANT)
2709 printf("%sBEGIN_VARIANT \"%s\" {\n", prefix, contents);
2710 else if (type == SD_BUS_TYPE_STRUCT)
2711 printf("%sBEGIN_STRUCT \"%s\" {\n", prefix, contents);
2712 else if (type == SD_BUS_TYPE_DICT_ENTRY)
2713 printf("%sBEGIN_DICT_ENTRY \"%s\" {\n", prefix, contents);
2720 r = sd_bus_message_read_basic(m, type, &basic);
2722 log_error("Failed to get basic: %s", strerror(-r));
2728 case SD_BUS_TYPE_BYTE:
2729 printf("%sBYTE: %u\n", prefix, basic.u8);
2732 case SD_BUS_TYPE_BOOLEAN:
2733 printf("%sBOOLEAN: %s\n", prefix, yes_no(basic.i));
2736 case SD_BUS_TYPE_INT16:
2737 printf("%sINT16: %i\n", prefix, basic.s16);
2740 case SD_BUS_TYPE_UINT16:
2741 printf("%sUINT16: %u\n", prefix, basic.u16);
2744 case SD_BUS_TYPE_INT32:
2745 printf("%sINT32: %i\n", prefix, basic.s32);
2748 case SD_BUS_TYPE_UINT32:
2749 printf("%sUINT32: %u\n", prefix, basic.u32);
2752 case SD_BUS_TYPE_INT64:
2753 printf("%sINT64: %lli\n", prefix, (long long) basic.s64);
2756 case SD_BUS_TYPE_UINT64:
2757 printf("%sUINT64: %llu\n", prefix, (unsigned long long) basic.u64);
2760 case SD_BUS_TYPE_DOUBLE:
2761 printf("%sDOUBLE: %g\n", prefix, basic.d64);
2764 case SD_BUS_TYPE_STRING:
2765 printf("%sSTRING: \"%s\"\n", prefix, basic.string);
2768 case SD_BUS_TYPE_OBJECT_PATH:
2769 printf("%sOBJECT_PATH: \"%s\"\n", prefix, basic.string);
2772 case SD_BUS_TYPE_SIGNATURE:
2773 printf("%sSIGNATURE: \"%s\"\n", prefix, basic.string);
2776 case SD_BUS_TYPE_UNIX_FD:
2777 printf("%sUNIX_FD: %i\n", prefix, basic.i);
2781 assert_not_reached("Unknown basic type.");
2785 printf("} END_MESSAGE\n");
2789 int bus_message_get_blob(sd_bus_message *m, void **buffer, size_t *sz) {
2798 for (i = 0, total = 0; i < m->n_iovec; i++)
2799 total += m->iovec[i].iov_len;
2805 for (i = 0, e = p; i < m->n_iovec; i++)
2806 e = mempcpy(e, m->iovec[i].iov_base, m->iovec[i].iov_len);
2814 int bus_message_read_strv_extend(sd_bus_message *m, char ***l) {
2820 r = sd_bus_message_enter_container(m, 'a', "s");
2827 r = sd_bus_message_read_basic(m, 's', &s);
2833 r = strv_extend(l, s);
2838 r = sd_bus_message_exit_container(m);