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:
772 sz = 4 + strlen(p) + 1;
775 case SD_BUS_TYPE_SIGNATURE:
777 sz = 1 + strlen(p) + 1;
780 case SD_BUS_TYPE_BOOLEAN:
783 assert_cc(sizeof(int) == sizeof(uint32_t));
790 align = bus_type_get_alignment(type);
791 sz = bus_type_get_size(type);
798 a = message_extend_body(m, align, sz);
800 /* Truncate extended signature again */
802 c->signature[c->index] = 0;
807 if (type == SD_BUS_TYPE_STRING || type == SD_BUS_TYPE_OBJECT_PATH) {
808 *(uint32_t*) a = sz - 5;
809 memcpy((uint8_t*) a + 4, p, sz - 4);
812 *stored = (const uint8_t*) a + 4;
814 } else if (type == SD_BUS_TYPE_SIGNATURE) {
815 *(uint8_t*) a = sz - 1;
816 memcpy((uint8_t*) a + 1, p, sz - 1);
819 *stored = (const uint8_t*) a + 1;
828 if (c->enclosing != SD_BUS_TYPE_ARRAY)
834 int sd_bus_message_append_basic(sd_bus_message *m, char type, const void *p) {
835 return message_append_basic(m, type, p, NULL);
838 static int bus_message_open_array(
840 struct bus_container *c,
841 const char *contents,
842 uint32_t **array_size) {
855 if (!signature_is_single(contents))
858 alignment = bus_type_get_alignment(contents[0]);
862 if (c->signature && c->signature[c->index]) {
864 /* Verify the existing signature */
866 if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
869 if (!startswith(c->signature + c->index + 1, contents))
872 nindex = c->index + 1 + strlen(contents);
874 if (c->enclosing != 0)
877 /* Extend the existing signature */
879 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_ARRAY), contents, NULL);
883 nindex = e - c->signature;
886 saved = m->header->body_size;
887 a = message_extend_body(m, 4, 4);
889 /* Truncate extended signature again */
891 c->signature[c->index] = 0;
897 if (!message_extend_body(m, alignment, 0)) {
898 /* Add alignment between size and first element */
900 c->signature[c->index] = 0;
902 m->header->body_size = saved;
906 if (c->enclosing != SD_BUS_TYPE_ARRAY)
909 /* m->body might have changed so let's readjust a */
910 a = (uint8_t*) m->body + ((uint8_t*) a - (uint8_t*) b);
917 static int bus_message_open_variant(
919 struct bus_container *c,
920 const char *contents) {
930 if (!signature_is_single(contents))
933 if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
936 if (c->signature && c->signature[c->index]) {
938 if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
942 if (c->enclosing != 0)
945 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_VARIANT), NULL);
950 l = strlen(contents);
951 a = message_extend_body(m, 1, 1 + l + 1);
953 /* Truncate extended signature again */
955 c->signature[c->index] = 0;
961 memcpy((uint8_t*) a + 1, contents, l + 1);
963 if (c->enclosing != SD_BUS_TYPE_ARRAY)
969 static int bus_message_open_struct(
971 struct bus_container *c,
972 const char *contents) {
981 if (!signature_is_valid(contents, false))
984 if (c->signature && c->signature[c->index]) {
987 l = strlen(contents);
989 if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
990 !startswith(c->signature + c->index + 1, contents) ||
991 c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
994 nindex = c->index + 1 + l + 1;
996 if (c->enclosing != 0)
999 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_BEGIN), contents, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_END), NULL);
1003 nindex = e - c->signature;
1006 /* Align contents to 8 byte boundary */
1007 if (!message_extend_body(m, 8, 0)) {
1009 c->signature[c->index] = 0;
1014 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1020 static int bus_message_open_dict_entry(
1022 struct bus_container *c,
1023 const char *contents) {
1031 if (!signature_is_pair(contents))
1034 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1037 if (c->signature && c->signature[c->index]) {
1040 l = strlen(contents);
1042 if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
1043 !startswith(c->signature + c->index + 1, contents) ||
1044 c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
1047 nindex = c->index + 1 + l + 1;
1051 /* Align contents to 8 byte boundary */
1052 if (!message_extend_body(m, 8, 0))
1055 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1061 int sd_bus_message_open_container(
1064 const char *contents) {
1066 struct bus_container *c, *w;
1067 uint32_t *array_size = NULL;
1078 /* Make sure we have space for one more container */
1079 w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
1084 c = message_get_container(m);
1086 signature = strdup(contents);
1090 if (type == SD_BUS_TYPE_ARRAY)
1091 r = bus_message_open_array(m, c, contents, &array_size);
1092 else if (type == SD_BUS_TYPE_VARIANT)
1093 r = bus_message_open_variant(m, c, contents);
1094 else if (type == SD_BUS_TYPE_STRUCT)
1095 r = bus_message_open_struct(m, c, contents);
1096 else if (type == SD_BUS_TYPE_DICT_ENTRY)
1097 r = bus_message_open_dict_entry(m, c, contents);
1106 /* OK, let's fill it in */
1107 w += m->n_containers++;
1108 w->enclosing = type;
1109 w->signature = signature;
1111 w->array_size = array_size;
1117 int sd_bus_message_close_container(sd_bus_message *m) {
1118 struct bus_container *c;
1124 if (m->n_containers <= 0)
1127 c = message_get_container(m);
1128 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1129 if (c->signature && c->signature[c->index] != 0)
1138 static int message_append_ap(
1149 for (t = types; *t; t++) {
1152 case SD_BUS_TYPE_BYTE: {
1155 x = (uint8_t) va_arg(ap, int);
1156 r = sd_bus_message_append_basic(m, *t, &x);
1160 case SD_BUS_TYPE_BOOLEAN:
1161 case SD_BUS_TYPE_INT32:
1162 case SD_BUS_TYPE_UINT32:
1163 case SD_BUS_TYPE_UNIX_FD: {
1166 /* We assume a boolean is the same as int32_t */
1167 assert_cc(sizeof(int32_t) == sizeof(int));
1169 x = va_arg(ap, uint32_t);
1170 r = sd_bus_message_append_basic(m, *t, &x);
1174 case SD_BUS_TYPE_INT16:
1175 case SD_BUS_TYPE_UINT16: {
1178 x = (uint16_t) va_arg(ap, int);
1179 r = sd_bus_message_append_basic(m, *t, &x);
1183 case SD_BUS_TYPE_INT64:
1184 case SD_BUS_TYPE_UINT64:
1185 case SD_BUS_TYPE_DOUBLE: {
1188 x = va_arg(ap, uint64_t);
1189 r = sd_bus_message_append_basic(m, *t, &x);
1193 case SD_BUS_TYPE_STRING:
1194 case SD_BUS_TYPE_OBJECT_PATH:
1195 case SD_BUS_TYPE_SIGNATURE: {
1198 x = va_arg(ap, const char*);
1199 r = sd_bus_message_append_basic(m, *t, x);
1203 case SD_BUS_TYPE_ARRAY: {
1206 r = signature_element_length(t + 1, &k);
1214 memcpy(s, t + 1, k);
1218 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, s);
1222 n = va_arg(ap, unsigned);
1223 for (i = 0; i < n; i++) {
1224 r = message_append_ap(m, s, ap);
1229 r = sd_bus_message_close_container(m);
1235 case SD_BUS_TYPE_VARIANT: {
1238 s = va_arg(ap, const char*);
1242 r = sd_bus_message_open_container(m, SD_BUS_TYPE_VARIANT, s);
1246 r = message_append_ap(m, s, ap);
1250 r = sd_bus_message_close_container(m);
1254 case SD_BUS_TYPE_STRUCT_BEGIN:
1255 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
1258 r = signature_element_length(t, &k);
1265 memcpy(s, t + 1, k - 2);
1268 r = sd_bus_message_open_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
1274 r = message_append_ap(m, s, ap);
1278 r = sd_bus_message_close_container(m);
1295 int sd_bus_message_append(sd_bus_message *m, const char *types, ...) {
1306 va_start(ap, types);
1307 r = message_append_ap(m, types, ap);
1313 static int buffer_peek(const void *p, uint32_t sz, size_t *rindex, size_t align, size_t nbytes, void **r) {
1319 start = ALIGN_TO((size_t) *rindex, align);
1325 /* Verify that padding is 0 */
1326 for (k = *rindex; k < start; k++)
1327 if (((const uint8_t*) p)[k] != 0)
1331 *r = (uint8_t*) p + start;
1338 static bool message_end_of_array(sd_bus_message *m, size_t index) {
1339 struct bus_container *c;
1343 c = message_get_container(m);
1347 return index >= c->begin + BUS_MESSAGE_BSWAP32(m, *c->array_size);
1350 static int message_peek_body(sd_bus_message *m, size_t *rindex, size_t align, size_t nbytes, void **ret) {
1355 if (message_end_of_array(m, *rindex))
1358 return buffer_peek(m->body, BUS_MESSAGE_BODY_SIZE(m), rindex, align, nbytes, ret);
1361 static bool validate_string(const char *s, size_t l) {
1364 /* Check for NUL chars in the string */
1365 if (memchr(s, 0, l))
1368 /* Check for NUL termination */
1372 /* Check if valid UTF8 */
1373 if (!utf8_is_valid(s))
1379 static bool validate_signature(const char *s, size_t l) {
1380 /* Check for NUL chars in the signature */
1381 if (memchr(s, 0, l))
1384 /* Check for NUL termination */
1388 /* Check if valid signature */
1389 if (!signature_is_valid(s, true))
1395 int sd_bus_message_read_basic(sd_bus_message *m, char type, void *p) {
1396 struct bus_container *c;
1404 if (!bus_type_is_basic(type))
1407 c = message_get_container(m);
1409 if (!c->signature || c->signature[c->index] == 0)
1412 if (c->signature[c->index] != type)
1417 case SD_BUS_TYPE_STRING:
1418 case SD_BUS_TYPE_OBJECT_PATH: {
1423 r = message_peek_body(m, &rindex, 4, 4, &q);
1427 l = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
1428 r = message_peek_body(m, &rindex, 1, l+1, &q);
1434 if (!validate_string(q, l))
1438 *(const char**) p = q;
1442 case SD_BUS_TYPE_SIGNATURE: {
1447 r = message_peek_body(m, &rindex, 1, 1, &q);
1452 r = message_peek_body(m, &rindex, 1, l+1, &q);
1458 if (!validate_signature(q, l))
1462 *(const char**) p = q;
1469 align = bus_type_get_alignment(type);
1470 sz = bus_type_get_size(type);
1472 r = message_peek_body(m, &m->rindex, align, sz, &q);
1478 case SD_BUS_TYPE_BYTE:
1479 *(uint8_t*) p = *(uint8_t*) q;
1482 case SD_BUS_TYPE_BOOLEAN:
1483 *(int*) p = !!*(uint32_t*) q;
1486 case SD_BUS_TYPE_INT16:
1487 case SD_BUS_TYPE_UINT16:
1488 *(uint16_t*) p = BUS_MESSAGE_BSWAP16(m, *(uint16_t*) q);
1491 case SD_BUS_TYPE_INT32:
1492 case SD_BUS_TYPE_UINT32:
1493 *(uint32_t*) p = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
1496 case SD_BUS_TYPE_INT64:
1497 case SD_BUS_TYPE_UINT64:
1498 case SD_BUS_TYPE_DOUBLE:
1499 *(uint64_t*) p = BUS_MESSAGE_BSWAP64(m, *(uint64_t*) q);
1503 assert_not_reached("Unknown basic type...");
1510 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1516 static int bus_message_enter_array(
1518 struct bus_container *c,
1519 const char *contents,
1520 uint32_t **array_size) {
1531 if (!signature_is_single(contents))
1534 alignment = bus_type_get_alignment(contents[0]);
1538 if (!c->signature || c->signature[c->index] == 0)
1541 if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
1544 if (!startswith(c->signature + c->index + 1, contents))
1548 r = message_peek_body(m, &rindex, 4, 4, &q);
1552 if (BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q) > 67108864)
1555 r = message_peek_body(m, &rindex, alignment, 0, NULL);
1561 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1562 c->index += 1 + strlen(contents);
1566 *array_size = (uint32_t*) q;
1571 static int bus_message_enter_variant(
1573 struct bus_container *c,
1574 const char *contents) {
1585 if (!signature_is_single(contents))
1588 if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
1591 if (!c->signature || c->signature[c->index] == 0)
1594 if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
1598 r = message_peek_body(m, &rindex, 1, 1, &q);
1603 r = message_peek_body(m, &rindex, 1, l+1, &q);
1609 if (!validate_signature(q, l))
1612 if (!streq(q, contents))
1615 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1623 static int bus_message_enter_struct(
1625 struct bus_container *c,
1626 const char *contents) {
1635 if (!signature_is_valid(contents, false))
1638 if (!c->signature || c->signature[c->index] == 0)
1641 l = strlen(contents);
1643 if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
1644 !startswith(c->signature + c->index + 1, contents) ||
1645 c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
1648 r = message_peek_body(m, &m->rindex, 8, 0, NULL);
1652 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1653 c->index += 1 + l + 1;
1658 static int bus_message_enter_dict_entry(
1660 struct bus_container *c,
1661 const char *contents) {
1670 if (!signature_is_pair(contents))
1673 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1676 if (!c->signature || c->signature[c->index] == 0)
1679 l = strlen(contents);
1681 if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
1682 !startswith(c->signature + c->index + 1, contents) ||
1683 c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
1686 r = message_peek_body(m, &m->rindex, 8, 0, NULL);
1690 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1691 c->index += 1 + l + 1;
1696 int sd_bus_message_enter_container(sd_bus_message *m, char type, const char *contents) {
1697 struct bus_container *c, *w;
1698 uint32_t *array_size = NULL;
1709 w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
1714 c = message_get_container(m);
1716 if (!c->signature || c->signature[c->index] == 0)
1719 signature = strdup(contents);
1723 if (type == SD_BUS_TYPE_ARRAY)
1724 r = bus_message_enter_array(m, c, contents, &array_size);
1725 else if (type == SD_BUS_TYPE_VARIANT)
1726 r = bus_message_enter_variant(m, c, contents);
1727 else if (type == SD_BUS_TYPE_STRUCT)
1728 r = bus_message_enter_struct(m, c, contents);
1729 else if (type == SD_BUS_TYPE_DICT_ENTRY)
1730 r = bus_message_enter_dict_entry(m, c, contents);
1739 /* OK, let's fill it in */
1740 w += m->n_containers++;
1741 w->enclosing = type;
1742 w->signature = signature;
1744 w->array_size = array_size;
1745 w->begin = m->rindex;
1750 int sd_bus_message_exit_container(sd_bus_message *m) {
1751 struct bus_container *c;
1757 if (m->n_containers <= 0)
1760 c = message_get_container(m);
1761 if (c->enclosing == SD_BUS_TYPE_ARRAY) {
1764 l = BUS_MESSAGE_BSWAP32(m, *c->array_size);
1765 if (c->begin + l != m->rindex)
1769 if (c->signature && c->signature[c->index] != 0)
1779 int sd_bus_message_peek_type(sd_bus_message *m, char *type, const char **contents) {
1780 struct bus_container *c;
1788 c = message_get_container(m);
1790 if (!c->signature || c->signature[c->index] == 0)
1793 if (message_end_of_array(m, m->rindex))
1796 if (bus_type_is_basic(c->signature[c->index])) {
1800 *type = c->signature[c->index];
1804 if (c->signature[c->index] == SD_BUS_TYPE_ARRAY) {
1810 r = signature_element_length(c->signature+c->index+1, &l);
1816 sig = strndup(c->signature + c->index + 1, l);
1820 free(m->peeked_signature);
1821 m->peeked_signature = sig;
1827 *type = SD_BUS_TYPE_ARRAY;
1832 if (c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ||
1833 c->signature[c->index] == SD_BUS_TYPE_DICT_ENTRY_BEGIN) {
1839 r = signature_element_length(c->signature+c->index, &l);
1844 sig = strndup(c->signature + c->index + 1, l - 2);
1848 free(m->peeked_signature);
1849 m->peeked_signature = sig;
1855 *type = c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY;
1860 if (c->signature[c->index] == SD_BUS_TYPE_VARIANT) {
1866 r = message_peek_body(m, &rindex, 1, 1, &q);
1873 r = message_peek_body(m, &rindex, 1, l+1, &q);
1879 if (!validate_signature(q, l))
1886 *type = SD_BUS_TYPE_VARIANT;
1895 *type = c->enclosing;
1901 int sd_bus_message_rewind(sd_bus_message *m, int complete) {
1902 struct bus_container *c;
1910 reset_containers(m);
1912 m->root_container.index = 0;
1914 c = message_get_container(m);
1916 c = message_get_container(m);
1919 m->rindex = c->begin;
1922 return !isempty(c->signature);
1925 static int message_read_ap(sd_bus_message *m, const char *types, va_list ap) {
1932 for (t = types; *t; t++) {
1935 case SD_BUS_TYPE_BYTE:
1936 case SD_BUS_TYPE_BOOLEAN:
1937 case SD_BUS_TYPE_INT16:
1938 case SD_BUS_TYPE_UINT16:
1939 case SD_BUS_TYPE_INT32:
1940 case SD_BUS_TYPE_UINT32:
1941 case SD_BUS_TYPE_INT64:
1942 case SD_BUS_TYPE_UINT64:
1943 case SD_BUS_TYPE_DOUBLE:
1944 case SD_BUS_TYPE_STRING:
1945 case SD_BUS_TYPE_OBJECT_PATH:
1946 case SD_BUS_TYPE_SIGNATURE: {
1949 p = va_arg(ap, void*);
1950 r = sd_bus_message_read_basic(m, *t, p);
1954 case SD_BUS_TYPE_ARRAY: {
1957 r = signature_element_length(t + 1, &k);
1965 memcpy(s, t + 1, k);
1969 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, s);
1975 n = va_arg(ap, unsigned);
1976 for (i = 0; i < n; i++) {
1977 r = message_read_ap(m, s, ap);
1982 r = sd_bus_message_exit_container(m);
1988 case SD_BUS_TYPE_VARIANT: {
1991 s = va_arg(ap, const char *);
1995 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, s);
2001 r = message_read_ap(m, s, ap);
2007 r = sd_bus_message_exit_container(m);
2011 case SD_BUS_TYPE_STRUCT_BEGIN:
2012 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
2015 r = signature_element_length(t, &k);
2021 memcpy(s, t + 1, k - 2);
2024 r = sd_bus_message_enter_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
2032 r = message_read_ap(m, s, ap);
2038 r = sd_bus_message_exit_container(m);
2057 int sd_bus_message_read(sd_bus_message *m, const char *types, ...) {
2068 va_start(ap, types);
2069 r = message_read_ap(m, types, ap);
2075 static int message_peek_fields(
2086 return buffer_peek(m->fields, BUS_MESSAGE_FIELDS_SIZE(m), rindex, align, nbytes, ret);
2089 static int message_peek_field_string(
2101 r = message_peek_fields(m, ri, 4, 4, &q);
2105 l = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2106 r = message_peek_fields(m, ri, 1, l+1, &q);
2110 if (!validate_string(q, l))
2119 static int message_peek_field_signature(
2131 r = message_peek_fields(m, ri, 1, 1, &q);
2136 r = message_peek_fields(m, ri, 1, l+1, &q);
2140 if (!validate_signature(q, l))
2149 static int message_peek_field_uint32(
2160 r = message_peek_fields(m, ri, 4, 4, &q);
2165 *ret = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2170 static int message_skip_fields(
2173 uint32_t array_size,
2174 const char **signature) {
2176 size_t original_index;
2183 original_index = *ri;
2190 if (array_size != (uint32_t) -1 &&
2191 array_size <= *ri - original_index)
2198 if (t == SD_BUS_TYPE_STRING ||
2199 t == SD_BUS_TYPE_OBJECT_PATH) {
2201 r = message_peek_field_string(m, ri, NULL);
2207 } else if (t == SD_BUS_TYPE_SIGNATURE) {
2209 r = message_peek_field_signature(m, ri, NULL);
2215 } else if (bus_type_is_basic(t)) {
2218 align = bus_type_get_alignment(t);
2219 k = bus_type_get_size(t);
2221 r = message_peek_fields(m, ri, align, k, NULL);
2227 } else if (t == SD_BUS_TYPE_ARRAY) {
2229 r = signature_element_length(*signature+1, &l);
2239 strncpy(sig, *signature + 1, l-1);
2242 alignment = bus_type_get_alignment(sig[0]);
2246 r = message_peek_fields(m, ri, 4, 4, &q);
2250 nas = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2254 r = message_peek_fields(m, ri, alignment, 0, NULL);
2258 r = message_skip_fields(m, ri, nas, (const char**) &s);
2263 (*signature) += 1 + l;
2265 } else if (t == SD_BUS_TYPE_VARIANT) {
2268 r = message_peek_field_signature(m, ri, &s);
2272 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
2278 } else if (t == SD_BUS_TYPE_STRUCT ||
2279 t == SD_BUS_TYPE_DICT_ENTRY) {
2281 r = signature_element_length(*signature, &l);
2288 strncpy(sig, *signature + 1, l-1);
2291 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
2302 static int message_parse_fields(sd_bus_message *m) {
2308 for (ri = 0; ri < BUS_MESSAGE_FIELDS_SIZE(m); ) {
2309 const char *signature;
2312 r = message_peek_fields(m, &ri, 8, 1, (void**) &header);
2316 r = message_peek_field_signature(m, &ri, &signature);
2321 case _SD_BUS_MESSAGE_HEADER_INVALID:
2324 case SD_BUS_MESSAGE_HEADER_PATH:
2325 if (!streq(signature, "o"))
2328 r = message_peek_field_string(m, &ri, &m->path);
2331 case SD_BUS_MESSAGE_HEADER_INTERFACE:
2332 if (!streq(signature, "s"))
2335 r = message_peek_field_string(m, &ri, &m->interface);
2338 case SD_BUS_MESSAGE_HEADER_MEMBER:
2339 if (!streq(signature, "s"))
2342 r = message_peek_field_string(m, &ri, &m->member);
2345 case SD_BUS_MESSAGE_HEADER_ERROR_NAME:
2346 if (!streq(signature, "s"))
2349 r = message_peek_field_string(m, &ri, &m->error.name);
2352 case SD_BUS_MESSAGE_HEADER_DESTINATION:
2353 if (!streq(signature, "s"))
2356 r = message_peek_field_string(m, &ri, &m->destination);
2359 case SD_BUS_MESSAGE_HEADER_SENDER:
2360 if (!streq(signature, "s"))
2363 r = message_peek_field_string(m, &ri, &m->sender);
2367 case SD_BUS_MESSAGE_HEADER_SIGNATURE: {
2371 if (!streq(signature, "g"))
2374 r = message_peek_field_signature(m, &ri, &s);
2382 free(m->root_container.signature);
2383 m->root_container.signature = c;
2389 case SD_BUS_MESSAGE_HEADER_REPLY_SERIAL:
2390 if (!streq(signature, "u"))
2393 r = message_peek_field_uint32(m, &ri, &m->reply_serial);
2397 r = message_skip_fields(m, &ri, (uint32_t) -1, (const char **) &signature);
2404 if (isempty(m->root_container.signature) != (BUS_MESSAGE_BODY_SIZE(m) == 0))
2407 switch (m->header->type) {
2409 case SD_BUS_MESSAGE_TYPE_SIGNAL:
2410 if (!m->path || !m->interface || !m->member)
2414 case SD_BUS_MESSAGE_TYPE_METHOD_CALL:
2416 if (!m->path || !m->member)
2421 case SD_BUS_MESSAGE_TYPE_METHOD_RETURN:
2423 if (m->reply_serial == 0)
2427 case SD_BUS_MESSAGE_TYPE_METHOD_ERROR:
2429 if (m->reply_serial == 0 || !m->error.name)
2434 /* Try to read the error message, but if we can't it's a non-issue */
2435 if (m->header->type == SD_BUS_MESSAGE_TYPE_METHOD_ERROR)
2436 sd_bus_message_read(m, "s", &m->error.message);
2441 static void setup_iovec(sd_bus_message *m) {
2448 m->iovec[m->n_iovec].iov_base = m->header;
2449 m->iovec[m->n_iovec].iov_len = sizeof(*m->header);
2450 m->size += m->iovec[m->n_iovec].iov_len;
2454 m->iovec[m->n_iovec].iov_base = m->fields;
2455 m->iovec[m->n_iovec].iov_len = m->header->fields_size;
2456 m->size += m->iovec[m->n_iovec].iov_len;
2459 if (m->header->fields_size % 8 != 0) {
2460 static const uint8_t padding[7] = { 0, 0, 0, 0, 0, 0, 0 };
2462 m->iovec[m->n_iovec].iov_base = (void*) padding;
2463 m->iovec[m->n_iovec].iov_len = 8 - m->header->fields_size % 8;
2464 m->size += m->iovec[m->n_iovec].iov_len;
2470 m->iovec[m->n_iovec].iov_base = m->body;
2471 m->iovec[m->n_iovec].iov_len = m->header->body_size;
2472 m->size += m->iovec[m->n_iovec].iov_len;
2477 int bus_message_seal(sd_bus_message *m, uint64_t serial) {
2485 if (m->n_containers > 0)
2488 /* If there's a non-trivial signature set, then add it in here */
2489 if (!isempty(m->root_container.signature)) {
2490 r = message_append_field_signature(m, SD_BUS_MESSAGE_HEADER_SIGNATURE, m->root_container.signature, NULL);
2496 r = message_append_field_uint32(m, SD_BUS_MESSAGE_HEADER_UNIX_FDS, m->n_fds);
2501 m->header->serial = serial;
2509 int sd_bus_message_set_destination(sd_bus_message *m, const char *destination) {
2519 return message_append_field_string(m, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &m->destination);
2522 int bus_message_dump(sd_bus_message *m) {
2528 printf("Message %p\n"
2535 "\tfields_size=%u\n"
2540 "\tdestination=%s\n"
2543 "\treply_serial=%u\n"
2545 "\terror.message=%s\n"
2553 BUS_MESSAGE_SERIAL(m),
2554 BUS_MESSAGE_FIELDS_SIZE(m),
2555 BUS_MESSAGE_BODY_SIZE(m),
2557 strna(m->interface),
2559 strna(m->destination),
2561 strna(m->root_container.signature),
2563 strna(m->error.name),
2564 strna(m->error.message),
2567 r = sd_bus_message_rewind(m, true);
2569 log_error("Failed to rewind: %s", strerror(-r));
2573 printf("BEGIN_MESSAGE \"%s\" {\n", strempty(m->root_container.signature));
2576 _cleanup_free_ char *prefix = NULL;
2577 const char *contents = NULL;
2592 r = sd_bus_message_peek_type(m, &type, &contents);
2594 log_error("Failed to peek type: %s", strerror(-r));
2601 r = sd_bus_message_exit_container(m);
2603 log_error("Failed to exit container: %s", strerror(-r));
2609 prefix = strrep("\t", level);
2613 if (type == SD_BUS_TYPE_ARRAY)
2614 printf("%s} END_ARRAY \n", prefix);
2615 else if (type == SD_BUS_TYPE_VARIANT)
2616 printf("%s} END_VARIANT\n", prefix);
2617 else if (type == SD_BUS_TYPE_STRUCT)
2618 printf("%s} END_STRUCT\n", prefix);
2619 else if (type == SD_BUS_TYPE_DICT_ENTRY)
2620 printf("%s} END_DICT_ENTRY\n", prefix);
2625 prefix = strrep("\t", level);
2629 if (bus_type_is_container(type) > 0) {
2630 r = sd_bus_message_enter_container(m, type, contents);
2632 log_error("Failed to enter container: %s", strerror(-r));
2636 if (type == SD_BUS_TYPE_ARRAY)
2637 printf("%sBEGIN_ARRAY \"%s\" {\n", prefix, contents);
2638 else if (type == SD_BUS_TYPE_VARIANT)
2639 printf("%sBEGIN_VARIANT \"%s\" {\n", prefix, contents);
2640 else if (type == SD_BUS_TYPE_STRUCT)
2641 printf("%sBEGIN_STRUCT \"%s\" {\n", prefix, contents);
2642 else if (type == SD_BUS_TYPE_DICT_ENTRY)
2643 printf("%sBEGIN_DICT_ENTRY \"%s\" {\n", prefix, contents);
2650 r = sd_bus_message_read_basic(m, type, &basic);
2652 log_error("Failed to get basic: %s", strerror(-r));
2658 case SD_BUS_TYPE_BYTE:
2659 printf("%sBYTE: %u\n", prefix, basic.u8);
2662 case SD_BUS_TYPE_BOOLEAN:
2663 printf("%sBOOLEAN: %s\n", prefix, yes_no(basic.i));
2666 case SD_BUS_TYPE_INT16:
2667 printf("%sINT16: %i\n", prefix, basic.s16);
2670 case SD_BUS_TYPE_UINT16:
2671 printf("%sUINT16: %u\n", prefix, basic.u16);
2674 case SD_BUS_TYPE_INT32:
2675 printf("%sINT32: %i\n", prefix, basic.s32);
2678 case SD_BUS_TYPE_UINT32:
2679 printf("%sUINT32: %u\n", prefix, basic.u32);
2682 case SD_BUS_TYPE_INT64:
2683 printf("%sINT64: %lli\n", prefix, (long long) basic.s64);
2686 case SD_BUS_TYPE_UINT64:
2687 printf("%sUINT64: %llu\n", prefix, (unsigned long long) basic.u64);
2690 case SD_BUS_TYPE_DOUBLE:
2691 printf("%sDOUBLE: %g\n", prefix, basic.d64);
2694 case SD_BUS_TYPE_STRING:
2695 printf("%sSTRING: \"%s\"\n", prefix, basic.string);
2698 case SD_BUS_TYPE_OBJECT_PATH:
2699 printf("%sOBJECT_PATH: \"%s\"\n", prefix, basic.string);
2702 case SD_BUS_TYPE_SIGNATURE:
2703 printf("%sSIGNATURE: \"%s\"\n", prefix, basic.string);
2706 case SD_BUS_TYPE_UNIX_FD:
2707 printf("%sUNIX_FD: %i\n", prefix, basic.i);
2711 assert_not_reached("Unknown basic type.");
2715 printf("} END_MESSAGE\n");
2719 int bus_message_get_blob(sd_bus_message *m, void **buffer, size_t *sz) {
2728 for (i = 0, total = 0; i < m->n_iovec; i++)
2729 total += m->iovec[i].iov_len;
2735 for (i = 0, e = p; i < m->n_iovec; i++)
2736 e = mempcpy(e, m->iovec[i].iov_base, m->iovec[i].iov_len);
2744 int bus_message_read_strv_extend(sd_bus_message *m, char ***l) {
2750 r = sd_bus_message_enter_container(m, 'a', "s");
2757 r = sd_bus_message_read_basic(m, 's', &s);
2763 r = strv_extend(l, s);
2768 r = sd_bus_message_exit_container(m);