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/>.
28 #include "bus-message.h"
29 #include "bus-internal.h"
31 #include "bus-signature.h"
33 static int message_parse_fields(sd_bus_message *m);
34 static int message_append_basic(sd_bus_message *m, char type, const void *p, const void **stored);
36 static void reset_containers(sd_bus_message *m) {
41 for (i = 0; i < m->n_containers; i++)
42 free(m->containers[i].signature);
48 m->root_container.index = 0;
51 static void message_free(sd_bus_message *m) {
65 for (i = 0; i < m->n_fds; i++)
66 close_nointr_nofail(m->fds[i]);
69 free(m->root_container.signature);
71 free(m->peeked_signature);
75 static void* buffer_extend(void **p, uint32_t *sz, size_t align, size_t extend) {
83 start = ALIGN_TO((size_t) *sz, align);
87 return (uint8_t*) *p + start;
89 if (n > (size_t) ((uint32_t) -1))
96 /* Zero out padding */
98 memset((uint8_t*) k + *sz, 0, start - *sz);
103 return (uint8_t*) k + start;
106 static void *message_extend_fields(sd_bus_message *m, size_t align, size_t sz) {
112 p = buffer_extend(&m->fields, &m->header->fields_size, align, sz);
116 if (o != m->fields) {
117 /* Adjust quick access pointers */
120 m->path = (const char*) m->fields + (m->path - (const char*) o);
122 m->interface = (const char*) m->fields + (m->interface - (const char*) o);
124 m->member = (const char*) m->fields + (m->member - (const char*) o);
126 m->destination = (const char*) m->fields + (m->destination - (const char*) o);
128 m->sender = (const char*) m->fields + (m->sender - (const char*) o);
130 m->error.name = (const char*) m->fields + (m->error.name - (const char*) o);
133 m->free_fields = true;
138 static int message_append_field_string(
151 if (l > (size_t) (uint32_t) -1)
154 /* field id byte + signature length + signature 's' + NUL + string length + string + NUL */
155 p = message_extend_fields(m, 8, 4 + 4 + l + 1);
164 ((uint32_t*) p)[1] = l;
165 memcpy(p + 8, s, l + 1);
168 *ret = (const char*) p + 8;
173 static int message_append_field_signature(
188 /* field id byte + signature length + signature 'g' + NUL + string length + string + NUL */
189 p = message_extend_fields(m, 8, 4 + 1 + l + 1);
195 p[2] = SD_BUS_TYPE_SIGNATURE;
198 memcpy(p + 5, s, l + 1);
201 *ret = (const char*) p + 5;
206 static int message_append_field_uint32(sd_bus_message *m, uint8_t h, uint32_t x) {
211 /* field id byte + signature length + signature 'u' + NUL + value */
212 p = message_extend_fields(m, 8, 4 + 4);
218 p[2] = SD_BUS_TYPE_UINT32;
221 ((uint32_t*) p)[1] = x;
226 int bus_message_from_malloc(void *buffer, size_t length, sd_bus_message **ret) {
228 struct bus_header *h;
229 size_t total, fs, bs;
232 assert(buffer || length <= 0);
235 if (length < sizeof(struct bus_header))
245 if (h->type == _SD_BUS_MESSAGE_TYPE_INVALID)
248 if (h->endian == SD_BUS_NATIVE_ENDIAN) {
251 } else if (h->endian == SD_BUS_REVERSE_ENDIAN) {
252 fs = bswap_32(h->fields_size);
253 bs = bswap_32(h->body_size);
257 total = sizeof(struct bus_header) + ALIGN_TO(fs, 8) + bs;
261 m = new0(sd_bus_message, 1);
267 m->free_header = true;
268 m->fields = (uint8_t*) buffer + sizeof(struct bus_header);
269 m->body = (uint8_t*) buffer + sizeof(struct bus_header) + ALIGN_TO(fs, 8);
273 m->iovec[0].iov_base = buffer;
274 m->iovec[0].iov_len = length;
276 r = message_parse_fields(m);
286 static sd_bus_message *message_new(sd_bus *bus, uint8_t type) {
289 m = malloc0(ALIGN(sizeof(sd_bus_message)) + sizeof(struct bus_header));
294 m->header = (struct bus_header*) ((uint8_t*) m + ALIGN(sizeof(struct sd_bus_message)));
295 m->header->endian = SD_BUS_NATIVE_ENDIAN;
296 m->header->type = type;
297 m->header->version = bus ? bus->message_version : 1;
302 int sd_bus_message_new_signal(
305 const char *interface,
307 sd_bus_message **m) {
321 t = message_new(bus, SD_BUS_MESSAGE_TYPE_SIGNAL);
325 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_PATH, SD_BUS_TYPE_OBJECT_PATH, path, &t->path);
328 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_INTERFACE, SD_BUS_TYPE_STRING, interface, &t->interface);
331 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_MEMBER, SD_BUS_TYPE_STRING, member, &t->member);
339 sd_bus_message_unref(t);
343 int sd_bus_message_new_method_call(
345 const char *destination,
347 const char *interface,
349 sd_bus_message **m) {
361 t = message_new(bus, SD_BUS_MESSAGE_TYPE_METHOD_CALL);
365 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_PATH, SD_BUS_TYPE_OBJECT_PATH, path, &t->path);
368 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_MEMBER, SD_BUS_TYPE_STRING, member, &t->member);
373 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_INTERFACE, SD_BUS_TYPE_STRING, interface, &t->interface);
379 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &t->destination);
392 static int message_new_reply(
394 sd_bus_message *call,
396 sd_bus_message **m) {
403 if (call->header->type != SD_BUS_MESSAGE_TYPE_METHOD_CALL)
408 t = message_new(bus, type);
412 t->reply_serial = BUS_MESSAGE_SERIAL(call);
414 r = message_append_field_uint32(t, SD_BUS_MESSAGE_HEADER_REPLY_SERIAL, t->reply_serial);
419 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, call->sender, &t->sender);
424 t->dont_send = !!(call->header->flags & SD_BUS_MESSAGE_NO_REPLY_EXPECTED);
433 int sd_bus_message_new_method_return(
435 sd_bus_message *call,
436 sd_bus_message **m) {
438 return message_new_reply(bus, call, SD_BUS_MESSAGE_TYPE_METHOD_RETURN, m);
441 int sd_bus_message_new_method_error(
443 sd_bus_message *call,
444 const sd_bus_error *e,
445 sd_bus_message **m) {
450 if (!sd_bus_error_is_set(e))
455 r = message_new_reply(bus, call, SD_BUS_MESSAGE_TYPE_METHOD_ERROR, &t);
459 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_ERROR_NAME, SD_BUS_TYPE_STRING, e->name, &t->error.name);
464 r = message_append_basic(t, SD_BUS_TYPE_STRING, e->message, (const void**) &t->error.message);
477 sd_bus_message* sd_bus_message_ref(sd_bus_message *m) {
481 assert(m->n_ref > 0);
487 sd_bus_message* sd_bus_message_unref(sd_bus_message *m) {
491 assert(m->n_ref > 0);
500 int sd_bus_message_get_type(sd_bus_message *m, uint8_t *type) {
506 *type = m->header->type;
510 int sd_bus_message_get_serial(sd_bus_message *m, uint64_t *serial) {
515 if (m->header->serial == 0)
518 *serial = BUS_MESSAGE_SERIAL(m);
522 int sd_bus_message_get_reply_serial(sd_bus_message *m, uint64_t *serial) {
527 if (m->reply_serial == 0)
530 *serial = m->reply_serial;
534 int sd_bus_message_get_no_reply(sd_bus_message *m) {
538 return m->header->type == SD_BUS_MESSAGE_TYPE_METHOD_CALL ? !!(m->header->flags & SD_BUS_MESSAGE_NO_REPLY_EXPECTED) : 0;
541 const char *sd_bus_message_get_path(sd_bus_message *m) {
548 const char *sd_bus_message_get_interface(sd_bus_message *m) {
555 const char *sd_bus_message_get_member(sd_bus_message *m) {
561 const char *sd_bus_message_get_destination(sd_bus_message *m) {
565 return m->destination;
568 const char *sd_bus_message_get_sender(sd_bus_message *m) {
575 const sd_bus_error *sd_bus_message_get_error(sd_bus_message *m) {
579 if (!sd_bus_error_is_set(&m->error))
585 int sd_bus_message_get_uid(sd_bus_message *m, uid_t *uid) {
595 int sd_bus_message_get_gid(sd_bus_message *m, gid_t *gid) {
605 int sd_bus_message_get_pid(sd_bus_message *m, pid_t *pid) {
615 int sd_bus_message_get_tid(sd_bus_message *m, pid_t *tid) {
625 int sd_bus_message_is_signal(sd_bus_message *m, const char *interface, const char *member) {
629 if (m->header->type != SD_BUS_MESSAGE_TYPE_SIGNAL)
632 if (interface && (!m->interface || !streq(m->interface, interface)))
635 if (member && (!m->member || !streq(m->member, member)))
641 int sd_bus_message_is_method_call(sd_bus_message *m, const char *interface, const char *member) {
645 if (m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_CALL)
648 if (interface && (!m->interface || !streq(m->interface, interface)))
651 if (member && (!m->member || !streq(m->member, member)))
657 int sd_bus_message_is_method_error(sd_bus_message *m, const char *name) {
661 if (m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_ERROR)
664 if (name && (!m->error.name || !streq(m->error.name, name)))
670 int sd_bus_message_set_no_reply(sd_bus_message *m, int b) {
675 if (m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_CALL)
679 m->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
681 m->header->flags &= ~SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
686 static struct bus_container *message_get_container(sd_bus_message *m) {
689 if (m->n_containers == 0)
690 return &m->root_container;
692 assert(m->containers);
693 return m->containers + m->n_containers - 1;
696 static void *message_extend_body(sd_bus_message *m, size_t align, size_t sz) {
699 struct bus_container *c;
705 added = m->header->body_size;
707 p = buffer_extend(&m->body, &m->header->body_size, align, sz);
711 added = m->header->body_size - added;
713 for (c = m->containers; c < m->containers + m->n_containers; c++)
715 c->array_size = (uint32_t*) ((uint8_t*) m->body + ((uint8_t*) c->array_size - (uint8_t*) o));
716 *c->array_size += added;
720 if (m->error.message)
721 m->error.message = (const char*) m->body + (m->error.message - (const char*) o);
729 int message_append_basic(sd_bus_message *m, char type, const void *p, const void **stored) {
730 struct bus_container *c;
740 if (!bus_type_is_basic(type))
743 c = message_get_container(m);
745 if (c->signature && c->signature[c->index]) {
746 /* Container signature is already set */
748 if (c->signature[c->index] != type)
751 /* Maybe we can append to the signature? But only if this is the top-level container*/
752 if (c->enclosing != 0)
755 e = strextend(&c->signature, CHAR_TO_STR(type), NULL);
762 case SD_BUS_TYPE_STRING:
763 case SD_BUS_TYPE_OBJECT_PATH:
765 sz = 4 + strlen(p) + 1;
768 case SD_BUS_TYPE_SIGNATURE:
770 sz = 1 + strlen(p) + 1;
773 case SD_BUS_TYPE_BOOLEAN:
776 assert_cc(sizeof(int) == sizeof(uint32_t));
783 align = bus_type_get_alignment(type);
784 sz = bus_type_get_size(type);
791 a = message_extend_body(m, align, sz);
793 /* Truncate extended signature again */
795 c->signature[c->index] = 0;
800 if (type == SD_BUS_TYPE_STRING || type == SD_BUS_TYPE_OBJECT_PATH) {
801 *(uint32_t*) a = sz - 5;
802 memcpy((uint8_t*) a + 4, p, sz - 4);
805 *stored = (const uint8_t*) a + 4;
807 } else if (type == SD_BUS_TYPE_SIGNATURE) {
808 *(uint8_t*) a = sz - 1;
809 memcpy((uint8_t*) a + 1, p, sz - 1);
812 *stored = (const uint8_t*) a + 1;
821 if (c->enclosing != SD_BUS_TYPE_ARRAY)
827 int sd_bus_message_append_basic(sd_bus_message *m, char type, const void *p) {
828 return message_append_basic(m, type, p, NULL);
831 static int bus_message_open_array(
833 struct bus_container *c,
834 const char *contents,
835 uint32_t **array_size) {
848 if (!signature_is_single(contents))
851 alignment = bus_type_get_alignment(contents[0]);
855 if (c->signature && c->signature[c->index]) {
857 /* Verify the existing signature */
859 if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
862 if (!startswith(c->signature + c->index + 1, contents))
865 nindex = c->index + 1 + strlen(contents);
867 if (c->enclosing != 0)
870 /* Extend the existing signature */
872 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_ARRAY), contents, NULL);
876 nindex = e - c->signature;
879 saved = m->header->body_size;
880 a = message_extend_body(m, 4, 4);
882 /* Truncate extended signature again */
884 c->signature[c->index] = 0;
890 if (!message_extend_body(m, alignment, 0)) {
891 /* Add alignment between size and first element */
893 c->signature[c->index] = 0;
895 m->header->body_size = saved;
899 if (c->enclosing != SD_BUS_TYPE_ARRAY)
902 /* m->body might have changed so let's readjust a */
903 a = (uint8_t*) m->body + ((uint8_t*) a - (uint8_t*) b);
910 static int bus_message_open_variant(
912 struct bus_container *c,
913 const char *contents) {
923 if (!signature_is_single(contents))
926 if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
929 if (c->signature && c->signature[c->index]) {
931 if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
935 if (c->enclosing != 0)
938 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_VARIANT), NULL);
943 l = strlen(contents);
944 a = message_extend_body(m, 1, 1 + l + 1);
946 /* Truncate extended signature again */
948 c->signature[c->index] = 0;
954 memcpy((uint8_t*) a + 1, contents, l + 1);
956 if (c->enclosing != SD_BUS_TYPE_ARRAY)
962 static int bus_message_open_struct(
964 struct bus_container *c,
965 const char *contents) {
974 if (!signature_is_valid(contents, false))
977 if (c->signature && c->signature[c->index]) {
980 l = strlen(contents);
982 if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
983 !startswith(c->signature + c->index + 1, contents) ||
984 c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
987 nindex = c->index + 1 + l + 1;
989 if (c->enclosing != 0)
992 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_BEGIN), contents, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_END), NULL);
996 nindex = e - c->signature;
999 /* Align contents to 8 byte boundary */
1000 if (!message_extend_body(m, 8, 0)) {
1002 c->signature[c->index] = 0;
1007 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1013 static int bus_message_open_dict_entry(
1015 struct bus_container *c,
1016 const char *contents) {
1024 if (!signature_is_pair(contents))
1027 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1030 if (c->signature && c->signature[c->index]) {
1033 l = strlen(contents);
1035 if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
1036 !startswith(c->signature + c->index + 1, contents) ||
1037 c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
1040 nindex = c->index + 1 + l + 1;
1044 /* Align contents to 8 byte boundary */
1045 if (!message_extend_body(m, 8, 0))
1048 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1054 int sd_bus_message_open_container(
1057 const char *contents) {
1059 struct bus_container *c, *w;
1060 uint32_t *array_size = NULL;
1071 /* Make sure we have space for one more container */
1072 w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
1077 c = message_get_container(m);
1079 signature = strdup(contents);
1083 if (type == SD_BUS_TYPE_ARRAY)
1084 r = bus_message_open_array(m, c, contents, &array_size);
1085 else if (type == SD_BUS_TYPE_VARIANT)
1086 r = bus_message_open_variant(m, c, contents);
1087 else if (type == SD_BUS_TYPE_STRUCT)
1088 r = bus_message_open_struct(m, c, contents);
1089 else if (type == SD_BUS_TYPE_DICT_ENTRY)
1090 r = bus_message_open_dict_entry(m, c, contents);
1099 /* OK, let's fill it in */
1100 w += m->n_containers++;
1101 w->enclosing = type;
1102 w->signature = signature;
1104 w->array_size = array_size;
1110 int sd_bus_message_close_container(sd_bus_message *m) {
1111 struct bus_container *c;
1117 if (m->n_containers <= 0)
1120 c = message_get_container(m);
1121 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1122 if (c->signature && c->signature[c->index] != 0)
1131 static int message_append_ap(
1142 for (t = types; *t; t++) {
1145 case SD_BUS_TYPE_BYTE: {
1148 x = (uint8_t) va_arg(ap, int);
1149 r = sd_bus_message_append_basic(m, *t, &x);
1153 case SD_BUS_TYPE_BOOLEAN:
1154 case SD_BUS_TYPE_INT32:
1155 case SD_BUS_TYPE_UINT32:
1156 case SD_BUS_TYPE_UNIX_FD: {
1159 /* We assume a boolean is the same as int32_t */
1160 assert_cc(sizeof(int32_t) == sizeof(int));
1162 x = va_arg(ap, uint32_t);
1163 r = sd_bus_message_append_basic(m, *t, &x);
1167 case SD_BUS_TYPE_INT16:
1168 case SD_BUS_TYPE_UINT16: {
1171 x = (uint16_t) va_arg(ap, int);
1172 r = sd_bus_message_append_basic(m, *t, &x);
1176 case SD_BUS_TYPE_INT64:
1177 case SD_BUS_TYPE_UINT64:
1178 case SD_BUS_TYPE_DOUBLE: {
1181 x = va_arg(ap, uint64_t);
1182 r = sd_bus_message_append_basic(m, *t, &x);
1186 case SD_BUS_TYPE_STRING:
1187 case SD_BUS_TYPE_OBJECT_PATH:
1188 case SD_BUS_TYPE_SIGNATURE: {
1191 x = va_arg(ap, const char*);
1192 r = sd_bus_message_append_basic(m, *t, x);
1196 case SD_BUS_TYPE_ARRAY: {
1199 r = signature_element_length(t + 1, &k);
1207 memcpy(s, t + 1, k);
1211 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, s);
1215 n = va_arg(ap, unsigned);
1216 for (i = 0; i < n; i++) {
1217 r = message_append_ap(m, s, ap);
1222 r = sd_bus_message_close_container(m);
1228 case SD_BUS_TYPE_VARIANT: {
1231 s = va_arg(ap, const char*);
1235 r = sd_bus_message_open_container(m, SD_BUS_TYPE_VARIANT, s);
1239 r = message_append_ap(m, s, ap);
1243 r = sd_bus_message_close_container(m);
1247 case SD_BUS_TYPE_STRUCT_BEGIN:
1248 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
1251 r = signature_element_length(t, &k);
1258 memcpy(s, t + 1, k - 2);
1261 r = sd_bus_message_open_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
1267 r = message_append_ap(m, s, ap);
1271 r = sd_bus_message_close_container(m);
1288 int sd_bus_message_append(sd_bus_message *m, const char *types, ...) {
1299 va_start(ap, types);
1300 r = message_append_ap(m, types, ap);
1306 static int buffer_peek(const void *p, uint32_t sz, size_t *rindex, size_t align, size_t nbytes, void **r) {
1312 start = ALIGN_TO((size_t) *rindex, align);
1318 /* Verify that padding is 0 */
1319 for (k = *rindex; k < start; k++)
1320 if (((const uint8_t*) p)[k] != 0)
1324 *r = (uint8_t*) p + start;
1331 static bool message_end_of_array(sd_bus_message *m, size_t index) {
1332 struct bus_container *c;
1336 c = message_get_container(m);
1340 return index >= c->begin + BUS_MESSAGE_BSWAP32(m, *c->array_size);
1343 static int message_peek_body(sd_bus_message *m, size_t *rindex, size_t align, size_t nbytes, void **ret) {
1348 if (message_end_of_array(m, *rindex))
1351 return buffer_peek(m->body, BUS_MESSAGE_BODY_SIZE(m), rindex, align, nbytes, ret);
1354 static bool validate_string(const char *s, size_t l) {
1357 /* Check for NUL chars in the string */
1358 if (memchr(s, 0, l))
1361 /* Check for NUL termination */
1365 /* Check if valid UTF8 */
1366 if (!utf8_is_valid(s))
1372 static bool validate_signature(const char *s, size_t l) {
1373 /* Check for NUL chars in the signature */
1374 if (memchr(s, 0, l))
1377 /* Check for NUL termination */
1381 /* Check if valid signature */
1382 if (!signature_is_valid(s, true))
1388 int sd_bus_message_read_basic(sd_bus_message *m, char type, void *p) {
1389 struct bus_container *c;
1397 if (!bus_type_is_basic(type))
1400 c = message_get_container(m);
1402 if (!c->signature || c->signature[c->index] == 0)
1405 if (c->signature[c->index] != type)
1410 case SD_BUS_TYPE_STRING:
1411 case SD_BUS_TYPE_OBJECT_PATH: {
1416 r = message_peek_body(m, &rindex, 4, 4, &q);
1420 l = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
1421 r = message_peek_body(m, &rindex, 1, l+1, &q);
1427 if (!validate_string(q, l))
1431 *(const char**) p = q;
1435 case SD_BUS_TYPE_SIGNATURE: {
1440 r = message_peek_body(m, &rindex, 1, 1, &q);
1445 r = message_peek_body(m, &rindex, 1, l+1, &q);
1451 if (!validate_signature(q, l))
1455 *(const char**) p = q;
1462 align = bus_type_get_alignment(type);
1463 sz = bus_type_get_size(type);
1465 r = message_peek_body(m, &m->rindex, align, sz, &q);
1471 case SD_BUS_TYPE_BYTE:
1472 *(uint8_t*) p = *(uint8_t*) q;
1475 case SD_BUS_TYPE_BOOLEAN:
1476 *(int*) p = !!*(uint32_t*) q;
1479 case SD_BUS_TYPE_INT16:
1480 case SD_BUS_TYPE_UINT16:
1481 *(uint16_t*) p = BUS_MESSAGE_BSWAP16(m, *(uint16_t*) q);
1484 case SD_BUS_TYPE_INT32:
1485 case SD_BUS_TYPE_UINT32:
1486 *(uint32_t*) p = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
1489 case SD_BUS_TYPE_INT64:
1490 case SD_BUS_TYPE_UINT64:
1491 case SD_BUS_TYPE_DOUBLE:
1492 *(uint64_t*) p = BUS_MESSAGE_BSWAP64(m, *(uint64_t*) q);
1496 assert_not_reached("Unknown basic type...");
1503 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1509 static int bus_message_enter_array(
1511 struct bus_container *c,
1512 const char *contents,
1513 uint32_t **array_size) {
1524 if (!signature_is_single(contents))
1527 alignment = bus_type_get_alignment(contents[0]);
1531 if (!c->signature || c->signature[c->index] == 0)
1534 if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
1537 if (!startswith(c->signature + c->index + 1, contents))
1541 r = message_peek_body(m, &rindex, 4, 4, &q);
1545 if (BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q) > 67108864)
1548 r = message_peek_body(m, &rindex, alignment, 0, NULL);
1554 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1555 c->index += 1 + strlen(contents);
1559 *array_size = (uint32_t*) q;
1564 static int bus_message_enter_variant(
1566 struct bus_container *c,
1567 const char *contents) {
1578 if (!signature_is_single(contents))
1581 if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
1584 if (!c->signature || c->signature[c->index] == 0)
1587 if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
1591 r = message_peek_body(m, &rindex, 1, 1, &q);
1596 r = message_peek_body(m, &rindex, 1, l+1, &q);
1602 if (!validate_signature(q, l))
1605 if (!streq(q, contents))
1608 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1616 static int bus_message_enter_struct(
1618 struct bus_container *c,
1619 const char *contents) {
1628 if (!signature_is_valid(contents, false))
1631 if (!c->signature || c->signature[c->index] == 0)
1634 l = strlen(contents);
1636 if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
1637 !startswith(c->signature + c->index + 1, contents) ||
1638 c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
1641 r = message_peek_body(m, &m->rindex, 8, 0, NULL);
1645 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1646 c->index += 1 + l + 1;
1651 static int bus_message_enter_dict_entry(
1653 struct bus_container *c,
1654 const char *contents) {
1663 if (!signature_is_pair(contents))
1666 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1669 if (!c->signature || c->signature[c->index] == 0)
1672 l = strlen(contents);
1674 if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
1675 !startswith(c->signature + c->index + 1, contents) ||
1676 c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
1679 r = message_peek_body(m, &m->rindex, 8, 0, NULL);
1683 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1684 c->index += 1 + l + 1;
1689 int sd_bus_message_enter_container(sd_bus_message *m, char type, const char *contents) {
1690 struct bus_container *c, *w;
1691 uint32_t *array_size = NULL;
1702 w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
1707 c = message_get_container(m);
1709 if (!c->signature || c->signature[c->index] == 0)
1712 signature = strdup(contents);
1716 if (type == SD_BUS_TYPE_ARRAY)
1717 r = bus_message_enter_array(m, c, contents, &array_size);
1718 else if (type == SD_BUS_TYPE_VARIANT)
1719 r = bus_message_enter_variant(m, c, contents);
1720 else if (type == SD_BUS_TYPE_STRUCT)
1721 r = bus_message_enter_struct(m, c, contents);
1722 else if (type == SD_BUS_TYPE_DICT_ENTRY)
1723 r = bus_message_enter_dict_entry(m, c, contents);
1732 /* OK, let's fill it in */
1733 w += m->n_containers++;
1734 w->enclosing = type;
1735 w->signature = signature;
1737 w->array_size = array_size;
1738 w->begin = m->rindex;
1743 int sd_bus_message_exit_container(sd_bus_message *m) {
1744 struct bus_container *c;
1750 if (m->n_containers <= 0)
1753 c = message_get_container(m);
1754 if (c->enclosing == SD_BUS_TYPE_ARRAY) {
1757 l = BUS_MESSAGE_BSWAP32(m, *c->array_size);
1758 if (c->begin + l != m->rindex)
1762 if (c->signature && c->signature[c->index] != 0)
1772 int sd_bus_message_peek_type(sd_bus_message *m, char *type, const char **contents) {
1773 struct bus_container *c;
1781 c = message_get_container(m);
1783 if (!c->signature || c->signature[c->index] == 0)
1786 if (message_end_of_array(m, m->rindex))
1789 if (bus_type_is_basic(c->signature[c->index])) {
1793 *type = c->signature[c->index];
1797 if (c->signature[c->index] == SD_BUS_TYPE_ARRAY) {
1803 r = signature_element_length(c->signature+c->index+1, &l);
1809 sig = strndup(c->signature + c->index + 1, l);
1813 free(m->peeked_signature);
1814 m->peeked_signature = sig;
1820 *type = SD_BUS_TYPE_ARRAY;
1825 if (c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ||
1826 c->signature[c->index] == SD_BUS_TYPE_DICT_ENTRY_BEGIN) {
1832 r = signature_element_length(c->signature+c->index, &l);
1837 sig = strndup(c->signature + c->index + 1, l - 2);
1841 free(m->peeked_signature);
1842 m->peeked_signature = sig;
1848 *type = c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY;
1853 if (c->signature[c->index] == SD_BUS_TYPE_VARIANT) {
1859 r = message_peek_body(m, &rindex, 1, 1, &q);
1866 r = message_peek_body(m, &rindex, 1, l+1, &q);
1872 if (!validate_signature(q, l))
1879 *type = SD_BUS_TYPE_VARIANT;
1888 *type = c->enclosing;
1894 int sd_bus_message_rewind(sd_bus_message *m, bool complete) {
1895 struct bus_container *c;
1903 reset_containers(m);
1905 m->root_container.index = 0;
1907 c = message_get_container(m);
1909 c = message_get_container(m);
1912 m->rindex = c->begin;
1915 return !isempty(c->signature);
1918 static int message_read_ap(sd_bus_message *m, const char *types, va_list ap) {
1925 for (t = types; *t; t++) {
1928 case SD_BUS_TYPE_BYTE:
1929 case SD_BUS_TYPE_BOOLEAN:
1930 case SD_BUS_TYPE_INT16:
1931 case SD_BUS_TYPE_UINT16:
1932 case SD_BUS_TYPE_INT32:
1933 case SD_BUS_TYPE_UINT32:
1934 case SD_BUS_TYPE_INT64:
1935 case SD_BUS_TYPE_UINT64:
1936 case SD_BUS_TYPE_DOUBLE:
1937 case SD_BUS_TYPE_STRING:
1938 case SD_BUS_TYPE_OBJECT_PATH:
1939 case SD_BUS_TYPE_SIGNATURE: {
1942 p = va_arg(ap, void*);
1943 r = sd_bus_message_read_basic(m, *t, p);
1947 case SD_BUS_TYPE_ARRAY: {
1950 r = signature_element_length(t + 1, &k);
1958 memcpy(s, t + 1, k);
1962 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, s);
1968 n = va_arg(ap, unsigned);
1969 for (i = 0; i < n; i++) {
1970 r = message_read_ap(m, s, ap);
1975 r = sd_bus_message_exit_container(m);
1981 case SD_BUS_TYPE_VARIANT: {
1984 s = va_arg(ap, const char *);
1988 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, s);
1994 r = message_read_ap(m, s, ap);
2000 r = sd_bus_message_exit_container(m);
2004 case SD_BUS_TYPE_STRUCT_BEGIN:
2005 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
2008 r = signature_element_length(t, &k);
2014 memcpy(s, t + 1, k - 2);
2017 r = sd_bus_message_enter_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
2025 r = message_read_ap(m, s, ap);
2031 r = sd_bus_message_exit_container(m);
2050 int sd_bus_message_read(sd_bus_message *m, const char *types, ...) {
2061 va_start(ap, types);
2062 r = message_read_ap(m, types, ap);
2068 static int message_peek_fields(
2079 return buffer_peek(m->fields, BUS_MESSAGE_FIELDS_SIZE(m), rindex, align, nbytes, ret);
2082 static int message_peek_field_string(
2094 r = message_peek_fields(m, ri, 4, 4, &q);
2098 l = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2099 r = message_peek_fields(m, ri, 1, l+1, &q);
2103 if (!validate_string(q, l))
2112 static int message_peek_field_signature(
2124 r = message_peek_fields(m, ri, 1, 1, &q);
2129 r = message_peek_fields(m, ri, 1, l+1, &q);
2133 if (!validate_signature(q, l))
2142 static int message_peek_field_uint32(
2153 r = message_peek_fields(m, ri, 4, 4, &q);
2158 *ret = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2163 static int message_skip_fields(
2166 uint32_t array_size,
2167 const char **signature) {
2169 size_t original_index;
2176 original_index = *ri;
2183 if (array_size != (uint32_t) -1 &&
2184 array_size <= *ri - original_index)
2191 if (t == SD_BUS_TYPE_STRING ||
2192 t == SD_BUS_TYPE_OBJECT_PATH) {
2194 r = message_peek_field_string(m, ri, NULL);
2200 } else if (t == SD_BUS_TYPE_SIGNATURE) {
2202 r = message_peek_field_signature(m, ri, NULL);
2208 } else if (bus_type_is_basic(t)) {
2211 align = bus_type_get_alignment(align);
2212 k = bus_type_get_size(align);
2214 r = message_peek_fields(m, ri, align, k, NULL);
2220 } else if (t == SD_BUS_TYPE_ARRAY) {
2222 r = signature_element_length(*signature+1, &l);
2232 strncpy(sig, *signature + 1, l-1);
2235 alignment = bus_type_get_alignment(sig[0]);
2239 r = message_peek_fields(m, ri, 4, 4, &q);
2243 nas = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2247 r = message_peek_fields(m, ri, alignment, 0, NULL);
2251 r = message_skip_fields(m, ri, nas, (const char**) &s);
2256 (*signature) += 1 + l;
2258 } else if (t == SD_BUS_TYPE_VARIANT) {
2261 r = message_peek_field_signature(m, ri, &s);
2265 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
2271 } else if (t == SD_BUS_TYPE_STRUCT ||
2272 t == SD_BUS_TYPE_DICT_ENTRY) {
2274 r = signature_element_length(*signature, &l);
2281 strncpy(sig, *signature + 1, l-1);
2284 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
2295 static int message_parse_fields(sd_bus_message *m) {
2301 for (ri = 0; ri < BUS_MESSAGE_FIELDS_SIZE(m); ) {
2302 const char *signature;
2305 r = message_peek_fields(m, &ri, 8, 1, (void**) &header);
2309 r = message_peek_field_signature(m, &ri, &signature);
2314 case _SD_BUS_MESSAGE_HEADER_INVALID:
2317 case SD_BUS_MESSAGE_HEADER_PATH:
2318 if (!streq(signature, "o"))
2321 r = message_peek_field_string(m, &ri, &m->path);
2324 case SD_BUS_MESSAGE_HEADER_INTERFACE:
2325 if (!streq(signature, "s"))
2328 r = message_peek_field_string(m, &ri, &m->interface);
2331 case SD_BUS_MESSAGE_HEADER_MEMBER:
2332 if (!streq(signature, "s"))
2335 r = message_peek_field_string(m, &ri, &m->member);
2338 case SD_BUS_MESSAGE_HEADER_ERROR_NAME:
2339 if (!streq(signature, "s"))
2342 r = message_peek_field_string(m, &ri, &m->error.name);
2345 case SD_BUS_MESSAGE_HEADER_DESTINATION:
2346 if (!streq(signature, "s"))
2349 r = message_peek_field_string(m, &ri, &m->destination);
2352 case SD_BUS_MESSAGE_HEADER_SENDER:
2353 if (!streq(signature, "s"))
2356 r = message_peek_field_string(m, &ri, &m->sender);
2360 case SD_BUS_MESSAGE_HEADER_SIGNATURE: {
2364 if (!streq(signature, "g"))
2367 r = message_peek_field_signature(m, &ri, &s);
2375 free(m->root_container.signature);
2376 m->root_container.signature = c;
2382 case SD_BUS_MESSAGE_HEADER_REPLY_SERIAL:
2383 if (!streq(signature, "u"))
2386 r = message_peek_field_uint32(m, &ri, &m->reply_serial);
2390 r = message_skip_fields(m, &ri, (uint32_t) -1, (const char **) &signature);
2397 if (isempty(m->root_container.signature) != (BUS_MESSAGE_BODY_SIZE(m) == 0))
2400 switch (m->header->type) {
2402 case SD_BUS_MESSAGE_TYPE_SIGNAL:
2403 if (!m->path || !m->interface || !m->member)
2407 case SD_BUS_MESSAGE_TYPE_METHOD_CALL:
2409 if (!m->path || !m->member)
2414 case SD_BUS_MESSAGE_TYPE_METHOD_RETURN:
2416 if (m->reply_serial == 0)
2420 case SD_BUS_MESSAGE_TYPE_METHOD_ERROR:
2422 if (m->reply_serial == 0 || !m->error.name)
2430 static void setup_iovec(sd_bus_message *m) {
2436 m->iovec[m->n_iovec].iov_base = m->header;
2437 m->iovec[m->n_iovec].iov_len = sizeof(*m->header);
2441 m->iovec[m->n_iovec].iov_base = m->fields;
2442 m->iovec[m->n_iovec].iov_len = m->header->fields_size;
2445 if (m->header->fields_size % 8 != 0) {
2446 static const uint8_t padding[7] = { 0, 0, 0, 0, 0, 0, 0 };
2448 m->iovec[m->n_iovec].iov_base = (void*) padding;
2449 m->iovec[m->n_iovec].iov_len = 8 - m->header->fields_size % 8;
2455 m->iovec[m->n_iovec].iov_base = m->body;
2456 m->iovec[m->n_iovec].iov_len = m->header->body_size;
2461 int bus_message_seal(sd_bus_message *m, uint64_t serial) {
2469 if (m->n_containers > 0)
2472 /* If there's a non-trivial signature set, then add it in here */
2473 if (!isempty(m->root_container.signature)) {
2474 r = message_append_field_signature(m, SD_BUS_MESSAGE_HEADER_SIGNATURE, m->root_container.signature, NULL);
2480 r = message_append_field_uint32(m, SD_BUS_MESSAGE_HEADER_UNIX_FDS, m->n_fds);
2485 m->header->serial = serial;
2493 int sd_bus_message_set_destination(sd_bus_message *m, const char *destination) {
2503 return message_append_field_string(m, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &m->destination);
2506 int bus_message_dump(sd_bus_message *m) {
2512 printf("Message %p\n"
2519 "\tfields_size=%u\n"
2524 "\tdestination=%s\n"
2527 "\treply_serial=%u\n"
2529 "\terror.message=%s\n"
2537 BUS_MESSAGE_SERIAL(m),
2538 BUS_MESSAGE_FIELDS_SIZE(m),
2539 BUS_MESSAGE_BODY_SIZE(m),
2541 strna(m->interface),
2543 strna(m->destination),
2545 strna(m->root_container.signature),
2547 strna(m->error.name),
2548 strna(m->error.message),
2551 r = sd_bus_message_rewind(m, true);
2553 log_error("Failed to rewind: %s", strerror(-r));
2557 printf("BEGIN_MESSAGE \"%s\" {\n", strempty(m->root_container.signature));
2560 _cleanup_free_ char *prefix = NULL;
2561 const char *contents = NULL;
2576 r = sd_bus_message_peek_type(m, &type, &contents);
2578 log_error("Failed to peek type: %s", strerror(-r));
2585 r = sd_bus_message_exit_container(m);
2587 log_error("Failed to exit container: %s", strerror(-r));
2593 prefix = strrep("\t", level);
2597 if (type == SD_BUS_TYPE_ARRAY)
2598 printf("%s} END_ARRAY \n", prefix);
2599 else if (type == SD_BUS_TYPE_VARIANT)
2600 printf("%s} END_VARIANT\n", prefix);
2601 else if (type == SD_BUS_TYPE_STRUCT)
2602 printf("%s} END_STRUCT\n", prefix);
2603 else if (type == SD_BUS_TYPE_DICT_ENTRY)
2604 printf("%s} END_DICT_ENTRY\n", prefix);
2609 prefix = strrep("\t", level);
2613 if (bus_type_is_container(type) > 0) {
2614 r = sd_bus_message_enter_container(m, type, contents);
2616 log_error("Failed to enter container: %s", strerror(-r));
2620 if (type == SD_BUS_TYPE_ARRAY)
2621 printf("%sBEGIN_ARRAY \"%s\" {\n", prefix, contents);
2622 else if (type == SD_BUS_TYPE_VARIANT)
2623 printf("%sBEGIN_VARIANT \"%s\" {\n", prefix, contents);
2624 else if (type == SD_BUS_TYPE_STRUCT)
2625 printf("%sBEGIN_STRUCT \"%s\" {\n", prefix, contents);
2626 else if (type == SD_BUS_TYPE_DICT_ENTRY)
2627 printf("%sBEGIN_DICT_ENTRY \"%s\" {\n", prefix, contents);
2634 r = sd_bus_message_read_basic(m, type, &basic);
2636 log_error("Failed to get basic: %s", strerror(-r));
2642 case SD_BUS_TYPE_BYTE:
2643 printf("%sBYTE: %u\n", prefix, basic.u8);
2646 case SD_BUS_TYPE_BOOLEAN:
2647 printf("%sBOOLEAN: %s\n", prefix, yes_no(basic.i));
2650 case SD_BUS_TYPE_INT16:
2651 printf("%sINT16: %i\n", prefix, basic.s16);
2654 case SD_BUS_TYPE_UINT16:
2655 printf("%sUINT16: %u\n", prefix, basic.u16);
2658 case SD_BUS_TYPE_INT32:
2659 printf("%sINT32: %i\n", prefix, basic.s32);
2662 case SD_BUS_TYPE_UINT32:
2663 printf("%sUINT32: %u\n", prefix, basic.u32);
2666 case SD_BUS_TYPE_INT64:
2667 printf("%sINT64: %lli\n", prefix, (long long) basic.s64);
2670 case SD_BUS_TYPE_UINT64:
2671 printf("%sUINT64: %llu\n", prefix, (unsigned long long) basic.u64);
2674 case SD_BUS_TYPE_DOUBLE:
2675 printf("%sDOUBLE: %g\n", prefix, basic.d64);
2678 case SD_BUS_TYPE_STRING:
2679 printf("%sSTRING: \"%s\"\n", prefix, basic.string);
2682 case SD_BUS_TYPE_OBJECT_PATH:
2683 printf("%sOBJECT_PATH: \"%s\"\n", prefix, basic.string);
2686 case SD_BUS_TYPE_SIGNATURE:
2687 printf("%sSIGNATURE: \"%s\"\n", prefix, basic.string);
2690 case SD_BUS_TYPE_UNIX_FD:
2691 printf("%sUNIX_FD: %i\n", prefix, basic.i);
2695 assert_not_reached("Unknown basic type.");
2699 printf("} END_MESSAGE\n");
2703 int bus_message_get_blob(sd_bus_message *m, void **buffer, size_t *sz) {
2712 for (i = 0, total = 0; i < m->n_iovec; i++)
2713 total += m->iovec[i].iov_len;
2719 for (i = 0, e = p; i < m->n_iovec; i++)
2720 e = mempcpy(e, m->iovec[i].iov_base, m->iovec[i].iov_len);