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(
232 sd_bus_message **ret) {
235 struct bus_header *h;
236 size_t total, fs, bs, label_sz, a;
239 assert(buffer || length <= 0);
242 if (length < sizeof(struct bus_header))
252 if (h->type == _SD_BUS_MESSAGE_TYPE_INVALID)
255 if (h->endian == SD_BUS_NATIVE_ENDIAN) {
258 } else if (h->endian == SD_BUS_REVERSE_ENDIAN) {
259 fs = bswap_32(h->fields_size);
260 bs = bswap_32(h->body_size);
264 total = sizeof(struct bus_header) + ALIGN_TO(fs, 8) + bs;
269 label_sz = strlen(label);
270 a = ALIGN(sizeof(sd_bus_message)) + label_sz + 1;
272 a = sizeof(sd_bus_message);
280 m->free_header = true;
281 m->fields = (uint8_t*) buffer + sizeof(struct bus_header);
282 m->body = (uint8_t*) buffer + sizeof(struct bus_header) + ALIGN_TO(fs, 8);
289 m->uid_valid = m->gid_valid = true;
293 m->label = (char*) m + ALIGN(sizeof(sd_bus_message));
294 memcpy(m->label, label, label_sz + 1);
298 m->iovec[0].iov_base = buffer;
299 m->iovec[0].iov_len = length;
301 r = message_parse_fields(m);
311 static sd_bus_message *message_new(sd_bus *bus, uint8_t type) {
314 m = malloc0(ALIGN(sizeof(sd_bus_message)) + sizeof(struct bus_header));
319 m->header = (struct bus_header*) ((uint8_t*) m + ALIGN(sizeof(struct sd_bus_message)));
320 m->header->endian = SD_BUS_NATIVE_ENDIAN;
321 m->header->type = type;
322 m->header->version = bus ? bus->message_version : 1;
327 int sd_bus_message_new_signal(
330 const char *interface,
332 sd_bus_message **m) {
346 t = message_new(bus, SD_BUS_MESSAGE_TYPE_SIGNAL);
350 t->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
352 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_PATH, SD_BUS_TYPE_OBJECT_PATH, path, &t->path);
355 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_INTERFACE, SD_BUS_TYPE_STRING, interface, &t->interface);
358 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_MEMBER, SD_BUS_TYPE_STRING, member, &t->member);
366 sd_bus_message_unref(t);
370 int sd_bus_message_new_method_call(
372 const char *destination,
374 const char *interface,
376 sd_bus_message **m) {
388 t = message_new(bus, SD_BUS_MESSAGE_TYPE_METHOD_CALL);
392 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_PATH, SD_BUS_TYPE_OBJECT_PATH, path, &t->path);
395 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_MEMBER, SD_BUS_TYPE_STRING, member, &t->member);
400 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_INTERFACE, SD_BUS_TYPE_STRING, interface, &t->interface);
406 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &t->destination);
419 static int message_new_reply(
421 sd_bus_message *call,
423 sd_bus_message **m) {
432 if (call->header->type != SD_BUS_MESSAGE_TYPE_METHOD_CALL)
437 t = message_new(bus, type);
441 t->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
442 t->reply_serial = BUS_MESSAGE_SERIAL(call);
444 r = message_append_field_uint32(t, SD_BUS_MESSAGE_HEADER_REPLY_SERIAL, t->reply_serial);
449 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, call->sender, &t->sender);
454 t->dont_send = !!(call->header->flags & SD_BUS_MESSAGE_NO_REPLY_EXPECTED);
464 int sd_bus_message_new_method_return(
466 sd_bus_message *call,
467 sd_bus_message **m) {
469 return message_new_reply(bus, call, SD_BUS_MESSAGE_TYPE_METHOD_RETURN, m);
472 int sd_bus_message_new_method_error(
474 sd_bus_message *call,
475 const sd_bus_error *e,
476 sd_bus_message **m) {
481 if (!sd_bus_error_is_set(e))
486 r = message_new_reply(bus, call, SD_BUS_MESSAGE_TYPE_METHOD_ERROR, &t);
490 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_ERROR_NAME, SD_BUS_TYPE_STRING, e->name, &t->error.name);
495 r = message_append_basic(t, SD_BUS_TYPE_STRING, e->message, (const void**) &t->error.message);
508 sd_bus_message* sd_bus_message_ref(sd_bus_message *m) {
512 assert(m->n_ref > 0);
518 sd_bus_message* sd_bus_message_unref(sd_bus_message *m) {
522 assert(m->n_ref > 0);
531 int sd_bus_message_get_type(sd_bus_message *m, uint8_t *type) {
537 *type = m->header->type;
541 int sd_bus_message_get_serial(sd_bus_message *m, uint64_t *serial) {
546 if (m->header->serial == 0)
549 *serial = BUS_MESSAGE_SERIAL(m);
553 int sd_bus_message_get_reply_serial(sd_bus_message *m, uint64_t *serial) {
558 if (m->reply_serial == 0)
561 *serial = m->reply_serial;
565 int sd_bus_message_get_no_reply(sd_bus_message *m) {
569 return m->header->type == SD_BUS_MESSAGE_TYPE_METHOD_CALL ? !!(m->header->flags & SD_BUS_MESSAGE_NO_REPLY_EXPECTED) : 0;
572 const char *sd_bus_message_get_path(sd_bus_message *m) {
579 const char *sd_bus_message_get_interface(sd_bus_message *m) {
586 const char *sd_bus_message_get_member(sd_bus_message *m) {
592 const char *sd_bus_message_get_destination(sd_bus_message *m) {
596 return m->destination;
599 const char *sd_bus_message_get_sender(sd_bus_message *m) {
606 const sd_bus_error *sd_bus_message_get_error(sd_bus_message *m) {
610 if (!sd_bus_error_is_set(&m->error))
616 int sd_bus_message_get_uid(sd_bus_message *m, uid_t *uid) {
626 int sd_bus_message_get_gid(sd_bus_message *m, gid_t *gid) {
636 int sd_bus_message_get_pid(sd_bus_message *m, pid_t *pid) {
646 int sd_bus_message_get_tid(sd_bus_message *m, pid_t *tid) {
656 const char *sd_bus_message_get_label(sd_bus_message *m) {
663 int sd_bus_message_is_signal(sd_bus_message *m, const char *interface, const char *member) {
667 if (m->header->type != SD_BUS_MESSAGE_TYPE_SIGNAL)
670 if (interface && (!m->interface || !streq(m->interface, interface)))
673 if (member && (!m->member || !streq(m->member, member)))
679 int sd_bus_message_is_method_call(sd_bus_message *m, const char *interface, const char *member) {
683 if (m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_CALL)
686 if (interface && (!m->interface || !streq(m->interface, interface)))
689 if (member && (!m->member || !streq(m->member, member)))
695 int sd_bus_message_is_method_error(sd_bus_message *m, const char *name) {
699 if (m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_ERROR)
702 if (name && (!m->error.name || !streq(m->error.name, name)))
708 int sd_bus_message_set_no_reply(sd_bus_message *m, int b) {
713 if (m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_CALL)
717 m->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
719 m->header->flags &= ~SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
724 static struct bus_container *message_get_container(sd_bus_message *m) {
727 if (m->n_containers == 0)
728 return &m->root_container;
730 assert(m->containers);
731 return m->containers + m->n_containers - 1;
734 static void *message_extend_body(sd_bus_message *m, size_t align, size_t sz) {
737 struct bus_container *c;
743 added = m->header->body_size;
745 p = buffer_extend(&m->body, &m->header->body_size, align, sz);
749 added = m->header->body_size - added;
751 for (c = m->containers; c < m->containers + m->n_containers; c++)
753 c->array_size = (uint32_t*) ((uint8_t*) m->body + ((uint8_t*) c->array_size - (uint8_t*) o));
754 *c->array_size += added;
758 if (m->error.message)
759 m->error.message = (const char*) m->body + (m->error.message - (const char*) o);
767 int message_append_basic(sd_bus_message *m, char type, const void *p, const void **stored) {
768 struct bus_container *c;
778 if (!bus_type_is_basic(type))
781 c = message_get_container(m);
783 if (c->signature && c->signature[c->index]) {
784 /* Container signature is already set */
786 if (c->signature[c->index] != type)
789 /* Maybe we can append to the signature? But only if this is the top-level container*/
790 if (c->enclosing != 0)
793 e = strextend(&c->signature, CHAR_TO_STR(type), NULL);
800 case SD_BUS_TYPE_STRING:
801 case SD_BUS_TYPE_OBJECT_PATH:
805 c->signature[c->index] = 0;
811 sz = 4 + strlen(p) + 1;
814 case SD_BUS_TYPE_SIGNATURE:
818 c->signature[c->index] = 0;
824 sz = 1 + strlen(p) + 1;
827 case SD_BUS_TYPE_BOOLEAN:
830 assert_cc(sizeof(int) == sizeof(uint32_t));
837 align = bus_type_get_alignment(type);
838 sz = bus_type_get_size(type);
845 a = message_extend_body(m, align, sz);
847 /* Truncate extended signature again */
849 c->signature[c->index] = 0;
854 if (type == SD_BUS_TYPE_STRING || type == SD_BUS_TYPE_OBJECT_PATH) {
855 *(uint32_t*) a = sz - 5;
856 memcpy((uint8_t*) a + 4, p, sz - 4);
859 *stored = (const uint8_t*) a + 4;
861 } else if (type == SD_BUS_TYPE_SIGNATURE) {
862 *(uint8_t*) a = sz - 1;
863 memcpy((uint8_t*) a + 1, p, sz - 1);
866 *stored = (const uint8_t*) a + 1;
875 if (c->enclosing != SD_BUS_TYPE_ARRAY)
881 int sd_bus_message_append_basic(sd_bus_message *m, char type, const void *p) {
882 return message_append_basic(m, type, p, NULL);
885 static int bus_message_open_array(
887 struct bus_container *c,
888 const char *contents,
889 uint32_t **array_size) {
902 if (!signature_is_single(contents))
905 alignment = bus_type_get_alignment(contents[0]);
909 if (c->signature && c->signature[c->index]) {
911 /* Verify the existing signature */
913 if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
916 if (!startswith(c->signature + c->index + 1, contents))
919 nindex = c->index + 1 + strlen(contents);
921 if (c->enclosing != 0)
924 /* Extend the existing signature */
926 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_ARRAY), contents, NULL);
930 nindex = e - c->signature;
933 saved = m->header->body_size;
934 a = message_extend_body(m, 4, 4);
936 /* Truncate extended signature again */
938 c->signature[c->index] = 0;
944 if (!message_extend_body(m, alignment, 0)) {
945 /* Add alignment between size and first element */
947 c->signature[c->index] = 0;
949 m->header->body_size = saved;
953 if (c->enclosing != SD_BUS_TYPE_ARRAY)
956 /* m->body might have changed so let's readjust a */
957 a = (uint8_t*) m->body + ((uint8_t*) a - (uint8_t*) b);
964 static int bus_message_open_variant(
966 struct bus_container *c,
967 const char *contents) {
977 if (!signature_is_single(contents))
980 if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
983 if (c->signature && c->signature[c->index]) {
985 if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
989 if (c->enclosing != 0)
992 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_VARIANT), NULL);
997 l = strlen(contents);
998 a = message_extend_body(m, 1, 1 + l + 1);
1000 /* Truncate extended signature again */
1002 c->signature[c->index] = 0;
1008 memcpy((uint8_t*) a + 1, contents, l + 1);
1010 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1016 static int bus_message_open_struct(
1018 struct bus_container *c,
1019 const char *contents) {
1028 if (!signature_is_valid(contents, false))
1031 if (c->signature && c->signature[c->index]) {
1034 l = strlen(contents);
1036 if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
1037 !startswith(c->signature + c->index + 1, contents) ||
1038 c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
1041 nindex = c->index + 1 + l + 1;
1043 if (c->enclosing != 0)
1046 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_BEGIN), contents, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_END), NULL);
1050 nindex = e - c->signature;
1053 /* Align contents to 8 byte boundary */
1054 if (!message_extend_body(m, 8, 0)) {
1056 c->signature[c->index] = 0;
1061 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1067 static int bus_message_open_dict_entry(
1069 struct bus_container *c,
1070 const char *contents) {
1078 if (!signature_is_pair(contents))
1081 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1084 if (c->signature && c->signature[c->index]) {
1087 l = strlen(contents);
1089 if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
1090 !startswith(c->signature + c->index + 1, contents) ||
1091 c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
1094 nindex = c->index + 1 + l + 1;
1098 /* Align contents to 8 byte boundary */
1099 if (!message_extend_body(m, 8, 0))
1102 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1108 int sd_bus_message_open_container(
1111 const char *contents) {
1113 struct bus_container *c, *w;
1114 uint32_t *array_size = NULL;
1125 /* Make sure we have space for one more container */
1126 w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
1131 c = message_get_container(m);
1133 signature = strdup(contents);
1137 if (type == SD_BUS_TYPE_ARRAY)
1138 r = bus_message_open_array(m, c, contents, &array_size);
1139 else if (type == SD_BUS_TYPE_VARIANT)
1140 r = bus_message_open_variant(m, c, contents);
1141 else if (type == SD_BUS_TYPE_STRUCT)
1142 r = bus_message_open_struct(m, c, contents);
1143 else if (type == SD_BUS_TYPE_DICT_ENTRY)
1144 r = bus_message_open_dict_entry(m, c, contents);
1153 /* OK, let's fill it in */
1154 w += m->n_containers++;
1155 w->enclosing = type;
1156 w->signature = signature;
1158 w->array_size = array_size;
1164 int sd_bus_message_close_container(sd_bus_message *m) {
1165 struct bus_container *c;
1171 if (m->n_containers <= 0)
1174 c = message_get_container(m);
1175 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1176 if (c->signature && c->signature[c->index] != 0)
1185 static int message_append_ap(
1196 for (t = types; *t; t++) {
1199 case SD_BUS_TYPE_BYTE: {
1202 x = (uint8_t) va_arg(ap, int);
1203 r = sd_bus_message_append_basic(m, *t, &x);
1207 case SD_BUS_TYPE_BOOLEAN:
1208 case SD_BUS_TYPE_INT32:
1209 case SD_BUS_TYPE_UINT32:
1210 case SD_BUS_TYPE_UNIX_FD: {
1213 /* We assume a boolean is the same as int32_t */
1214 assert_cc(sizeof(int32_t) == sizeof(int));
1216 x = va_arg(ap, uint32_t);
1217 r = sd_bus_message_append_basic(m, *t, &x);
1221 case SD_BUS_TYPE_INT16:
1222 case SD_BUS_TYPE_UINT16: {
1225 x = (uint16_t) va_arg(ap, int);
1226 r = sd_bus_message_append_basic(m, *t, &x);
1230 case SD_BUS_TYPE_INT64:
1231 case SD_BUS_TYPE_UINT64:
1232 case SD_BUS_TYPE_DOUBLE: {
1235 x = va_arg(ap, uint64_t);
1236 r = sd_bus_message_append_basic(m, *t, &x);
1240 case SD_BUS_TYPE_STRING:
1241 case SD_BUS_TYPE_OBJECT_PATH:
1242 case SD_BUS_TYPE_SIGNATURE: {
1245 x = va_arg(ap, const char*);
1246 r = sd_bus_message_append_basic(m, *t, x);
1250 case SD_BUS_TYPE_ARRAY: {
1253 r = signature_element_length(t + 1, &k);
1261 memcpy(s, t + 1, k);
1265 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, s);
1269 n = va_arg(ap, unsigned);
1270 for (i = 0; i < n; i++) {
1271 r = message_append_ap(m, s, ap);
1276 r = sd_bus_message_close_container(m);
1282 case SD_BUS_TYPE_VARIANT: {
1285 s = va_arg(ap, const char*);
1289 r = sd_bus_message_open_container(m, SD_BUS_TYPE_VARIANT, s);
1293 r = message_append_ap(m, s, ap);
1297 r = sd_bus_message_close_container(m);
1301 case SD_BUS_TYPE_STRUCT_BEGIN:
1302 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
1305 r = signature_element_length(t, &k);
1312 memcpy(s, t + 1, k - 2);
1315 r = sd_bus_message_open_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
1321 r = message_append_ap(m, s, ap);
1325 r = sd_bus_message_close_container(m);
1342 int sd_bus_message_append(sd_bus_message *m, const char *types, ...) {
1353 va_start(ap, types);
1354 r = message_append_ap(m, types, ap);
1360 static int buffer_peek(const void *p, uint32_t sz, size_t *rindex, size_t align, size_t nbytes, void **r) {
1366 start = ALIGN_TO((size_t) *rindex, align);
1372 /* Verify that padding is 0 */
1373 for (k = *rindex; k < start; k++)
1374 if (((const uint8_t*) p)[k] != 0)
1378 *r = (uint8_t*) p + start;
1385 static bool message_end_of_array(sd_bus_message *m, size_t index) {
1386 struct bus_container *c;
1390 c = message_get_container(m);
1394 return index >= c->begin + BUS_MESSAGE_BSWAP32(m, *c->array_size);
1397 static int message_peek_body(sd_bus_message *m, size_t *rindex, size_t align, size_t nbytes, void **ret) {
1402 if (message_end_of_array(m, *rindex))
1405 return buffer_peek(m->body, BUS_MESSAGE_BODY_SIZE(m), rindex, align, nbytes, ret);
1408 static bool validate_nul(const char *s, size_t l) {
1410 /* Check for NUL chars in the string */
1411 if (memchr(s, 0, l))
1414 /* Check for NUL termination */
1421 static bool validate_string(const char *s, size_t l) {
1423 if (!validate_nul(s, l))
1426 /* Check if valid UTF8 */
1427 if (!utf8_is_valid(s))
1433 static bool validate_signature(const char *s, size_t l) {
1435 if (!validate_nul(s, l))
1438 /* Check if valid signature */
1439 if (!signature_is_valid(s, true))
1445 static bool validate_object_path(const char *s, size_t l) {
1447 if (!validate_nul(s, l))
1450 if (!object_path_is_valid(s))
1456 int sd_bus_message_read_basic(sd_bus_message *m, char type, void *p) {
1457 struct bus_container *c;
1465 if (!bus_type_is_basic(type))
1468 c = message_get_container(m);
1470 if (!c->signature || c->signature[c->index] == 0)
1473 if (c->signature[c->index] != type)
1478 case SD_BUS_TYPE_STRING:
1479 case SD_BUS_TYPE_OBJECT_PATH: {
1484 r = message_peek_body(m, &rindex, 4, 4, &q);
1488 l = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
1489 r = message_peek_body(m, &rindex, 1, l+1, &q);
1495 if (type == SD_BUS_TYPE_OBJECT_PATH) {
1496 if (!validate_object_path(q, l))
1499 if (!validate_string(q, l))
1504 *(const char**) p = q;
1508 case SD_BUS_TYPE_SIGNATURE: {
1513 r = message_peek_body(m, &rindex, 1, 1, &q);
1518 r = message_peek_body(m, &rindex, 1, l+1, &q);
1524 if (!validate_signature(q, l))
1528 *(const char**) p = q;
1535 align = bus_type_get_alignment(type);
1536 sz = bus_type_get_size(type);
1538 r = message_peek_body(m, &m->rindex, align, sz, &q);
1544 case SD_BUS_TYPE_BYTE:
1545 *(uint8_t*) p = *(uint8_t*) q;
1548 case SD_BUS_TYPE_BOOLEAN:
1549 *(int*) p = !!*(uint32_t*) q;
1552 case SD_BUS_TYPE_INT16:
1553 case SD_BUS_TYPE_UINT16:
1554 *(uint16_t*) p = BUS_MESSAGE_BSWAP16(m, *(uint16_t*) q);
1557 case SD_BUS_TYPE_INT32:
1558 case SD_BUS_TYPE_UINT32:
1559 *(uint32_t*) p = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
1562 case SD_BUS_TYPE_INT64:
1563 case SD_BUS_TYPE_UINT64:
1564 case SD_BUS_TYPE_DOUBLE:
1565 *(uint64_t*) p = BUS_MESSAGE_BSWAP64(m, *(uint64_t*) q);
1569 assert_not_reached("Unknown basic type...");
1576 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1582 static int bus_message_enter_array(
1584 struct bus_container *c,
1585 const char *contents,
1586 uint32_t **array_size) {
1597 if (!signature_is_single(contents))
1600 alignment = bus_type_get_alignment(contents[0]);
1604 if (!c->signature || c->signature[c->index] == 0)
1607 if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
1610 if (!startswith(c->signature + c->index + 1, contents))
1614 r = message_peek_body(m, &rindex, 4, 4, &q);
1618 if (BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q) > BUS_ARRAY_MAX_SIZE)
1621 r = message_peek_body(m, &rindex, alignment, 0, NULL);
1627 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1628 c->index += 1 + strlen(contents);
1632 *array_size = (uint32_t*) q;
1637 static int bus_message_enter_variant(
1639 struct bus_container *c,
1640 const char *contents) {
1651 if (!signature_is_single(contents))
1654 if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
1657 if (!c->signature || c->signature[c->index] == 0)
1660 if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
1664 r = message_peek_body(m, &rindex, 1, 1, &q);
1669 r = message_peek_body(m, &rindex, 1, l+1, &q);
1675 if (!validate_signature(q, l))
1678 if (!streq(q, contents))
1681 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1689 static int bus_message_enter_struct(
1691 struct bus_container *c,
1692 const char *contents) {
1701 if (!signature_is_valid(contents, false))
1704 if (!c->signature || c->signature[c->index] == 0)
1707 l = strlen(contents);
1709 if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
1710 !startswith(c->signature + c->index + 1, contents) ||
1711 c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
1714 r = message_peek_body(m, &m->rindex, 8, 0, NULL);
1718 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1719 c->index += 1 + l + 1;
1724 static int bus_message_enter_dict_entry(
1726 struct bus_container *c,
1727 const char *contents) {
1736 if (!signature_is_pair(contents))
1739 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1742 if (!c->signature || c->signature[c->index] == 0)
1745 l = strlen(contents);
1747 if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
1748 !startswith(c->signature + c->index + 1, contents) ||
1749 c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
1752 r = message_peek_body(m, &m->rindex, 8, 0, NULL);
1756 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1757 c->index += 1 + l + 1;
1762 int sd_bus_message_enter_container(sd_bus_message *m, char type, const char *contents) {
1763 struct bus_container *c, *w;
1764 uint32_t *array_size = NULL;
1776 * We enforce a global limit on container depth, that is much
1777 * higher than the 32 structs and 32 arrays the specification
1778 * mandates. This is simpler to implement for us, and we need
1779 * this only to ensure our container array doesn't grow
1780 * without bounds. We are happy to return any data from a
1781 * message as long as the data itself is valid, even if the
1782 * overall message might be not.
1784 * Note that the message signature is validated when
1785 * parsing the headers, and that validation does check the
1788 * Note that the specification defines no limits on the depth
1789 * of stacked variants, but we do.
1791 if (m->n_containers >= BUS_CONTAINER_DEPTH)
1794 w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
1799 c = message_get_container(m);
1801 if (!c->signature || c->signature[c->index] == 0)
1804 signature = strdup(contents);
1808 if (type == SD_BUS_TYPE_ARRAY)
1809 r = bus_message_enter_array(m, c, contents, &array_size);
1810 else if (type == SD_BUS_TYPE_VARIANT)
1811 r = bus_message_enter_variant(m, c, contents);
1812 else if (type == SD_BUS_TYPE_STRUCT)
1813 r = bus_message_enter_struct(m, c, contents);
1814 else if (type == SD_BUS_TYPE_DICT_ENTRY)
1815 r = bus_message_enter_dict_entry(m, c, contents);
1824 /* OK, let's fill it in */
1825 w += m->n_containers++;
1826 w->enclosing = type;
1827 w->signature = signature;
1829 w->array_size = array_size;
1830 w->begin = m->rindex;
1835 int sd_bus_message_exit_container(sd_bus_message *m) {
1836 struct bus_container *c;
1842 if (m->n_containers <= 0)
1845 c = message_get_container(m);
1846 if (c->enclosing == SD_BUS_TYPE_ARRAY) {
1849 l = BUS_MESSAGE_BSWAP32(m, *c->array_size);
1850 if (c->begin + l != m->rindex)
1854 if (c->signature && c->signature[c->index] != 0)
1864 int sd_bus_message_peek_type(sd_bus_message *m, char *type, const char **contents) {
1865 struct bus_container *c;
1873 c = message_get_container(m);
1875 if (!c->signature || c->signature[c->index] == 0)
1878 if (message_end_of_array(m, m->rindex))
1881 if (bus_type_is_basic(c->signature[c->index])) {
1885 *type = c->signature[c->index];
1889 if (c->signature[c->index] == SD_BUS_TYPE_ARRAY) {
1895 r = signature_element_length(c->signature+c->index+1, &l);
1901 sig = strndup(c->signature + c->index + 1, l);
1905 free(m->peeked_signature);
1906 m->peeked_signature = sig;
1912 *type = SD_BUS_TYPE_ARRAY;
1917 if (c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ||
1918 c->signature[c->index] == SD_BUS_TYPE_DICT_ENTRY_BEGIN) {
1924 r = signature_element_length(c->signature+c->index, &l);
1929 sig = strndup(c->signature + c->index + 1, l - 2);
1933 free(m->peeked_signature);
1934 m->peeked_signature = sig;
1940 *type = c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY;
1945 if (c->signature[c->index] == SD_BUS_TYPE_VARIANT) {
1951 r = message_peek_body(m, &rindex, 1, 1, &q);
1958 r = message_peek_body(m, &rindex, 1, l+1, &q);
1964 if (!validate_signature(q, l))
1971 *type = SD_BUS_TYPE_VARIANT;
1980 *type = c->enclosing;
1986 int sd_bus_message_rewind(sd_bus_message *m, int complete) {
1987 struct bus_container *c;
1995 reset_containers(m);
1997 m->root_container.index = 0;
1999 c = message_get_container(m);
2001 c = message_get_container(m);
2004 m->rindex = c->begin;
2007 return !isempty(c->signature);
2010 static int message_read_ap(sd_bus_message *m, const char *types, va_list ap) {
2017 for (t = types; *t; t++) {
2020 case SD_BUS_TYPE_BYTE:
2021 case SD_BUS_TYPE_BOOLEAN:
2022 case SD_BUS_TYPE_INT16:
2023 case SD_BUS_TYPE_UINT16:
2024 case SD_BUS_TYPE_INT32:
2025 case SD_BUS_TYPE_UINT32:
2026 case SD_BUS_TYPE_INT64:
2027 case SD_BUS_TYPE_UINT64:
2028 case SD_BUS_TYPE_DOUBLE:
2029 case SD_BUS_TYPE_STRING:
2030 case SD_BUS_TYPE_OBJECT_PATH:
2031 case SD_BUS_TYPE_SIGNATURE: {
2034 p = va_arg(ap, void*);
2035 r = sd_bus_message_read_basic(m, *t, p);
2039 case SD_BUS_TYPE_ARRAY: {
2042 r = signature_element_length(t + 1, &k);
2050 memcpy(s, t + 1, k);
2054 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, s);
2060 n = va_arg(ap, unsigned);
2061 for (i = 0; i < n; i++) {
2062 r = message_read_ap(m, s, ap);
2067 r = sd_bus_message_exit_container(m);
2073 case SD_BUS_TYPE_VARIANT: {
2076 s = va_arg(ap, const char *);
2080 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, s);
2086 r = message_read_ap(m, s, ap);
2092 r = sd_bus_message_exit_container(m);
2096 case SD_BUS_TYPE_STRUCT_BEGIN:
2097 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
2100 r = signature_element_length(t, &k);
2106 memcpy(s, t + 1, k - 2);
2109 r = sd_bus_message_enter_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
2117 r = message_read_ap(m, s, ap);
2123 r = sd_bus_message_exit_container(m);
2142 int sd_bus_message_read(sd_bus_message *m, const char *types, ...) {
2153 va_start(ap, types);
2154 r = message_read_ap(m, types, ap);
2160 static int message_peek_fields(
2171 return buffer_peek(m->fields, BUS_MESSAGE_FIELDS_SIZE(m), rindex, align, nbytes, ret);
2174 static int message_peek_field_uint32(
2185 r = message_peek_fields(m, ri, 4, 4, &q);
2190 *ret = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2195 static int message_peek_field_string(
2197 bool (*validate)(const char *p),
2208 r = message_peek_field_uint32(m, ri, &l);
2212 r = message_peek_fields(m, ri, 1, l+1, &q);
2217 if (!validate_nul(q, l))
2223 if (!validate_string(q, l))
2233 static int message_peek_field_signature(
2245 r = message_peek_fields(m, ri, 1, 1, &q);
2250 r = message_peek_fields(m, ri, 1, l+1, &q);
2254 if (!validate_signature(q, l))
2263 static int message_skip_fields(
2266 uint32_t array_size,
2267 const char **signature) {
2269 size_t original_index;
2276 original_index = *ri;
2282 if (array_size != (uint32_t) -1 &&
2283 array_size <= *ri - original_index)
2290 if (t == SD_BUS_TYPE_STRING) {
2292 r = message_peek_field_string(m, NULL, ri, NULL);
2298 } else if (t == SD_BUS_TYPE_OBJECT_PATH) {
2300 r = message_peek_field_string(m, object_path_is_valid, ri, NULL);
2306 } else if (t == SD_BUS_TYPE_SIGNATURE) {
2308 r = message_peek_field_signature(m, ri, NULL);
2314 } else if (bus_type_is_basic(t)) {
2317 align = bus_type_get_alignment(t);
2318 k = bus_type_get_size(t);
2320 r = message_peek_fields(m, ri, align, k, NULL);
2326 } else if (t == SD_BUS_TYPE_ARRAY) {
2328 r = signature_element_length(*signature+1, &l);
2338 strncpy(sig, *signature + 1, l-1);
2341 alignment = bus_type_get_alignment(sig[0]);
2345 r = message_peek_field_uint32(m, ri, &nas);
2348 if (nas > BUS_ARRAY_MAX_SIZE)
2351 r = message_peek_fields(m, ri, alignment, 0, NULL);
2355 r = message_skip_fields(m, ri, nas, (const char**) &s);
2360 (*signature) += 1 + l;
2362 } else if (t == SD_BUS_TYPE_VARIANT) {
2365 r = message_peek_field_signature(m, ri, &s);
2369 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
2375 } else if (t == SD_BUS_TYPE_STRUCT ||
2376 t == SD_BUS_TYPE_DICT_ENTRY) {
2378 r = signature_element_length(*signature, &l);
2385 strncpy(sig, *signature + 1, l-1);
2388 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
2399 static int message_parse_fields(sd_bus_message *m) {
2405 for (ri = 0; ri < BUS_MESSAGE_FIELDS_SIZE(m); ) {
2406 const char *signature;
2409 r = message_peek_fields(m, &ri, 8, 1, (void**) &header);
2413 r = message_peek_field_signature(m, &ri, &signature);
2418 case _SD_BUS_MESSAGE_HEADER_INVALID:
2421 case SD_BUS_MESSAGE_HEADER_PATH:
2422 if (!streq(signature, "o"))
2425 r = message_peek_field_string(m, object_path_is_valid, &ri, &m->path);
2428 case SD_BUS_MESSAGE_HEADER_INTERFACE:
2429 if (!streq(signature, "s"))
2432 r = message_peek_field_string(m, interface_name_is_valid, &ri, &m->interface);
2435 case SD_BUS_MESSAGE_HEADER_MEMBER:
2436 if (!streq(signature, "s"))
2439 r = message_peek_field_string(m, member_name_is_valid, &ri, &m->member);
2442 case SD_BUS_MESSAGE_HEADER_ERROR_NAME:
2443 if (!streq(signature, "s"))
2446 r = message_peek_field_string(m, error_name_is_valid, &ri, &m->error.name);
2449 case SD_BUS_MESSAGE_HEADER_DESTINATION:
2450 if (!streq(signature, "s"))
2453 r = message_peek_field_string(m, service_name_is_valid, &ri, &m->destination);
2456 case SD_BUS_MESSAGE_HEADER_SENDER:
2457 if (!streq(signature, "s"))
2460 r = message_peek_field_string(m, service_name_is_valid, &ri, &m->sender);
2464 case SD_BUS_MESSAGE_HEADER_SIGNATURE: {
2468 if (!streq(signature, "g"))
2471 r = message_peek_field_signature(m, &ri, &s);
2479 free(m->root_container.signature);
2480 m->root_container.signature = c;
2484 case SD_BUS_MESSAGE_HEADER_REPLY_SERIAL:
2485 if (!streq(signature, "u"))
2488 r = message_peek_field_uint32(m, &ri, &m->reply_serial);
2492 if (m->reply_serial == 0)
2498 r = message_skip_fields(m, &ri, (uint32_t) -1, (const char **) &signature);
2505 if (isempty(m->root_container.signature) != (BUS_MESSAGE_BODY_SIZE(m) == 0))
2508 switch (m->header->type) {
2510 case SD_BUS_MESSAGE_TYPE_SIGNAL:
2511 if (!m->path || !m->interface || !m->member)
2515 case SD_BUS_MESSAGE_TYPE_METHOD_CALL:
2517 if (!m->path || !m->member)
2522 case SD_BUS_MESSAGE_TYPE_METHOD_RETURN:
2524 if (m->reply_serial == 0)
2528 case SD_BUS_MESSAGE_TYPE_METHOD_ERROR:
2530 if (m->reply_serial == 0 || !m->error.name)
2535 /* Try to read the error message, but if we can't it's a non-issue */
2536 if (m->header->type == SD_BUS_MESSAGE_TYPE_METHOD_ERROR)
2537 sd_bus_message_read(m, "s", &m->error.message);
2542 static void setup_iovec(sd_bus_message *m) {
2549 m->iovec[m->n_iovec].iov_base = m->header;
2550 m->iovec[m->n_iovec].iov_len = sizeof(*m->header);
2551 m->size += m->iovec[m->n_iovec].iov_len;
2555 m->iovec[m->n_iovec].iov_base = m->fields;
2556 m->iovec[m->n_iovec].iov_len = m->header->fields_size;
2557 m->size += m->iovec[m->n_iovec].iov_len;
2560 if (m->header->fields_size % 8 != 0) {
2561 static const uint8_t padding[7] = { 0, 0, 0, 0, 0, 0, 0 };
2563 m->iovec[m->n_iovec].iov_base = (void*) padding;
2564 m->iovec[m->n_iovec].iov_len = 8 - m->header->fields_size % 8;
2565 m->size += m->iovec[m->n_iovec].iov_len;
2571 m->iovec[m->n_iovec].iov_base = m->body;
2572 m->iovec[m->n_iovec].iov_len = m->header->body_size;
2573 m->size += m->iovec[m->n_iovec].iov_len;
2578 int bus_message_seal(sd_bus_message *m, uint64_t serial) {
2586 if (m->n_containers > 0)
2589 /* If there's a non-trivial signature set, then add it in here */
2590 if (!isempty(m->root_container.signature)) {
2591 r = message_append_field_signature(m, SD_BUS_MESSAGE_HEADER_SIGNATURE, m->root_container.signature, NULL);
2597 r = message_append_field_uint32(m, SD_BUS_MESSAGE_HEADER_UNIX_FDS, m->n_fds);
2602 m->header->serial = serial;
2610 int sd_bus_message_set_destination(sd_bus_message *m, const char *destination) {
2620 return message_append_field_string(m, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &m->destination);
2623 int bus_message_dump(sd_bus_message *m) {
2629 printf("Message %p\n"
2636 "\tfields_size=%u\n"
2641 "\tdestination=%s\n"
2644 "\treply_serial=%u\n"
2646 "\terror.message=%s\n"
2654 BUS_MESSAGE_SERIAL(m),
2655 BUS_MESSAGE_FIELDS_SIZE(m),
2656 BUS_MESSAGE_BODY_SIZE(m),
2658 strna(m->interface),
2660 strna(m->destination),
2662 strna(m->root_container.signature),
2664 strna(m->error.name),
2665 strna(m->error.message),
2668 r = sd_bus_message_rewind(m, true);
2670 log_error("Failed to rewind: %s", strerror(-r));
2674 printf("BEGIN_MESSAGE \"%s\" {\n", strempty(m->root_container.signature));
2677 _cleanup_free_ char *prefix = NULL;
2678 const char *contents = NULL;
2693 r = sd_bus_message_peek_type(m, &type, &contents);
2695 log_error("Failed to peek type: %s", strerror(-r));
2702 r = sd_bus_message_exit_container(m);
2704 log_error("Failed to exit container: %s", strerror(-r));
2710 prefix = strrep("\t", level);
2714 if (type == SD_BUS_TYPE_ARRAY)
2715 printf("%s} END_ARRAY \n", prefix);
2716 else if (type == SD_BUS_TYPE_VARIANT)
2717 printf("%s} END_VARIANT\n", prefix);
2718 else if (type == SD_BUS_TYPE_STRUCT)
2719 printf("%s} END_STRUCT\n", prefix);
2720 else if (type == SD_BUS_TYPE_DICT_ENTRY)
2721 printf("%s} END_DICT_ENTRY\n", prefix);
2726 prefix = strrep("\t", level);
2730 if (bus_type_is_container(type) > 0) {
2731 r = sd_bus_message_enter_container(m, type, contents);
2733 log_error("Failed to enter container: %s", strerror(-r));
2737 if (type == SD_BUS_TYPE_ARRAY)
2738 printf("%sBEGIN_ARRAY \"%s\" {\n", prefix, contents);
2739 else if (type == SD_BUS_TYPE_VARIANT)
2740 printf("%sBEGIN_VARIANT \"%s\" {\n", prefix, contents);
2741 else if (type == SD_BUS_TYPE_STRUCT)
2742 printf("%sBEGIN_STRUCT \"%s\" {\n", prefix, contents);
2743 else if (type == SD_BUS_TYPE_DICT_ENTRY)
2744 printf("%sBEGIN_DICT_ENTRY \"%s\" {\n", prefix, contents);
2751 r = sd_bus_message_read_basic(m, type, &basic);
2753 log_error("Failed to get basic: %s", strerror(-r));
2759 case SD_BUS_TYPE_BYTE:
2760 printf("%sBYTE: %u\n", prefix, basic.u8);
2763 case SD_BUS_TYPE_BOOLEAN:
2764 printf("%sBOOLEAN: %s\n", prefix, yes_no(basic.i));
2767 case SD_BUS_TYPE_INT16:
2768 printf("%sINT16: %i\n", prefix, basic.s16);
2771 case SD_BUS_TYPE_UINT16:
2772 printf("%sUINT16: %u\n", prefix, basic.u16);
2775 case SD_BUS_TYPE_INT32:
2776 printf("%sINT32: %i\n", prefix, basic.s32);
2779 case SD_BUS_TYPE_UINT32:
2780 printf("%sUINT32: %u\n", prefix, basic.u32);
2783 case SD_BUS_TYPE_INT64:
2784 printf("%sINT64: %lli\n", prefix, (long long) basic.s64);
2787 case SD_BUS_TYPE_UINT64:
2788 printf("%sUINT64: %llu\n", prefix, (unsigned long long) basic.u64);
2791 case SD_BUS_TYPE_DOUBLE:
2792 printf("%sDOUBLE: %g\n", prefix, basic.d64);
2795 case SD_BUS_TYPE_STRING:
2796 printf("%sSTRING: \"%s\"\n", prefix, basic.string);
2799 case SD_BUS_TYPE_OBJECT_PATH:
2800 printf("%sOBJECT_PATH: \"%s\"\n", prefix, basic.string);
2803 case SD_BUS_TYPE_SIGNATURE:
2804 printf("%sSIGNATURE: \"%s\"\n", prefix, basic.string);
2807 case SD_BUS_TYPE_UNIX_FD:
2808 printf("%sUNIX_FD: %i\n", prefix, basic.i);
2812 assert_not_reached("Unknown basic type.");
2816 printf("} END_MESSAGE\n");
2820 int bus_message_get_blob(sd_bus_message *m, void **buffer, size_t *sz) {
2829 for (i = 0, total = 0; i < m->n_iovec; i++)
2830 total += m->iovec[i].iov_len;
2836 for (i = 0, e = p; i < m->n_iovec; i++)
2837 e = mempcpy(e, m->iovec[i].iov_base, m->iovec[i].iov_len);
2845 int bus_message_read_strv_extend(sd_bus_message *m, char ***l) {
2851 r = sd_bus_message_enter_container(m, 'a', "s");
2858 r = sd_bus_message_read_basic(m, 's', &s);
2864 r = strv_extend(l, s);
2869 r = sd_bus_message_exit_container(m);