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/>.
26 #include "bus-message.h"
28 #include "bus-internal.h"
30 #include "bus-signature.h"
32 int message_append_basic(sd_bus_message *m, char type, const void *p, const void **stored);
34 static void message_free(sd_bus_message *m) {
48 for (i = 0; i < m->n_fds; i++)
49 close_nointr_nofail(m->fds[i]);
51 for (i = 0; i < m->n_containers; i++)
52 free(m->sub_containers[i].signature);
54 free(m->sub_containers);
58 static void* buffer_extend(void **p, uint32_t *sz, size_t align, size_t extend) {
66 start = ALIGN_TO((size_t) *sz, align);
70 return (uint8_t*) *p + start;
72 if (n > (size_t) ((uint32_t) -1))
79 /* Zero out padding */
81 memset((uint8_t*) k + *sz, 0, start - *sz);
86 return (uint8_t*) k + start;
89 static void *message_extend_fields(sd_bus_message *m, size_t align, size_t sz) {
95 p = buffer_extend(&m->fields, &m->header->fields_size, align, sz);
100 /* Adjust quick access pointers */
103 m->path = (const char*) m->fields + (m->path - (const char*) o);
105 m->interface = (const char*) m->fields + (m->interface - (const char*) o);
107 m->member = (const char*) m->fields + (m->member - (const char*) o);
109 m->destination = (const char*) m->fields + (m->destination - (const char*) o);
111 m->sender = (const char*) m->fields + (m->sender - (const char*) o);
113 m->signature = (const char*) m->fields + (m->signature - (const char*) o);
115 m->error.name = (const char*) m->fields + (m->error.name - (const char*) o);
118 m->free_fields = true;
123 static int message_append_field_string(
136 if (l > (size_t) (uint32_t) -1)
139 /* field id byte + signature length + signature 's' + NUL + string length + string + NUL */
140 p = message_extend_fields(m, 8, 4 + 4 + l + 1);
149 ((uint32_t*) p)[1] = l;
150 memcpy(p + 8, s, l + 1);
153 *ret = (const char*) p + 8;
158 static int message_append_field_signature(
173 /* field id byte + signature length + signature 'g' + NUL + string length + string + NUL */
174 p = message_extend_fields(m, 8, 4 + 1 + l + 1);
180 p[2] = SD_BUS_TYPE_SIGNATURE;
183 memcpy(p + 5, s, l + 1);
186 *ret = (const char*) p + 5;
191 static int message_append_field_uint32(sd_bus_message *m, uint8_t h, uint32_t x) {
196 /* field id byte + signature length + signature 'u' + NUL + value */
197 p = message_extend_fields(m, 8, 4 + 4);
203 p[2] = SD_BUS_TYPE_UINT32;
206 ((uint32_t*) p)[1] = x;
211 static sd_bus_message *message_new(sd_bus *bus, uint8_t type) {
214 m = malloc0(ALIGN(sizeof(struct sd_bus_message)) + sizeof(struct bus_header));
219 m->header = (struct bus_header*) ((uint8_t*) m + ALIGN(sizeof(struct sd_bus_message)));
221 #if __BYTE_ORDER == __BIG_ENDIAN
222 m->header->endian = SD_BUS_BIG_ENDIAN;
224 m->header->endian = SD_BUS_LITTLE_ENDIAN;
226 m->header->type = type;
227 m->header->version = bus ? bus->message_version : 1;
232 int sd_bus_message_new_signal(
235 const char *interface,
237 sd_bus_message **m) {
251 t = message_new(bus, SD_BUS_MESSAGE_TYPE_SIGNAL);
255 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_PATH, SD_BUS_TYPE_OBJECT_PATH, path, &t->path);
258 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_INTERFACE, SD_BUS_TYPE_STRING, interface, &t->interface);
261 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_MEMBER, SD_BUS_TYPE_STRING, member, &t->member);
269 sd_bus_message_unref(t);
273 int sd_bus_message_new_method_call(
275 const char *destination,
277 const char *interface,
279 sd_bus_message **m) {
291 t = message_new(bus, SD_BUS_MESSAGE_TYPE_METHOD_CALL);
295 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_PATH, SD_BUS_TYPE_OBJECT_PATH, path, &t->path);
298 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_MEMBER, SD_BUS_TYPE_STRING, member, &t->member);
303 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_INTERFACE, SD_BUS_TYPE_STRING, interface, &t->interface);
309 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &t->destination);
322 static int message_new_reply(
324 sd_bus_message *call,
326 sd_bus_message **m) {
333 if (call->header->type != SD_BUS_MESSAGE_TYPE_METHOD_CALL)
338 t = message_new(bus, type);
342 t->reply_serial = BUS_MESSAGE_SERIAL(call);
344 r = message_append_field_uint32(t, SD_BUS_MESSAGE_HEADER_REPLY_SERIAL, t->reply_serial);
349 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, call->sender, &t->sender);
354 t->dont_send = !!(call->header->flags & SD_BUS_MESSAGE_NO_REPLY_EXPECTED);
363 int sd_bus_message_new_method_return(
365 sd_bus_message *call,
366 sd_bus_message **m) {
368 return message_new_reply(bus, call, SD_BUS_MESSAGE_TYPE_METHOD_RETURN, m);
371 int sd_bus_message_new_method_error(
373 sd_bus_message *call,
374 const sd_bus_error *e,
375 sd_bus_message **m) {
387 r = message_new_reply(bus, call, SD_BUS_MESSAGE_TYPE_METHOD_ERROR, &t);
391 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_ERROR_NAME, SD_BUS_TYPE_STRING, e->name, &t->error.name);
396 r = message_append_basic(t, SD_BUS_TYPE_STRING, e->message, (const void**) &t->error.message);
409 sd_bus_message* sd_bus_message_ref(sd_bus_message *m) {
413 assert(m->n_ref > 0);
419 sd_bus_message* sd_bus_message_unref(sd_bus_message *m) {
423 assert(m->n_ref > 0);
432 int sd_bus_message_get_type(sd_bus_message *m, uint8_t *type) {
438 *type = m->header->type;
442 int sd_bus_message_get_serial(sd_bus_message *m, uint64_t *serial) {
447 if (m->header->serial == 0)
450 *serial = BUS_MESSAGE_SERIAL(m);
454 int sd_bus_message_get_reply_serial(sd_bus_message *m, uint64_t *serial) {
459 if (m->reply_serial == 0)
462 *serial = m->reply_serial;
466 int sd_bus_message_get_no_reply(sd_bus_message *m) {
470 return m->header->type == SD_BUS_MESSAGE_TYPE_METHOD_CALL ? !!(m->header->flags & SD_BUS_MESSAGE_NO_REPLY_EXPECTED) : 0;
473 const char *sd_bus_message_get_path(sd_bus_message *m) {
480 const char *sd_bus_message_get_interface(sd_bus_message *m) {
487 const char *sd_bus_message_get_member(sd_bus_message *m) {
493 const char *sd_bus_message_get_destination(sd_bus_message *m) {
497 return m->destination;
500 const char *sd_bus_message_get_sender(sd_bus_message *m) {
507 const sd_bus_error *sd_bus_message_get_error(sd_bus_message *m) {
511 if (!sd_bus_error_is_set(&m->error))
517 int sd_bus_message_get_uid(sd_bus_message *m, uid_t *uid) {
527 int sd_bus_message_get_gid(sd_bus_message *m, gid_t *gid) {
537 int sd_bus_message_get_pid(sd_bus_message *m, pid_t *pid) {
547 int sd_bus_message_get_tid(sd_bus_message *m, pid_t *tid) {
557 int sd_bus_message_is_signal(sd_bus_message *m, const char *interface, const char *member) {
561 if (m->header->type != SD_BUS_MESSAGE_TYPE_SIGNAL)
564 if (interface && (!m->interface || !streq(m->interface, interface)))
567 if (member && (!m->member || !streq(m->member, member)))
573 int sd_bus_message_is_method_call(sd_bus_message *m, const char *interface, const char *member) {
577 if (m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_CALL)
580 if (interface && (!m->interface || !streq(m->interface, interface)))
583 if (member && (!m->member || !streq(m->member, member)))
589 int sd_bus_message_is_method_error(sd_bus_message *m, const char *name) {
593 if (m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_ERROR)
596 if (name && (!m->error.name || !streq(m->error.name, name)))
602 int sd_bus_message_set_no_reply(sd_bus_message *m, int b) {
607 if (m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_CALL)
611 m->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
613 m->header->flags &= ~SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
618 static struct bus_container *message_get_container(sd_bus_message *m) {
621 if (m->n_containers == 0)
622 return &m->root_container;
624 assert(m->sub_containers);
625 return m->sub_containers + m->n_containers - 1;
628 static void *message_extend_body(sd_bus_message *m, size_t align, size_t sz) {
631 struct bus_container *c;
636 added = m->header->body_size;
638 p = buffer_extend(&m->body, &m->header->body_size, align, sz);
642 added = m->header->body_size - added;
644 for (c = m->sub_containers; c < m->sub_containers + m->n_containers; c++)
646 c->array_size = (uint32_t*) ((uint8_t*) m->body + ((uint8_t*) c->array_size - (uint8_t*) o));
647 *c->array_size += added;
651 if (m->error.message)
652 m->error.message = (const char*) m->body + (m->error.message - (const char*) o);
660 int message_append_basic(sd_bus_message *m, char type, const void *p, const void **stored) {
661 struct bus_container *c;
662 size_t sz, align, nindex;
671 if (!bus_type_is_basic(type))
674 c = message_get_container(m);
676 if (c->signature && c->signature[c->index]) {
677 /* Container signature is already set */
679 if (c->signature[c->index] != type)
682 /* Maybe we can append to the signature? But only if this is the top-level container*/
683 if (c->enclosing != 0)
686 e = strextend(&c->signature, CHAR_TO_STR(type), NULL);
691 nindex = c->index + 1;
695 case SD_BUS_TYPE_STRING:
696 case SD_BUS_TYPE_OBJECT_PATH:
698 sz = 4 + strlen(p) + 1;
701 case SD_BUS_TYPE_SIGNATURE:
703 sz = 1 + strlen(p) + 1;
706 case SD_BUS_TYPE_BOOLEAN:
709 assert_cc(sizeof(int) == sizeof(uint32_t));
716 align = bus_type_get_alignment(type);
717 sz = bus_type_get_size(type);
724 a = message_extend_body(m, align, sz);
726 /* Truncate extended signature again */
728 c->signature[c->index] = 0;
733 if (type == SD_BUS_TYPE_STRING || type == SD_BUS_TYPE_OBJECT_PATH) {
734 *(uint32_t*) a = sz - 5;
735 memcpy((uint8_t*) a + 4, p, sz - 4);
738 *stored = (const uint8_t*) a + 4;
740 } else if (type == SD_BUS_TYPE_SIGNATURE) {
741 *(uint8_t*) a = sz - 1;
742 memcpy((uint8_t*) a + 1, p, sz - 1);
745 *stored = (const uint8_t*) a + 1;
754 if (c->enclosing != SD_BUS_TYPE_ARRAY)
760 int sd_bus_message_append_basic(sd_bus_message *m, char type, const void *p) {
761 return message_append_basic(m, type, p, NULL);
764 static int bus_message_open_array(
766 struct bus_container *c,
767 const char *contents,
768 uint32_t **array_size) {
781 if (!signature_is_single(contents))
784 alignment = bus_type_get_alignment(contents[0]);
788 if (c->signature && c->signature[c->index]) {
790 /* Verify the existing signature */
792 if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
795 if (!startswith(c->signature + c->index + 1, contents))
798 nindex = c->index + 1 + strlen(contents);
800 if (c->enclosing != 0)
803 /* Extend the existing signature */
805 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_ARRAY), contents, NULL);
809 nindex = e - c->signature;
812 saved = m->header->body_size;
813 a = message_extend_body(m, 4, 4);
815 /* Truncate extended signature again */
817 c->signature[c->index] = 0;
823 if (!message_extend_body(m, alignment, 0)) {
824 /* Add alignment between size and first element */
826 c->signature[c->index] = 0;
828 m->header->body_size = saved;
832 if (c->enclosing != SD_BUS_TYPE_ARRAY)
835 /* m->body might have changed so let's readjust a */
836 a = (uint8_t*) m->body + ((uint8_t*) a - (uint8_t*) b);
843 static int bus_message_open_variant(
845 struct bus_container *c,
846 const char *contents) {
856 if (!signature_is_single(contents))
859 if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
862 if (c->signature && c->signature[c->index]) {
864 if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
868 if (c->enclosing != 0)
871 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_VARIANT), NULL);
876 nindex = c->index + 1;
878 l = strlen(contents);
879 a = message_extend_body(m, 1, 1 + l + 1);
881 /* Truncate extended signature again */
883 c->signature[c->index] = 0;
889 memcpy((uint8_t*) a + 1, contents, l + 1);
891 if (c->enclosing != SD_BUS_TYPE_ARRAY)
897 static int bus_message_open_struct(
899 struct bus_container *c,
900 const char *contents) {
909 if (!signature_is_valid(contents, false))
912 if (c->signature && c->signature[c->index]) {
915 l = strlen(contents);
917 if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
918 !startswith(c->signature + c->index + 1, contents) ||
919 c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
922 nindex = c->index + 1 + l + 1;
924 if (c->enclosing != 0)
927 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_BEGIN), contents, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_END), NULL);
931 nindex = e - c->signature;
934 /* Align contents to 8 byte boundary */
935 if (!message_extend_body(m, 8, 0)) {
937 c->signature[c->index] = 0;
942 if (c->enclosing != SD_BUS_TYPE_ARRAY)
948 static int bus_message_open_dict_entry(
950 struct bus_container *c,
951 const char *contents) {
959 if (!signature_is_pair(contents))
962 if (c->enclosing != SD_BUS_TYPE_ARRAY)
965 if (c->signature && c->signature[c->index]) {
968 l = strlen(contents);
970 if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
971 !startswith(c->signature + c->index + 1, contents) ||
972 c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
975 nindex = c->index + 1 + l + 1;
979 /* Align contents to 8 byte boundary */
980 if (!message_extend_body(m, 8, 0))
983 if (c->enclosing != SD_BUS_TYPE_ARRAY)
989 int sd_bus_message_open_container(
992 const char *contents) {
994 struct bus_container *c, *sub;
996 uint32_t *array_size = NULL;
1006 /* Make sure we have space for one more container */
1007 sub = realloc(m->sub_containers, sizeof(struct bus_container) * (m->n_containers + 1));
1011 m->sub_containers = sub;
1013 c = message_get_container(m);
1015 signature = strdup(contents);
1019 if (type == SD_BUS_TYPE_ARRAY)
1020 r = bus_message_open_array(m, c, contents, &array_size);
1021 else if (type == SD_BUS_TYPE_VARIANT)
1022 r = bus_message_open_variant(m, c, contents);
1023 else if (type == SD_BUS_TYPE_STRUCT)
1024 r = bus_message_open_struct(m, c, contents);
1025 else if (type == SD_BUS_TYPE_DICT_ENTRY)
1026 r = bus_message_open_dict_entry(m, c, contents);
1035 /* OK, let's fill it in */
1036 sub += m->n_containers++;
1038 sub->enclosing = type;
1039 sub->signature = signature;
1041 sub->array_size = array_size;
1046 int sd_bus_message_close_container(sd_bus_message *m) {
1047 struct bus_container *c;
1053 if (m->n_containers <= 0)
1056 c = message_get_container(m);
1061 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1062 if (c->signature[c->index] != 0)
1071 static int message_append_ap(
1082 for (t = types; *t; t++) {
1085 case SD_BUS_TYPE_BYTE: {
1088 x = (uint8_t) va_arg(ap, int);
1089 r = sd_bus_message_append_basic(m, *t, &x);
1093 case SD_BUS_TYPE_BOOLEAN:
1094 case SD_BUS_TYPE_INT32:
1095 case SD_BUS_TYPE_UINT32: {
1098 x = va_arg(ap, uint32_t);
1099 r = sd_bus_message_append_basic(m, *t, &x);
1103 case SD_BUS_TYPE_INT16:
1104 case SD_BUS_TYPE_UINT16: {
1107 x = (uint16_t) va_arg(ap, int);
1108 r = sd_bus_message_append_basic(m, *t, &x);
1112 case SD_BUS_TYPE_INT64:
1113 case SD_BUS_TYPE_UINT64:
1114 case SD_BUS_TYPE_DOUBLE: {
1117 x = va_arg(ap, uint64_t);
1118 r = sd_bus_message_append_basic(m, *t, &x);
1122 case SD_BUS_TYPE_STRING:
1123 case SD_BUS_TYPE_OBJECT_PATH:
1124 case SD_BUS_TYPE_SIGNATURE: {
1127 x = va_arg(ap, const char*);
1128 r = sd_bus_message_append_basic(m, *t, x);
1132 case SD_BUS_TYPE_UNIX_FD: {
1135 x = va_arg(ap, int);
1136 r = sd_bus_message_append_basic(m, *t, &x);
1140 case SD_BUS_TYPE_ARRAY: {
1144 r = signature_element_length(t + 1, &k);
1151 memcpy(s, t + 1, k);
1155 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, s);
1159 n = va_arg(ap, unsigned);
1161 for (i = 0; i < n; i++) {
1162 r = message_append_ap(m, s, ap);
1167 r = sd_bus_message_close_container(m);
1173 case SD_BUS_TYPE_VARIANT: {
1176 s = va_arg(ap, const char*);
1180 r = sd_bus_message_open_container(m, SD_BUS_TYPE_VARIANT, s);
1184 r = message_append_ap(m, s, ap);
1188 r = sd_bus_message_close_container(m);
1192 case SD_BUS_TYPE_STRUCT_BEGIN:
1193 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
1196 r = signature_element_length(t, &k);
1203 memcpy(s, t + 1, k - 2);
1206 r = sd_bus_message_open_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
1212 r = message_append_ap(m, s, ap);
1216 r = sd_bus_message_close_container(m);
1233 int sd_bus_message_append(sd_bus_message *m, const char *types, ...) {
1244 va_start(ap, types);
1245 r = message_append_ap(m, types, ap);
1251 int sd_bus_message_read_type(sd_bus_message *m, char *type, char *element, size_t *length) {
1255 int sd_bus_message_read_basic(sd_bus_message *m, char type, char element, const void **p, size_t *length) {
1259 int sd_bus_message_read(sd_bus_message *m, const char *types, ...) {
1263 int message_parse(sd_bus_message *m) {
1266 if (m->header->version != 1)
1269 if (m->header->endian != SD_BUS_BIG_ENDIAN &&
1270 m->header->endian != SD_BUS_LITTLE_ENDIAN)
1276 static void setup_iovec(sd_bus_message *m) {
1282 m->iovec[m->n_iovec].iov_base = m->header;
1283 m->iovec[m->n_iovec].iov_len = sizeof(*m->header);
1287 m->iovec[m->n_iovec].iov_base = m->fields;
1288 m->iovec[m->n_iovec].iov_len = m->header->fields_size;
1291 if (m->header->fields_size % 8 != 0) {
1292 static const uint8_t padding[7] = { 0, 0, 0, 0, 0, 0, 0 };
1294 m->iovec[m->n_iovec].iov_base = (void*) padding;
1295 m->iovec[m->n_iovec].iov_len = 8 - m->header->fields_size % 8;
1301 m->iovec[m->n_iovec].iov_base = m->body;
1302 m->iovec[m->n_iovec].iov_len = m->header->body_size;
1307 int message_seal(sd_bus_message *m, uint64_t serial) {
1315 if (m->n_containers > 0)
1318 /* If there's a non-trivial signature set, then add it in here */
1319 if (!isempty(m->root_container.signature)) {
1320 r = message_append_field_signature(m, SD_BUS_MESSAGE_HEADER_SIGNATURE, m->root_container.signature, &m->signature);
1326 r = message_append_field_uint32(m, SD_BUS_MESSAGE_HEADER_UNIX_FDS, m->n_fds);
1331 m->header->serial = serial;
1339 int sd_bus_message_set_destination(sd_bus_message *m, const char *destination) {
1349 return message_append_field_string(m, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &m->destination);
1352 void message_dump(sd_bus_message *m) {
1354 log_info("Message %p\n"
1361 "\tfields_size=%u\n"
1366 "\tdestination=%s\n"
1369 "\treply_serial=%u\n"
1371 "\terror.message=%s\n"
1379 BUS_MESSAGE_SERIAL(m),
1380 BUS_MESSAGE_FIELDS_SIZE(m),
1381 BUS_MESSAGE_BODY_SIZE(m),
1383 strna(m->interface),
1385 strna(m->destination),
1387 strna(m->signature),
1389 strna(m->error.name),
1390 strna(m->error.message),
1394 int bus_message_get_blob(sd_bus_message *m, void **buffer, size_t *sz) {
1403 for (i = 0, total = 0; i < m->n_iovec; i++)
1404 total += m->iovec[i].iov_len;
1410 for (i = 0, e = p; i < m->n_iovec; i++)
1411 e = mempcpy(e, m->iovec[i].iov_base, m->iovec[i].iov_len);