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) {
457 r = message_new_reply(bus, call, SD_BUS_MESSAGE_TYPE_METHOD_ERROR, &t);
461 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_ERROR_NAME, SD_BUS_TYPE_STRING, e->name, &t->error.name);
466 r = message_append_basic(t, SD_BUS_TYPE_STRING, e->message, (const void**) &t->error.message);
479 sd_bus_message* sd_bus_message_ref(sd_bus_message *m) {
483 assert(m->n_ref > 0);
489 sd_bus_message* sd_bus_message_unref(sd_bus_message *m) {
493 assert(m->n_ref > 0);
502 int sd_bus_message_get_type(sd_bus_message *m, uint8_t *type) {
508 *type = m->header->type;
512 int sd_bus_message_get_serial(sd_bus_message *m, uint64_t *serial) {
517 if (m->header->serial == 0)
520 *serial = BUS_MESSAGE_SERIAL(m);
524 int sd_bus_message_get_reply_serial(sd_bus_message *m, uint64_t *serial) {
529 if (m->reply_serial == 0)
532 *serial = m->reply_serial;
536 int sd_bus_message_get_no_reply(sd_bus_message *m) {
540 return m->header->type == SD_BUS_MESSAGE_TYPE_METHOD_CALL ? !!(m->header->flags & SD_BUS_MESSAGE_NO_REPLY_EXPECTED) : 0;
543 const char *sd_bus_message_get_path(sd_bus_message *m) {
550 const char *sd_bus_message_get_interface(sd_bus_message *m) {
557 const char *sd_bus_message_get_member(sd_bus_message *m) {
563 const char *sd_bus_message_get_destination(sd_bus_message *m) {
567 return m->destination;
570 const char *sd_bus_message_get_sender(sd_bus_message *m) {
577 const sd_bus_error *sd_bus_message_get_error(sd_bus_message *m) {
581 if (!sd_bus_error_is_set(&m->error))
587 int sd_bus_message_get_uid(sd_bus_message *m, uid_t *uid) {
597 int sd_bus_message_get_gid(sd_bus_message *m, gid_t *gid) {
607 int sd_bus_message_get_pid(sd_bus_message *m, pid_t *pid) {
617 int sd_bus_message_get_tid(sd_bus_message *m, pid_t *tid) {
627 int sd_bus_message_is_signal(sd_bus_message *m, const char *interface, const char *member) {
631 if (m->header->type != SD_BUS_MESSAGE_TYPE_SIGNAL)
634 if (interface && (!m->interface || !streq(m->interface, interface)))
637 if (member && (!m->member || !streq(m->member, member)))
643 int sd_bus_message_is_method_call(sd_bus_message *m, const char *interface, const char *member) {
647 if (m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_CALL)
650 if (interface && (!m->interface || !streq(m->interface, interface)))
653 if (member && (!m->member || !streq(m->member, member)))
659 int sd_bus_message_is_method_error(sd_bus_message *m, const char *name) {
663 if (m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_ERROR)
666 if (name && (!m->error.name || !streq(m->error.name, name)))
672 int sd_bus_message_set_no_reply(sd_bus_message *m, int b) {
677 if (m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_CALL)
681 m->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
683 m->header->flags &= ~SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
688 static struct bus_container *message_get_container(sd_bus_message *m) {
691 if (m->n_containers == 0)
692 return &m->root_container;
694 assert(m->containers);
695 return m->containers + m->n_containers - 1;
698 static void *message_extend_body(sd_bus_message *m, size_t align, size_t sz) {
701 struct bus_container *c;
707 added = m->header->body_size;
709 p = buffer_extend(&m->body, &m->header->body_size, align, sz);
713 added = m->header->body_size - added;
715 for (c = m->containers; c < m->containers + m->n_containers; c++)
717 c->array_size = (uint32_t*) ((uint8_t*) m->body + ((uint8_t*) c->array_size - (uint8_t*) o));
718 *c->array_size += added;
722 if (m->error.message)
723 m->error.message = (const char*) m->body + (m->error.message - (const char*) o);
731 int message_append_basic(sd_bus_message *m, char type, const void *p, const void **stored) {
732 struct bus_container *c;
742 if (!bus_type_is_basic(type))
745 c = message_get_container(m);
747 if (c->signature && c->signature[c->index]) {
748 /* Container signature is already set */
750 if (c->signature[c->index] != type)
753 /* Maybe we can append to the signature? But only if this is the top-level container*/
754 if (c->enclosing != 0)
757 e = strextend(&c->signature, CHAR_TO_STR(type), NULL);
764 case SD_BUS_TYPE_STRING:
765 case SD_BUS_TYPE_OBJECT_PATH:
767 sz = 4 + strlen(p) + 1;
770 case SD_BUS_TYPE_SIGNATURE:
772 sz = 1 + strlen(p) + 1;
775 case SD_BUS_TYPE_BOOLEAN:
778 assert_cc(sizeof(int) == sizeof(uint32_t));
785 align = bus_type_get_alignment(type);
786 sz = bus_type_get_size(type);
793 a = message_extend_body(m, align, sz);
795 /* Truncate extended signature again */
797 c->signature[c->index] = 0;
802 if (type == SD_BUS_TYPE_STRING || type == SD_BUS_TYPE_OBJECT_PATH) {
803 *(uint32_t*) a = sz - 5;
804 memcpy((uint8_t*) a + 4, p, sz - 4);
807 *stored = (const uint8_t*) a + 4;
809 } else if (type == SD_BUS_TYPE_SIGNATURE) {
810 *(uint8_t*) a = sz - 1;
811 memcpy((uint8_t*) a + 1, p, sz - 1);
814 *stored = (const uint8_t*) a + 1;
823 if (c->enclosing != SD_BUS_TYPE_ARRAY)
829 int sd_bus_message_append_basic(sd_bus_message *m, char type, const void *p) {
830 return message_append_basic(m, type, p, NULL);
833 static int bus_message_open_array(
835 struct bus_container *c,
836 const char *contents,
837 uint32_t **array_size) {
850 if (!signature_is_single(contents))
853 alignment = bus_type_get_alignment(contents[0]);
857 if (c->signature && c->signature[c->index]) {
859 /* Verify the existing signature */
861 if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
864 if (!startswith(c->signature + c->index + 1, contents))
867 nindex = c->index + 1 + strlen(contents);
869 if (c->enclosing != 0)
872 /* Extend the existing signature */
874 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_ARRAY), contents, NULL);
878 nindex = e - c->signature;
881 saved = m->header->body_size;
882 a = message_extend_body(m, 4, 4);
884 /* Truncate extended signature again */
886 c->signature[c->index] = 0;
892 if (!message_extend_body(m, alignment, 0)) {
893 /* Add alignment between size and first element */
895 c->signature[c->index] = 0;
897 m->header->body_size = saved;
901 if (c->enclosing != SD_BUS_TYPE_ARRAY)
904 /* m->body might have changed so let's readjust a */
905 a = (uint8_t*) m->body + ((uint8_t*) a - (uint8_t*) b);
912 static int bus_message_open_variant(
914 struct bus_container *c,
915 const char *contents) {
925 if (!signature_is_single(contents))
928 if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
931 if (c->signature && c->signature[c->index]) {
933 if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
937 if (c->enclosing != 0)
940 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_VARIANT), NULL);
945 l = strlen(contents);
946 a = message_extend_body(m, 1, 1 + l + 1);
948 /* Truncate extended signature again */
950 c->signature[c->index] = 0;
956 memcpy((uint8_t*) a + 1, contents, l + 1);
958 if (c->enclosing != SD_BUS_TYPE_ARRAY)
964 static int bus_message_open_struct(
966 struct bus_container *c,
967 const char *contents) {
976 if (!signature_is_valid(contents, false))
979 if (c->signature && c->signature[c->index]) {
982 l = strlen(contents);
984 if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
985 !startswith(c->signature + c->index + 1, contents) ||
986 c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
989 nindex = c->index + 1 + l + 1;
991 if (c->enclosing != 0)
994 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_BEGIN), contents, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_END), NULL);
998 nindex = e - c->signature;
1001 /* Align contents to 8 byte boundary */
1002 if (!message_extend_body(m, 8, 0)) {
1004 c->signature[c->index] = 0;
1009 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1015 static int bus_message_open_dict_entry(
1017 struct bus_container *c,
1018 const char *contents) {
1026 if (!signature_is_pair(contents))
1029 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1032 if (c->signature && c->signature[c->index]) {
1035 l = strlen(contents);
1037 if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
1038 !startswith(c->signature + c->index + 1, contents) ||
1039 c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
1042 nindex = c->index + 1 + l + 1;
1046 /* Align contents to 8 byte boundary */
1047 if (!message_extend_body(m, 8, 0))
1050 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1056 int sd_bus_message_open_container(
1059 const char *contents) {
1061 struct bus_container *c, *w;
1062 uint32_t *array_size = NULL;
1073 /* Make sure we have space for one more container */
1074 w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
1079 c = message_get_container(m);
1081 signature = strdup(contents);
1085 if (type == SD_BUS_TYPE_ARRAY)
1086 r = bus_message_open_array(m, c, contents, &array_size);
1087 else if (type == SD_BUS_TYPE_VARIANT)
1088 r = bus_message_open_variant(m, c, contents);
1089 else if (type == SD_BUS_TYPE_STRUCT)
1090 r = bus_message_open_struct(m, c, contents);
1091 else if (type == SD_BUS_TYPE_DICT_ENTRY)
1092 r = bus_message_open_dict_entry(m, c, contents);
1101 /* OK, let's fill it in */
1102 w += m->n_containers++;
1103 w->enclosing = type;
1104 w->signature = signature;
1106 w->array_size = array_size;
1112 int sd_bus_message_close_container(sd_bus_message *m) {
1113 struct bus_container *c;
1119 if (m->n_containers <= 0)
1122 c = message_get_container(m);
1123 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1124 if (c->signature && c->signature[c->index] != 0)
1133 static int message_append_ap(
1144 for (t = types; *t; t++) {
1147 case SD_BUS_TYPE_BYTE: {
1150 x = (uint8_t) va_arg(ap, int);
1151 r = sd_bus_message_append_basic(m, *t, &x);
1155 case SD_BUS_TYPE_BOOLEAN:
1156 case SD_BUS_TYPE_INT32:
1157 case SD_BUS_TYPE_UINT32:
1158 case SD_BUS_TYPE_UNIX_FD: {
1161 /* We assume a boolean is the same as int32_t */
1162 assert_cc(sizeof(int32_t) == sizeof(int));
1164 x = va_arg(ap, uint32_t);
1165 r = sd_bus_message_append_basic(m, *t, &x);
1169 case SD_BUS_TYPE_INT16:
1170 case SD_BUS_TYPE_UINT16: {
1173 x = (uint16_t) va_arg(ap, int);
1174 r = sd_bus_message_append_basic(m, *t, &x);
1178 case SD_BUS_TYPE_INT64:
1179 case SD_BUS_TYPE_UINT64:
1180 case SD_BUS_TYPE_DOUBLE: {
1183 x = va_arg(ap, uint64_t);
1184 r = sd_bus_message_append_basic(m, *t, &x);
1188 case SD_BUS_TYPE_STRING:
1189 case SD_BUS_TYPE_OBJECT_PATH:
1190 case SD_BUS_TYPE_SIGNATURE: {
1193 x = va_arg(ap, const char*);
1194 r = sd_bus_message_append_basic(m, *t, x);
1198 case SD_BUS_TYPE_ARRAY: {
1201 r = signature_element_length(t + 1, &k);
1209 memcpy(s, t + 1, k);
1213 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, s);
1217 n = va_arg(ap, unsigned);
1218 for (i = 0; i < n; i++) {
1219 r = message_append_ap(m, s, ap);
1224 r = sd_bus_message_close_container(m);
1230 case SD_BUS_TYPE_VARIANT: {
1233 s = va_arg(ap, const char*);
1237 r = sd_bus_message_open_container(m, SD_BUS_TYPE_VARIANT, s);
1241 r = message_append_ap(m, s, ap);
1245 r = sd_bus_message_close_container(m);
1249 case SD_BUS_TYPE_STRUCT_BEGIN:
1250 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
1253 r = signature_element_length(t, &k);
1260 memcpy(s, t + 1, k - 2);
1263 r = sd_bus_message_open_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
1269 r = message_append_ap(m, s, ap);
1273 r = sd_bus_message_close_container(m);
1290 int sd_bus_message_append(sd_bus_message *m, const char *types, ...) {
1301 va_start(ap, types);
1302 r = message_append_ap(m, types, ap);
1308 static int buffer_peek(const void *p, uint32_t sz, size_t *rindex, size_t align, size_t nbytes, void **r) {
1314 start = ALIGN_TO((size_t) *rindex, align);
1320 /* Verify that padding is 0 */
1321 for (k = *rindex; k < start; k++)
1322 if (((const uint8_t*) p)[k] != 0)
1326 *r = (uint8_t*) p + start;
1333 static bool message_end_of_array(sd_bus_message *m, size_t index) {
1334 struct bus_container *c;
1338 c = message_get_container(m);
1342 return index >= c->begin + BUS_MESSAGE_BSWAP32(m, *c->array_size);
1345 static int message_peek_body(sd_bus_message *m, size_t *rindex, size_t align, size_t nbytes, void **ret) {
1350 if (message_end_of_array(m, *rindex))
1353 return buffer_peek(m->body, BUS_MESSAGE_BODY_SIZE(m), rindex, align, nbytes, ret);
1356 static bool validate_string(const char *s, size_t l) {
1359 /* Check for NUL chars in the string */
1360 if (memchr(s, 0, l))
1363 /* Check for NUL termination */
1367 /* Check if valid UTF8 */
1368 if (!utf8_is_valid(s))
1374 static bool validate_signature(const char *s, size_t l) {
1375 /* Check for NUL chars in the signature */
1376 if (memchr(s, 0, l))
1379 /* Check for NUL termination */
1383 /* Check if valid signature */
1384 if (!signature_is_valid(s, true))
1390 int sd_bus_message_read_basic(sd_bus_message *m, char type, void *p) {
1391 struct bus_container *c;
1399 if (!bus_type_is_basic(type))
1402 c = message_get_container(m);
1404 if (!c->signature || c->signature[c->index] == 0)
1407 if (c->signature[c->index] != type)
1412 case SD_BUS_TYPE_STRING:
1413 case SD_BUS_TYPE_OBJECT_PATH: {
1418 r = message_peek_body(m, &rindex, 4, 4, &q);
1422 l = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
1423 r = message_peek_body(m, &rindex, 1, l+1, &q);
1429 if (!validate_string(q, l))
1433 *(const char**) p = q;
1437 case SD_BUS_TYPE_SIGNATURE: {
1442 r = message_peek_body(m, &rindex, 1, 1, &q);
1447 r = message_peek_body(m, &rindex, 1, l+1, &q);
1453 if (!validate_signature(q, l))
1457 *(const char**) p = q;
1464 align = bus_type_get_alignment(type);
1465 sz = bus_type_get_size(type);
1467 r = message_peek_body(m, &m->rindex, align, sz, &q);
1473 case SD_BUS_TYPE_BYTE:
1474 *(uint8_t*) p = *(uint8_t*) q;
1477 case SD_BUS_TYPE_BOOLEAN:
1478 *(int*) p = !!*(uint32_t*) q;
1481 case SD_BUS_TYPE_INT16:
1482 case SD_BUS_TYPE_UINT16:
1483 *(uint16_t*) p = BUS_MESSAGE_BSWAP16(m, *(uint16_t*) q);
1486 case SD_BUS_TYPE_INT32:
1487 case SD_BUS_TYPE_UINT32:
1488 *(uint32_t*) p = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
1491 case SD_BUS_TYPE_INT64:
1492 case SD_BUS_TYPE_UINT64:
1493 case SD_BUS_TYPE_DOUBLE:
1494 *(uint64_t*) p = BUS_MESSAGE_BSWAP64(m, *(uint64_t*) q);
1498 assert_not_reached("Unknown basic type...");
1505 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1511 static int bus_message_enter_array(
1513 struct bus_container *c,
1514 const char *contents,
1515 uint32_t **array_size) {
1526 if (!signature_is_single(contents))
1529 alignment = bus_type_get_alignment(contents[0]);
1533 if (!c->signature || c->signature[c->index] == 0)
1536 if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
1539 if (!startswith(c->signature + c->index + 1, contents))
1543 r = message_peek_body(m, &rindex, 4, 4, &q);
1547 if (BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q) > 67108864)
1550 r = message_peek_body(m, &rindex, alignment, 0, NULL);
1556 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1557 c->index += 1 + strlen(contents);
1561 *array_size = (uint32_t*) q;
1566 static int bus_message_enter_variant(
1568 struct bus_container *c,
1569 const char *contents) {
1580 if (!signature_is_single(contents))
1583 if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
1586 if (!c->signature || c->signature[c->index] == 0)
1589 if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
1593 r = message_peek_body(m, &rindex, 1, 1, &q);
1598 r = message_peek_body(m, &rindex, 1, l+1, &q);
1604 if (!validate_signature(q, l))
1607 if (!streq(q, contents))
1610 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1618 static int bus_message_enter_struct(
1620 struct bus_container *c,
1621 const char *contents) {
1630 if (!signature_is_valid(contents, false))
1633 if (!c->signature || c->signature[c->index] == 0)
1636 l = strlen(contents);
1638 if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
1639 !startswith(c->signature + c->index + 1, contents) ||
1640 c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
1643 r = message_peek_body(m, &m->rindex, 8, 0, NULL);
1647 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1648 c->index += 1 + l + 1;
1653 static int bus_message_enter_dict_entry(
1655 struct bus_container *c,
1656 const char *contents) {
1665 if (!signature_is_pair(contents))
1668 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1671 if (!c->signature || c->signature[c->index] == 0)
1674 l = strlen(contents);
1676 if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
1677 !startswith(c->signature + c->index + 1, contents) ||
1678 c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
1681 r = message_peek_body(m, &m->rindex, 8, 0, NULL);
1685 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1686 c->index += 1 + l + 1;
1691 int sd_bus_message_enter_container(sd_bus_message *m, char type, const char *contents) {
1692 struct bus_container *c, *w;
1693 uint32_t *array_size = NULL;
1704 w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
1709 c = message_get_container(m);
1711 if (!c->signature || c->signature[c->index] == 0)
1714 signature = strdup(contents);
1718 if (type == SD_BUS_TYPE_ARRAY)
1719 r = bus_message_enter_array(m, c, contents, &array_size);
1720 else if (type == SD_BUS_TYPE_VARIANT)
1721 r = bus_message_enter_variant(m, c, contents);
1722 else if (type == SD_BUS_TYPE_STRUCT)
1723 r = bus_message_enter_struct(m, c, contents);
1724 else if (type == SD_BUS_TYPE_DICT_ENTRY)
1725 r = bus_message_enter_dict_entry(m, c, contents);
1734 /* OK, let's fill it in */
1735 w += m->n_containers++;
1736 w->enclosing = type;
1737 w->signature = signature;
1739 w->array_size = array_size;
1740 w->begin = m->rindex;
1745 int sd_bus_message_exit_container(sd_bus_message *m) {
1746 struct bus_container *c;
1752 if (m->n_containers <= 0)
1755 c = message_get_container(m);
1756 if (c->enclosing == SD_BUS_TYPE_ARRAY) {
1759 l = BUS_MESSAGE_BSWAP32(m, *c->array_size);
1760 if (c->begin + l != m->rindex)
1764 if (c->signature && c->signature[c->index] != 0)
1774 int sd_bus_message_peek_type(sd_bus_message *m, char *type, const char **contents) {
1775 struct bus_container *c;
1783 c = message_get_container(m);
1785 if (!c->signature || c->signature[c->index] == 0)
1788 if (message_end_of_array(m, m->rindex))
1791 if (bus_type_is_basic(c->signature[c->index])) {
1795 *type = c->signature[c->index];
1799 if (c->signature[c->index] == SD_BUS_TYPE_ARRAY) {
1805 r = signature_element_length(c->signature+c->index+1, &l);
1811 sig = strndup(c->signature + c->index + 1, l);
1815 free(m->peeked_signature);
1816 m->peeked_signature = sig;
1822 *type = SD_BUS_TYPE_ARRAY;
1827 if (c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ||
1828 c->signature[c->index] == SD_BUS_TYPE_DICT_ENTRY_BEGIN) {
1834 r = signature_element_length(c->signature+c->index, &l);
1839 sig = strndup(c->signature + c->index + 1, l - 2);
1843 free(m->peeked_signature);
1844 m->peeked_signature = sig;
1850 *type = c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY;
1855 if (c->signature[c->index] == SD_BUS_TYPE_VARIANT) {
1861 r = message_peek_body(m, &rindex, 1, 1, &q);
1868 r = message_peek_body(m, &rindex, 1, l+1, &q);
1874 if (!validate_signature(q, l))
1881 *type = SD_BUS_TYPE_VARIANT;
1890 *type = c->enclosing;
1896 int sd_bus_message_rewind(sd_bus_message *m, bool complete) {
1897 struct bus_container *c;
1905 reset_containers(m);
1907 m->root_container.index = 0;
1909 c = message_get_container(m);
1911 c = message_get_container(m);
1914 m->rindex = c->begin;
1917 return !isempty(c->signature);
1920 static int message_read_ap(sd_bus_message *m, const char *types, va_list ap) {
1927 for (t = types; *t; t++) {
1930 case SD_BUS_TYPE_BYTE:
1931 case SD_BUS_TYPE_BOOLEAN:
1932 case SD_BUS_TYPE_INT16:
1933 case SD_BUS_TYPE_UINT16:
1934 case SD_BUS_TYPE_INT32:
1935 case SD_BUS_TYPE_UINT32:
1936 case SD_BUS_TYPE_INT64:
1937 case SD_BUS_TYPE_UINT64:
1938 case SD_BUS_TYPE_DOUBLE:
1939 case SD_BUS_TYPE_STRING:
1940 case SD_BUS_TYPE_OBJECT_PATH:
1941 case SD_BUS_TYPE_SIGNATURE: {
1944 p = va_arg(ap, void*);
1945 r = sd_bus_message_read_basic(m, *t, p);
1949 case SD_BUS_TYPE_ARRAY: {
1952 r = signature_element_length(t + 1, &k);
1960 memcpy(s, t + 1, k);
1964 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, s);
1970 n = va_arg(ap, unsigned);
1971 for (i = 0; i < n; i++) {
1972 r = message_read_ap(m, s, ap);
1977 r = sd_bus_message_exit_container(m);
1983 case SD_BUS_TYPE_VARIANT: {
1986 s = va_arg(ap, const char *);
1990 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, s);
1996 r = message_read_ap(m, s, ap);
2002 r = sd_bus_message_exit_container(m);
2006 case SD_BUS_TYPE_STRUCT_BEGIN:
2007 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
2010 r = signature_element_length(t, &k);
2016 memcpy(s, t + 1, k - 2);
2019 r = sd_bus_message_enter_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
2027 r = message_read_ap(m, s, ap);
2033 r = sd_bus_message_exit_container(m);
2052 int sd_bus_message_read(sd_bus_message *m, const char *types, ...) {
2063 va_start(ap, types);
2064 r = message_read_ap(m, types, ap);
2070 static int message_peek_fields(
2081 return buffer_peek(m->fields, BUS_MESSAGE_FIELDS_SIZE(m), rindex, align, nbytes, ret);
2084 static int message_peek_field_string(
2096 r = message_peek_fields(m, ri, 4, 4, &q);
2100 l = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2101 r = message_peek_fields(m, ri, 1, l+1, &q);
2105 if (!validate_string(q, l))
2114 static int message_peek_field_signature(
2126 r = message_peek_fields(m, ri, 1, 1, &q);
2131 r = message_peek_fields(m, ri, 1, l+1, &q);
2135 if (!validate_signature(q, l))
2144 static int message_peek_field_uint32(
2155 r = message_peek_fields(m, ri, 4, 4, &q);
2160 *ret = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2165 static int message_skip_fields(
2168 uint32_t array_size,
2169 const char **signature) {
2171 size_t original_index;
2178 original_index = *ri;
2185 if (array_size != (uint32_t) -1 &&
2186 array_size <= *ri - original_index)
2193 if (t == SD_BUS_TYPE_STRING ||
2194 t == SD_BUS_TYPE_OBJECT_PATH) {
2196 r = message_peek_field_string(m, ri, NULL);
2202 } else if (t == SD_BUS_TYPE_SIGNATURE) {
2204 r = message_peek_field_signature(m, ri, NULL);
2210 } else if (bus_type_is_basic(t)) {
2213 align = bus_type_get_alignment(align);
2214 k = bus_type_get_size(align);
2216 r = message_peek_fields(m, ri, align, k, NULL);
2222 } else if (t == SD_BUS_TYPE_ARRAY) {
2224 r = signature_element_length(*signature+1, &l);
2234 strncpy(sig, *signature + 1, l-1);
2237 alignment = bus_type_get_alignment(sig[0]);
2241 r = message_peek_fields(m, ri, 4, 4, &q);
2245 nas = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2249 r = message_peek_fields(m, ri, alignment, 0, NULL);
2253 r = message_skip_fields(m, ri, nas, (const char**) &s);
2258 (*signature) += 1 + l;
2260 } else if (t == SD_BUS_TYPE_VARIANT) {
2263 r = message_peek_field_signature(m, ri, &s);
2267 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
2273 } else if (t == SD_BUS_TYPE_STRUCT ||
2274 t == SD_BUS_TYPE_DICT_ENTRY) {
2276 r = signature_element_length(*signature, &l);
2283 strncpy(sig, *signature + 1, l-1);
2286 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
2297 static int message_parse_fields(sd_bus_message *m) {
2303 for (ri = 0; ri < BUS_MESSAGE_FIELDS_SIZE(m); ) {
2304 const char *signature;
2307 r = message_peek_fields(m, &ri, 8, 1, (void**) &header);
2311 r = message_peek_field_signature(m, &ri, &signature);
2316 case _SD_BUS_MESSAGE_HEADER_INVALID:
2319 case SD_BUS_MESSAGE_HEADER_PATH:
2320 if (!streq(signature, "o"))
2323 r = message_peek_field_string(m, &ri, &m->path);
2326 case SD_BUS_MESSAGE_HEADER_INTERFACE:
2327 if (!streq(signature, "s"))
2330 r = message_peek_field_string(m, &ri, &m->interface);
2333 case SD_BUS_MESSAGE_HEADER_MEMBER:
2334 if (!streq(signature, "s"))
2337 r = message_peek_field_string(m, &ri, &m->member);
2340 case SD_BUS_MESSAGE_HEADER_ERROR_NAME:
2341 if (!streq(signature, "s"))
2344 r = message_peek_field_string(m, &ri, &m->error.name);
2347 case SD_BUS_MESSAGE_HEADER_DESTINATION:
2348 if (!streq(signature, "s"))
2351 r = message_peek_field_string(m, &ri, &m->destination);
2354 case SD_BUS_MESSAGE_HEADER_SENDER:
2355 if (!streq(signature, "s"))
2358 r = message_peek_field_string(m, &ri, &m->sender);
2362 case SD_BUS_MESSAGE_HEADER_SIGNATURE: {
2366 if (!streq(signature, "g"))
2369 r = message_peek_field_signature(m, &ri, &s);
2377 free(m->root_container.signature);
2378 m->root_container.signature = c;
2384 case SD_BUS_MESSAGE_HEADER_REPLY_SERIAL:
2385 if (!streq(signature, "u"))
2388 r = message_peek_field_uint32(m, &ri, &m->reply_serial);
2392 r = message_skip_fields(m, &ri, (uint32_t) -1, (const char **) &signature);
2399 if (isempty(m->root_container.signature) != (BUS_MESSAGE_BODY_SIZE(m) == 0))
2402 switch (m->header->type) {
2404 case SD_BUS_MESSAGE_TYPE_SIGNAL:
2405 if (!m->path || !m->interface || !m->member)
2409 case SD_BUS_MESSAGE_TYPE_METHOD_CALL:
2411 if (!m->path || !m->member)
2416 case SD_BUS_MESSAGE_TYPE_METHOD_RETURN:
2418 if (m->reply_serial == 0)
2422 case SD_BUS_MESSAGE_TYPE_METHOD_ERROR:
2424 if (m->reply_serial == 0 || !m->error.name)
2432 static void setup_iovec(sd_bus_message *m) {
2438 m->iovec[m->n_iovec].iov_base = m->header;
2439 m->iovec[m->n_iovec].iov_len = sizeof(*m->header);
2443 m->iovec[m->n_iovec].iov_base = m->fields;
2444 m->iovec[m->n_iovec].iov_len = m->header->fields_size;
2447 if (m->header->fields_size % 8 != 0) {
2448 static const uint8_t padding[7] = { 0, 0, 0, 0, 0, 0, 0 };
2450 m->iovec[m->n_iovec].iov_base = (void*) padding;
2451 m->iovec[m->n_iovec].iov_len = 8 - m->header->fields_size % 8;
2457 m->iovec[m->n_iovec].iov_base = m->body;
2458 m->iovec[m->n_iovec].iov_len = m->header->body_size;
2463 int bus_message_seal(sd_bus_message *m, uint64_t serial) {
2471 if (m->n_containers > 0)
2474 /* If there's a non-trivial signature set, then add it in here */
2475 if (!isempty(m->root_container.signature)) {
2476 r = message_append_field_signature(m, SD_BUS_MESSAGE_HEADER_SIGNATURE, m->root_container.signature, NULL);
2482 r = message_append_field_uint32(m, SD_BUS_MESSAGE_HEADER_UNIX_FDS, m->n_fds);
2487 m->header->serial = serial;
2495 int sd_bus_message_set_destination(sd_bus_message *m, const char *destination) {
2505 return message_append_field_string(m, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &m->destination);
2508 int bus_message_dump(sd_bus_message *m) {
2514 printf("Message %p\n"
2521 "\tfields_size=%u\n"
2526 "\tdestination=%s\n"
2529 "\treply_serial=%u\n"
2531 "\terror.message=%s\n"
2539 BUS_MESSAGE_SERIAL(m),
2540 BUS_MESSAGE_FIELDS_SIZE(m),
2541 BUS_MESSAGE_BODY_SIZE(m),
2543 strna(m->interface),
2545 strna(m->destination),
2547 strna(m->root_container.signature),
2549 strna(m->error.name),
2550 strna(m->error.message),
2553 r = sd_bus_message_rewind(m, true);
2555 log_error("Failed to rewind: %s", strerror(-r));
2559 printf("BEGIN_MESSAGE \"%s\" {\n", strempty(m->root_container.signature));
2562 _cleanup_free_ char *prefix = NULL;
2563 const char *contents = NULL;
2578 r = sd_bus_message_peek_type(m, &type, &contents);
2580 log_error("Failed to peek type: %s", strerror(-r));
2587 r = sd_bus_message_exit_container(m);
2589 log_error("Failed to exit container: %s", strerror(-r));
2595 prefix = strrep("\t", level);
2599 if (type == SD_BUS_TYPE_ARRAY)
2600 printf("%s} END_ARRAY \n", prefix);
2601 else if (type == SD_BUS_TYPE_VARIANT)
2602 printf("%s} END_VARIANT\n", prefix);
2603 else if (type == SD_BUS_TYPE_STRUCT)
2604 printf("%s} END_STRUCT\n", prefix);
2605 else if (type == SD_BUS_TYPE_DICT_ENTRY)
2606 printf("%s} END_DICT_ENTRY\n", prefix);
2611 prefix = strrep("\t", level);
2615 if (bus_type_is_container(type) > 0) {
2616 r = sd_bus_message_enter_container(m, type, contents);
2618 log_error("Failed to enter container: %s", strerror(-r));
2622 if (type == SD_BUS_TYPE_ARRAY)
2623 printf("%sBEGIN_ARRAY \"%s\" {\n", prefix, contents);
2624 else if (type == SD_BUS_TYPE_VARIANT)
2625 printf("%sBEGIN_VARIANT \"%s\" {\n", prefix, contents);
2626 else if (type == SD_BUS_TYPE_STRUCT)
2627 printf("%sBEGIN_STRUCT \"%s\" {\n", prefix, contents);
2628 else if (type == SD_BUS_TYPE_DICT_ENTRY)
2629 printf("%sBEGIN_DICT_ENTRY \"%s\" {\n", prefix, contents);
2636 r = sd_bus_message_read_basic(m, type, &basic);
2638 log_error("Failed to get basic: %s", strerror(-r));
2644 case SD_BUS_TYPE_BYTE:
2645 printf("%sBYTE: %u\n", prefix, basic.u8);
2648 case SD_BUS_TYPE_BOOLEAN:
2649 printf("%sBOOLEAN: %s\n", prefix, yes_no(basic.i));
2652 case SD_BUS_TYPE_INT16:
2653 printf("%sINT16: %i\n", prefix, basic.s16);
2656 case SD_BUS_TYPE_UINT16:
2657 printf("%sUINT16: %u\n", prefix, basic.u16);
2660 case SD_BUS_TYPE_INT32:
2661 printf("%sINT32: %i\n", prefix, basic.s32);
2664 case SD_BUS_TYPE_UINT32:
2665 printf("%sUINT32: %u\n", prefix, basic.u32);
2668 case SD_BUS_TYPE_INT64:
2669 printf("%sINT64: %lli\n", prefix, (long long) basic.s64);
2672 case SD_BUS_TYPE_UINT64:
2673 printf("%sUINT64: %llu\n", prefix, (unsigned long long) basic.u64);
2676 case SD_BUS_TYPE_DOUBLE:
2677 printf("%sDOUBLE: %g\n", prefix, basic.d64);
2680 case SD_BUS_TYPE_STRING:
2681 printf("%sSTRING: \"%s\"\n", prefix, basic.string);
2684 case SD_BUS_TYPE_OBJECT_PATH:
2685 printf("%sOBJECT_PATH: \"%s\"\n", prefix, basic.string);
2688 case SD_BUS_TYPE_SIGNATURE:
2689 printf("%sSIGNATURE: \"%s\"\n", prefix, basic.string);
2692 case SD_BUS_TYPE_UNIX_FD:
2693 printf("%sUNIX_FD: %i\n", prefix, basic.i);
2697 assert_not_reached("Unknown basic type.");
2701 printf("} END_MESSAGE\n");
2705 int bus_message_get_blob(sd_bus_message *m, void **buffer, size_t *sz) {
2714 for (i = 0, total = 0; i < m->n_iovec; i++)
2715 total += m->iovec[i].iov_len;
2721 for (i = 0, e = p; i < m->n_iovec; i++)
2722 e = mempcpy(e, m->iovec[i].iov_base, m->iovec[i].iov_len);