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_string(const char *s, size_t l) {
1380 /* Check for NUL chars in the string */
1381 if (memchr(s, 0, l))
1384 /* Check for NUL termination */
1388 /* Check if valid UTF8 */
1389 if (!utf8_is_valid(s))
1395 static bool validate_signature(const char *s, size_t l) {
1396 /* Check for NUL chars in the signature */
1397 if (memchr(s, 0, l))
1400 /* Check for NUL termination */
1404 /* Check if valid signature */
1405 if (!signature_is_valid(s, true))
1411 int sd_bus_message_read_basic(sd_bus_message *m, char type, void *p) {
1412 struct bus_container *c;
1420 if (!bus_type_is_basic(type))
1423 c = message_get_container(m);
1425 if (!c->signature || c->signature[c->index] == 0)
1428 if (c->signature[c->index] != type)
1433 case SD_BUS_TYPE_STRING:
1434 case SD_BUS_TYPE_OBJECT_PATH: {
1439 r = message_peek_body(m, &rindex, 4, 4, &q);
1443 l = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
1444 r = message_peek_body(m, &rindex, 1, l+1, &q);
1450 if (!validate_string(q, l))
1454 *(const char**) p = q;
1458 case SD_BUS_TYPE_SIGNATURE: {
1463 r = message_peek_body(m, &rindex, 1, 1, &q);
1468 r = message_peek_body(m, &rindex, 1, l+1, &q);
1474 if (!validate_signature(q, l))
1478 *(const char**) p = q;
1485 align = bus_type_get_alignment(type);
1486 sz = bus_type_get_size(type);
1488 r = message_peek_body(m, &m->rindex, align, sz, &q);
1494 case SD_BUS_TYPE_BYTE:
1495 *(uint8_t*) p = *(uint8_t*) q;
1498 case SD_BUS_TYPE_BOOLEAN:
1499 *(int*) p = !!*(uint32_t*) q;
1502 case SD_BUS_TYPE_INT16:
1503 case SD_BUS_TYPE_UINT16:
1504 *(uint16_t*) p = BUS_MESSAGE_BSWAP16(m, *(uint16_t*) q);
1507 case SD_BUS_TYPE_INT32:
1508 case SD_BUS_TYPE_UINT32:
1509 *(uint32_t*) p = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
1512 case SD_BUS_TYPE_INT64:
1513 case SD_BUS_TYPE_UINT64:
1514 case SD_BUS_TYPE_DOUBLE:
1515 *(uint64_t*) p = BUS_MESSAGE_BSWAP64(m, *(uint64_t*) q);
1519 assert_not_reached("Unknown basic type...");
1526 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1532 static int bus_message_enter_array(
1534 struct bus_container *c,
1535 const char *contents,
1536 uint32_t **array_size) {
1547 if (!signature_is_single(contents))
1550 alignment = bus_type_get_alignment(contents[0]);
1554 if (!c->signature || c->signature[c->index] == 0)
1557 if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
1560 if (!startswith(c->signature + c->index + 1, contents))
1564 r = message_peek_body(m, &rindex, 4, 4, &q);
1568 if (BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q) > 67108864)
1571 r = message_peek_body(m, &rindex, alignment, 0, NULL);
1577 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1578 c->index += 1 + strlen(contents);
1582 *array_size = (uint32_t*) q;
1587 static int bus_message_enter_variant(
1589 struct bus_container *c,
1590 const char *contents) {
1601 if (!signature_is_single(contents))
1604 if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
1607 if (!c->signature || c->signature[c->index] == 0)
1610 if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
1614 r = message_peek_body(m, &rindex, 1, 1, &q);
1619 r = message_peek_body(m, &rindex, 1, l+1, &q);
1625 if (!validate_signature(q, l))
1628 if (!streq(q, contents))
1631 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1639 static int bus_message_enter_struct(
1641 struct bus_container *c,
1642 const char *contents) {
1651 if (!signature_is_valid(contents, false))
1654 if (!c->signature || c->signature[c->index] == 0)
1657 l = strlen(contents);
1659 if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
1660 !startswith(c->signature + c->index + 1, contents) ||
1661 c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
1664 r = message_peek_body(m, &m->rindex, 8, 0, NULL);
1668 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1669 c->index += 1 + l + 1;
1674 static int bus_message_enter_dict_entry(
1676 struct bus_container *c,
1677 const char *contents) {
1686 if (!signature_is_pair(contents))
1689 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1692 if (!c->signature || c->signature[c->index] == 0)
1695 l = strlen(contents);
1697 if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
1698 !startswith(c->signature + c->index + 1, contents) ||
1699 c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
1702 r = message_peek_body(m, &m->rindex, 8, 0, NULL);
1706 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1707 c->index += 1 + l + 1;
1712 int sd_bus_message_enter_container(sd_bus_message *m, char type, const char *contents) {
1713 struct bus_container *c, *w;
1714 uint32_t *array_size = NULL;
1725 w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
1730 c = message_get_container(m);
1732 if (!c->signature || c->signature[c->index] == 0)
1735 signature = strdup(contents);
1739 if (type == SD_BUS_TYPE_ARRAY)
1740 r = bus_message_enter_array(m, c, contents, &array_size);
1741 else if (type == SD_BUS_TYPE_VARIANT)
1742 r = bus_message_enter_variant(m, c, contents);
1743 else if (type == SD_BUS_TYPE_STRUCT)
1744 r = bus_message_enter_struct(m, c, contents);
1745 else if (type == SD_BUS_TYPE_DICT_ENTRY)
1746 r = bus_message_enter_dict_entry(m, c, contents);
1755 /* OK, let's fill it in */
1756 w += m->n_containers++;
1757 w->enclosing = type;
1758 w->signature = signature;
1760 w->array_size = array_size;
1761 w->begin = m->rindex;
1766 int sd_bus_message_exit_container(sd_bus_message *m) {
1767 struct bus_container *c;
1773 if (m->n_containers <= 0)
1776 c = message_get_container(m);
1777 if (c->enclosing == SD_BUS_TYPE_ARRAY) {
1780 l = BUS_MESSAGE_BSWAP32(m, *c->array_size);
1781 if (c->begin + l != m->rindex)
1785 if (c->signature && c->signature[c->index] != 0)
1795 int sd_bus_message_peek_type(sd_bus_message *m, char *type, const char **contents) {
1796 struct bus_container *c;
1804 c = message_get_container(m);
1806 if (!c->signature || c->signature[c->index] == 0)
1809 if (message_end_of_array(m, m->rindex))
1812 if (bus_type_is_basic(c->signature[c->index])) {
1816 *type = c->signature[c->index];
1820 if (c->signature[c->index] == SD_BUS_TYPE_ARRAY) {
1826 r = signature_element_length(c->signature+c->index+1, &l);
1832 sig = strndup(c->signature + c->index + 1, l);
1836 free(m->peeked_signature);
1837 m->peeked_signature = sig;
1843 *type = SD_BUS_TYPE_ARRAY;
1848 if (c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ||
1849 c->signature[c->index] == SD_BUS_TYPE_DICT_ENTRY_BEGIN) {
1855 r = signature_element_length(c->signature+c->index, &l);
1860 sig = strndup(c->signature + c->index + 1, l - 2);
1864 free(m->peeked_signature);
1865 m->peeked_signature = sig;
1871 *type = c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY;
1876 if (c->signature[c->index] == SD_BUS_TYPE_VARIANT) {
1882 r = message_peek_body(m, &rindex, 1, 1, &q);
1889 r = message_peek_body(m, &rindex, 1, l+1, &q);
1895 if (!validate_signature(q, l))
1902 *type = SD_BUS_TYPE_VARIANT;
1911 *type = c->enclosing;
1917 int sd_bus_message_rewind(sd_bus_message *m, int complete) {
1918 struct bus_container *c;
1926 reset_containers(m);
1928 m->root_container.index = 0;
1930 c = message_get_container(m);
1932 c = message_get_container(m);
1935 m->rindex = c->begin;
1938 return !isempty(c->signature);
1941 static int message_read_ap(sd_bus_message *m, const char *types, va_list ap) {
1948 for (t = types; *t; t++) {
1951 case SD_BUS_TYPE_BYTE:
1952 case SD_BUS_TYPE_BOOLEAN:
1953 case SD_BUS_TYPE_INT16:
1954 case SD_BUS_TYPE_UINT16:
1955 case SD_BUS_TYPE_INT32:
1956 case SD_BUS_TYPE_UINT32:
1957 case SD_BUS_TYPE_INT64:
1958 case SD_BUS_TYPE_UINT64:
1959 case SD_BUS_TYPE_DOUBLE:
1960 case SD_BUS_TYPE_STRING:
1961 case SD_BUS_TYPE_OBJECT_PATH:
1962 case SD_BUS_TYPE_SIGNATURE: {
1965 p = va_arg(ap, void*);
1966 r = sd_bus_message_read_basic(m, *t, p);
1970 case SD_BUS_TYPE_ARRAY: {
1973 r = signature_element_length(t + 1, &k);
1981 memcpy(s, t + 1, k);
1985 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, s);
1991 n = va_arg(ap, unsigned);
1992 for (i = 0; i < n; i++) {
1993 r = message_read_ap(m, s, ap);
1998 r = sd_bus_message_exit_container(m);
2004 case SD_BUS_TYPE_VARIANT: {
2007 s = va_arg(ap, const char *);
2011 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, s);
2017 r = message_read_ap(m, s, ap);
2023 r = sd_bus_message_exit_container(m);
2027 case SD_BUS_TYPE_STRUCT_BEGIN:
2028 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
2031 r = signature_element_length(t, &k);
2037 memcpy(s, t + 1, k - 2);
2040 r = sd_bus_message_enter_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
2048 r = message_read_ap(m, s, ap);
2054 r = sd_bus_message_exit_container(m);
2073 int sd_bus_message_read(sd_bus_message *m, const char *types, ...) {
2084 va_start(ap, types);
2085 r = message_read_ap(m, types, ap);
2091 static int message_peek_fields(
2102 return buffer_peek(m->fields, BUS_MESSAGE_FIELDS_SIZE(m), rindex, align, nbytes, ret);
2105 static int message_peek_field_string(
2117 r = message_peek_fields(m, ri, 4, 4, &q);
2121 l = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2122 r = message_peek_fields(m, ri, 1, l+1, &q);
2126 if (!validate_string(q, l))
2135 static int message_peek_field_signature(
2147 r = message_peek_fields(m, ri, 1, 1, &q);
2152 r = message_peek_fields(m, ri, 1, l+1, &q);
2156 if (!validate_signature(q, l))
2165 static int message_peek_field_uint32(
2176 r = message_peek_fields(m, ri, 4, 4, &q);
2181 *ret = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2186 static int message_skip_fields(
2189 uint32_t array_size,
2190 const char **signature) {
2192 size_t original_index;
2199 original_index = *ri;
2206 if (array_size != (uint32_t) -1 &&
2207 array_size <= *ri - original_index)
2214 if (t == SD_BUS_TYPE_STRING ||
2215 t == SD_BUS_TYPE_OBJECT_PATH) {
2217 r = message_peek_field_string(m, ri, NULL);
2223 } else if (t == SD_BUS_TYPE_SIGNATURE) {
2225 r = message_peek_field_signature(m, ri, NULL);
2231 } else if (bus_type_is_basic(t)) {
2234 align = bus_type_get_alignment(t);
2235 k = bus_type_get_size(t);
2237 r = message_peek_fields(m, ri, align, k, NULL);
2243 } else if (t == SD_BUS_TYPE_ARRAY) {
2245 r = signature_element_length(*signature+1, &l);
2255 strncpy(sig, *signature + 1, l-1);
2258 alignment = bus_type_get_alignment(sig[0]);
2262 r = message_peek_fields(m, ri, 4, 4, &q);
2266 nas = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2270 r = message_peek_fields(m, ri, alignment, 0, NULL);
2274 r = message_skip_fields(m, ri, nas, (const char**) &s);
2279 (*signature) += 1 + l;
2281 } else if (t == SD_BUS_TYPE_VARIANT) {
2284 r = message_peek_field_signature(m, ri, &s);
2288 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
2294 } else if (t == SD_BUS_TYPE_STRUCT ||
2295 t == SD_BUS_TYPE_DICT_ENTRY) {
2297 r = signature_element_length(*signature, &l);
2304 strncpy(sig, *signature + 1, l-1);
2307 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
2318 static int message_parse_fields(sd_bus_message *m) {
2324 for (ri = 0; ri < BUS_MESSAGE_FIELDS_SIZE(m); ) {
2325 const char *signature;
2328 r = message_peek_fields(m, &ri, 8, 1, (void**) &header);
2332 r = message_peek_field_signature(m, &ri, &signature);
2337 case _SD_BUS_MESSAGE_HEADER_INVALID:
2340 case SD_BUS_MESSAGE_HEADER_PATH:
2341 if (!streq(signature, "o"))
2344 r = message_peek_field_string(m, &ri, &m->path);
2347 case SD_BUS_MESSAGE_HEADER_INTERFACE:
2348 if (!streq(signature, "s"))
2351 r = message_peek_field_string(m, &ri, &m->interface);
2354 case SD_BUS_MESSAGE_HEADER_MEMBER:
2355 if (!streq(signature, "s"))
2358 r = message_peek_field_string(m, &ri, &m->member);
2361 case SD_BUS_MESSAGE_HEADER_ERROR_NAME:
2362 if (!streq(signature, "s"))
2365 r = message_peek_field_string(m, &ri, &m->error.name);
2368 case SD_BUS_MESSAGE_HEADER_DESTINATION:
2369 if (!streq(signature, "s"))
2372 r = message_peek_field_string(m, &ri, &m->destination);
2375 case SD_BUS_MESSAGE_HEADER_SENDER:
2376 if (!streq(signature, "s"))
2379 r = message_peek_field_string(m, &ri, &m->sender);
2383 case SD_BUS_MESSAGE_HEADER_SIGNATURE: {
2387 if (!streq(signature, "g"))
2390 r = message_peek_field_signature(m, &ri, &s);
2398 free(m->root_container.signature);
2399 m->root_container.signature = c;
2405 case SD_BUS_MESSAGE_HEADER_REPLY_SERIAL:
2406 if (!streq(signature, "u"))
2409 r = message_peek_field_uint32(m, &ri, &m->reply_serial);
2413 r = message_skip_fields(m, &ri, (uint32_t) -1, (const char **) &signature);
2420 if (isempty(m->root_container.signature) != (BUS_MESSAGE_BODY_SIZE(m) == 0))
2423 switch (m->header->type) {
2425 case SD_BUS_MESSAGE_TYPE_SIGNAL:
2426 if (!m->path || !m->interface || !m->member)
2430 case SD_BUS_MESSAGE_TYPE_METHOD_CALL:
2432 if (!m->path || !m->member)
2437 case SD_BUS_MESSAGE_TYPE_METHOD_RETURN:
2439 if (m->reply_serial == 0)
2443 case SD_BUS_MESSAGE_TYPE_METHOD_ERROR:
2445 if (m->reply_serial == 0 || !m->error.name)
2450 /* Try to read the error message, but if we can't it's a non-issue */
2451 if (m->header->type == SD_BUS_MESSAGE_TYPE_METHOD_ERROR)
2452 sd_bus_message_read(m, "s", &m->error.message);
2457 static void setup_iovec(sd_bus_message *m) {
2464 m->iovec[m->n_iovec].iov_base = m->header;
2465 m->iovec[m->n_iovec].iov_len = sizeof(*m->header);
2466 m->size += m->iovec[m->n_iovec].iov_len;
2470 m->iovec[m->n_iovec].iov_base = m->fields;
2471 m->iovec[m->n_iovec].iov_len = m->header->fields_size;
2472 m->size += m->iovec[m->n_iovec].iov_len;
2475 if (m->header->fields_size % 8 != 0) {
2476 static const uint8_t padding[7] = { 0, 0, 0, 0, 0, 0, 0 };
2478 m->iovec[m->n_iovec].iov_base = (void*) padding;
2479 m->iovec[m->n_iovec].iov_len = 8 - m->header->fields_size % 8;
2480 m->size += m->iovec[m->n_iovec].iov_len;
2486 m->iovec[m->n_iovec].iov_base = m->body;
2487 m->iovec[m->n_iovec].iov_len = m->header->body_size;
2488 m->size += m->iovec[m->n_iovec].iov_len;
2493 int bus_message_seal(sd_bus_message *m, uint64_t serial) {
2501 if (m->n_containers > 0)
2504 /* If there's a non-trivial signature set, then add it in here */
2505 if (!isempty(m->root_container.signature)) {
2506 r = message_append_field_signature(m, SD_BUS_MESSAGE_HEADER_SIGNATURE, m->root_container.signature, NULL);
2512 r = message_append_field_uint32(m, SD_BUS_MESSAGE_HEADER_UNIX_FDS, m->n_fds);
2517 m->header->serial = serial;
2525 int sd_bus_message_set_destination(sd_bus_message *m, const char *destination) {
2535 return message_append_field_string(m, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &m->destination);
2538 int bus_message_dump(sd_bus_message *m) {
2544 printf("Message %p\n"
2551 "\tfields_size=%u\n"
2556 "\tdestination=%s\n"
2559 "\treply_serial=%u\n"
2561 "\terror.message=%s\n"
2569 BUS_MESSAGE_SERIAL(m),
2570 BUS_MESSAGE_FIELDS_SIZE(m),
2571 BUS_MESSAGE_BODY_SIZE(m),
2573 strna(m->interface),
2575 strna(m->destination),
2577 strna(m->root_container.signature),
2579 strna(m->error.name),
2580 strna(m->error.message),
2583 r = sd_bus_message_rewind(m, true);
2585 log_error("Failed to rewind: %s", strerror(-r));
2589 printf("BEGIN_MESSAGE \"%s\" {\n", strempty(m->root_container.signature));
2592 _cleanup_free_ char *prefix = NULL;
2593 const char *contents = NULL;
2608 r = sd_bus_message_peek_type(m, &type, &contents);
2610 log_error("Failed to peek type: %s", strerror(-r));
2617 r = sd_bus_message_exit_container(m);
2619 log_error("Failed to exit container: %s", strerror(-r));
2625 prefix = strrep("\t", level);
2629 if (type == SD_BUS_TYPE_ARRAY)
2630 printf("%s} END_ARRAY \n", prefix);
2631 else if (type == SD_BUS_TYPE_VARIANT)
2632 printf("%s} END_VARIANT\n", prefix);
2633 else if (type == SD_BUS_TYPE_STRUCT)
2634 printf("%s} END_STRUCT\n", prefix);
2635 else if (type == SD_BUS_TYPE_DICT_ENTRY)
2636 printf("%s} END_DICT_ENTRY\n", prefix);
2641 prefix = strrep("\t", level);
2645 if (bus_type_is_container(type) > 0) {
2646 r = sd_bus_message_enter_container(m, type, contents);
2648 log_error("Failed to enter container: %s", strerror(-r));
2652 if (type == SD_BUS_TYPE_ARRAY)
2653 printf("%sBEGIN_ARRAY \"%s\" {\n", prefix, contents);
2654 else if (type == SD_BUS_TYPE_VARIANT)
2655 printf("%sBEGIN_VARIANT \"%s\" {\n", prefix, contents);
2656 else if (type == SD_BUS_TYPE_STRUCT)
2657 printf("%sBEGIN_STRUCT \"%s\" {\n", prefix, contents);
2658 else if (type == SD_BUS_TYPE_DICT_ENTRY)
2659 printf("%sBEGIN_DICT_ENTRY \"%s\" {\n", prefix, contents);
2666 r = sd_bus_message_read_basic(m, type, &basic);
2668 log_error("Failed to get basic: %s", strerror(-r));
2674 case SD_BUS_TYPE_BYTE:
2675 printf("%sBYTE: %u\n", prefix, basic.u8);
2678 case SD_BUS_TYPE_BOOLEAN:
2679 printf("%sBOOLEAN: %s\n", prefix, yes_no(basic.i));
2682 case SD_BUS_TYPE_INT16:
2683 printf("%sINT16: %i\n", prefix, basic.s16);
2686 case SD_BUS_TYPE_UINT16:
2687 printf("%sUINT16: %u\n", prefix, basic.u16);
2690 case SD_BUS_TYPE_INT32:
2691 printf("%sINT32: %i\n", prefix, basic.s32);
2694 case SD_BUS_TYPE_UINT32:
2695 printf("%sUINT32: %u\n", prefix, basic.u32);
2698 case SD_BUS_TYPE_INT64:
2699 printf("%sINT64: %lli\n", prefix, (long long) basic.s64);
2702 case SD_BUS_TYPE_UINT64:
2703 printf("%sUINT64: %llu\n", prefix, (unsigned long long) basic.u64);
2706 case SD_BUS_TYPE_DOUBLE:
2707 printf("%sDOUBLE: %g\n", prefix, basic.d64);
2710 case SD_BUS_TYPE_STRING:
2711 printf("%sSTRING: \"%s\"\n", prefix, basic.string);
2714 case SD_BUS_TYPE_OBJECT_PATH:
2715 printf("%sOBJECT_PATH: \"%s\"\n", prefix, basic.string);
2718 case SD_BUS_TYPE_SIGNATURE:
2719 printf("%sSIGNATURE: \"%s\"\n", prefix, basic.string);
2722 case SD_BUS_TYPE_UNIX_FD:
2723 printf("%sUNIX_FD: %i\n", prefix, basic.i);
2727 assert_not_reached("Unknown basic type.");
2731 printf("} END_MESSAGE\n");
2735 int bus_message_get_blob(sd_bus_message *m, void **buffer, size_t *sz) {
2744 for (i = 0, total = 0; i < m->n_iovec; i++)
2745 total += m->iovec[i].iov_len;
2751 for (i = 0, e = p; i < m->n_iovec; i++)
2752 e = mempcpy(e, m->iovec[i].iov_base, m->iovec[i].iov_len);
2760 int bus_message_read_strv_extend(sd_bus_message *m, char ***l) {
2766 r = sd_bus_message_enter_container(m, 'a', "s");
2773 r = sd_bus_message_read_basic(m, 's', &s);
2779 r = strv_extend(l, s);
2784 r = sd_bus_message_exit_container(m);