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 "time-util.h"
31 #include "bus-message.h"
32 #include "bus-internal.h"
34 #include "bus-signature.h"
36 static int message_append_basic(sd_bus_message *m, char type, const void *p, const void **stored);
38 static void reset_containers(sd_bus_message *m) {
43 for (i = 0; i < m->n_containers; i++)
44 free(m->containers[i].signature);
50 m->root_container.index = 0;
53 static void message_free(sd_bus_message *m) {
69 close_many(m->fds, m->n_fds);
74 free(m->root_container.signature);
76 free(m->peeked_signature);
80 static void* buffer_extend(void **p, uint32_t *sz, size_t align, size_t extend) {
88 start = ALIGN_TO((size_t) *sz, align);
92 return (uint8_t*) *p + start;
94 if (n > (size_t) ((uint32_t) -1))
101 /* Zero out padding */
103 memset((uint8_t*) k + *sz, 0, start - *sz);
108 return (uint8_t*) k + start;
111 static void *message_extend_fields(sd_bus_message *m, size_t align, size_t sz) {
117 p = buffer_extend(&m->fields, &m->header->fields_size, align, sz);
121 if (o != m->fields) {
122 /* Adjust quick access pointers */
125 m->path = (const char*) m->fields + (m->path - (const char*) o);
127 m->interface = (const char*) m->fields + (m->interface - (const char*) o);
129 m->member = (const char*) m->fields + (m->member - (const char*) o);
131 m->destination = (const char*) m->fields + (m->destination - (const char*) o);
133 m->sender = (const char*) m->fields + (m->sender - (const char*) o);
135 m->error.name = (const char*) m->fields + (m->error.name - (const char*) o);
138 m->free_fields = true;
143 static int message_append_field_string(
156 if (l > (size_t) (uint32_t) -1)
159 /* field id byte + signature length + signature 's' + NUL + string length + string + NUL */
160 p = message_extend_fields(m, 8, 4 + 4 + l + 1);
169 ((uint32_t*) p)[1] = l;
170 memcpy(p + 8, s, l + 1);
173 *ret = (const char*) p + 8;
178 static int message_append_field_signature(
193 /* field id byte + signature length + signature 'g' + NUL + string length + string + NUL */
194 p = message_extend_fields(m, 8, 4 + 1 + l + 1);
200 p[2] = SD_BUS_TYPE_SIGNATURE;
203 memcpy(p + 5, s, l + 1);
206 *ret = (const char*) p + 5;
211 static int message_append_field_uint32(sd_bus_message *m, uint8_t h, uint32_t x) {
216 /* field id byte + signature length + signature 'u' + NUL + value */
217 p = message_extend_fields(m, 8, 4 + 4);
223 p[2] = SD_BUS_TYPE_UINT32;
226 ((uint32_t*) p)[1] = x;
231 int bus_message_from_header(
236 const struct ucred *ucred,
239 sd_bus_message **ret) {
242 struct bus_header *h;
245 assert(buffer || length <= 0);
246 assert(fds || n_fds <= 0);
249 if (length < sizeof(struct bus_header))
259 if (h->type == _SD_BUS_MESSAGE_TYPE_INVALID)
262 if (h->endian != SD_BUS_LITTLE_ENDIAN &&
263 h->endian != SD_BUS_BIG_ENDIAN)
266 a = ALIGN(sizeof(sd_bus_message)) + ALIGN(extra);
269 label_sz = strlen(label);
287 m->uid_valid = m->gid_valid = true;
291 m->label = (char*) m + ALIGN(sizeof(sd_bus_message)) + ALIGN(extra);
292 memcpy(m->label, label, label_sz + 1);
299 int bus_message_from_malloc(
304 const struct ucred *ucred,
306 sd_bus_message **ret) {
311 r = bus_message_from_header(buffer, length, fds, n_fds, ucred, label, 0, &m);
315 if (length != BUS_MESSAGE_SIZE(m)) {
320 m->fields = (uint8_t*) buffer + sizeof(struct bus_header);
321 m->body = (uint8_t*) buffer + sizeof(struct bus_header) + ALIGN8(BUS_MESSAGE_FIELDS_SIZE(m));
324 m->iovec[0].iov_base = buffer;
325 m->iovec[0].iov_len = length;
327 r = bus_message_parse_fields(m);
331 /* We take possession of the memory and fds now */
332 m->free_header = true;
343 static sd_bus_message *message_new(sd_bus *bus, uint8_t type) {
346 m = malloc0(ALIGN(sizeof(sd_bus_message)) + sizeof(struct bus_header));
351 m->header = (struct bus_header*) ((uint8_t*) m + ALIGN(sizeof(struct sd_bus_message)));
352 m->header->endian = SD_BUS_NATIVE_ENDIAN;
353 m->header->type = type;
354 m->header->version = bus ? bus->message_version : 1;
355 m->allow_fds = !bus || bus->can_fds || (bus->state != BUS_HELLO && bus->state != BUS_RUNNING);
360 int sd_bus_message_new_signal(
363 const char *interface,
365 sd_bus_message **m) {
378 if (bus && bus->state == BUS_UNSET)
381 t = message_new(bus, SD_BUS_MESSAGE_TYPE_SIGNAL);
385 t->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
387 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_PATH, SD_BUS_TYPE_OBJECT_PATH, path, &t->path);
390 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_INTERFACE, SD_BUS_TYPE_STRING, interface, &t->interface);
393 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_MEMBER, SD_BUS_TYPE_STRING, member, &t->member);
401 sd_bus_message_unref(t);
405 int sd_bus_message_new_method_call(
407 const char *destination,
409 const char *interface,
411 sd_bus_message **m) {
422 if (bus && bus->state == BUS_UNSET)
425 t = message_new(bus, SD_BUS_MESSAGE_TYPE_METHOD_CALL);
429 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_PATH, SD_BUS_TYPE_OBJECT_PATH, path, &t->path);
432 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_MEMBER, SD_BUS_TYPE_STRING, member, &t->member);
437 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_INTERFACE, SD_BUS_TYPE_STRING, interface, &t->interface);
443 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &t->destination);
456 static int message_new_reply(
458 sd_bus_message *call,
460 sd_bus_message **m) {
469 if (call->header->type != SD_BUS_MESSAGE_TYPE_METHOD_CALL)
473 if (bus && bus->state == BUS_UNSET)
476 t = message_new(bus, type);
480 t->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
481 t->reply_serial = BUS_MESSAGE_SERIAL(call);
483 r = message_append_field_uint32(t, SD_BUS_MESSAGE_HEADER_REPLY_SERIAL, t->reply_serial);
488 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, call->sender, &t->sender);
493 t->dont_send = !!(call->header->flags & SD_BUS_MESSAGE_NO_REPLY_EXPECTED);
503 int sd_bus_message_new_method_return(
505 sd_bus_message *call,
506 sd_bus_message **m) {
508 return message_new_reply(bus, call, SD_BUS_MESSAGE_TYPE_METHOD_RETURN, m);
511 int sd_bus_message_new_method_error(
513 sd_bus_message *call,
514 const sd_bus_error *e,
515 sd_bus_message **m) {
520 if (!sd_bus_error_is_set(e))
525 r = message_new_reply(bus, call, SD_BUS_MESSAGE_TYPE_METHOD_ERROR, &t);
529 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_ERROR_NAME, SD_BUS_TYPE_STRING, e->name, &t->error.name);
534 r = message_append_basic(t, SD_BUS_TYPE_STRING, e->message, (const void**) &t->error.message);
547 sd_bus_message* sd_bus_message_ref(sd_bus_message *m) {
551 assert(m->n_ref > 0);
557 sd_bus_message* sd_bus_message_unref(sd_bus_message *m) {
561 assert(m->n_ref > 0);
570 int sd_bus_message_get_type(sd_bus_message *m, uint8_t *type) {
576 *type = m->header->type;
580 int sd_bus_message_get_serial(sd_bus_message *m, uint64_t *serial) {
585 if (m->header->serial == 0)
588 *serial = BUS_MESSAGE_SERIAL(m);
592 int sd_bus_message_get_reply_serial(sd_bus_message *m, uint64_t *serial) {
597 if (m->reply_serial == 0)
600 *serial = m->reply_serial;
604 int sd_bus_message_get_no_reply(sd_bus_message *m) {
608 return m->header->type == SD_BUS_MESSAGE_TYPE_METHOD_CALL ? !!(m->header->flags & SD_BUS_MESSAGE_NO_REPLY_EXPECTED) : 0;
611 const char *sd_bus_message_get_path(sd_bus_message *m) {
618 const char *sd_bus_message_get_interface(sd_bus_message *m) {
625 const char *sd_bus_message_get_member(sd_bus_message *m) {
631 const char *sd_bus_message_get_destination(sd_bus_message *m) {
635 return m->destination;
638 const char *sd_bus_message_get_sender(sd_bus_message *m) {
645 const sd_bus_error *sd_bus_message_get_error(sd_bus_message *m) {
649 if (!sd_bus_error_is_set(&m->error))
655 int sd_bus_message_get_uid(sd_bus_message *m, uid_t *uid) {
665 int sd_bus_message_get_gid(sd_bus_message *m, gid_t *gid) {
675 int sd_bus_message_get_pid(sd_bus_message *m, pid_t *pid) {
685 int sd_bus_message_get_tid(sd_bus_message *m, pid_t *tid) {
695 int sd_bus_message_get_pid_starttime(sd_bus_message *m, uint64_t *usec) {
698 if (m->pid_starttime <= 0)
701 *usec = m->pid_starttime;
705 const char *sd_bus_message_get_label(sd_bus_message *m) {
712 int sd_bus_message_is_signal(sd_bus_message *m, const char *interface, const char *member) {
716 if (m->header->type != SD_BUS_MESSAGE_TYPE_SIGNAL)
719 if (interface && (!m->interface || !streq(m->interface, interface)))
722 if (member && (!m->member || !streq(m->member, member)))
728 int sd_bus_message_is_method_call(sd_bus_message *m, const char *interface, const char *member) {
732 if (m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_CALL)
735 if (interface && (!m->interface || !streq(m->interface, interface)))
738 if (member && (!m->member || !streq(m->member, member)))
744 int sd_bus_message_is_method_error(sd_bus_message *m, const char *name) {
748 if (m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_ERROR)
751 if (name && (!m->error.name || !streq(m->error.name, name)))
757 int sd_bus_message_set_no_reply(sd_bus_message *m, int b) {
762 if (m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_CALL)
766 m->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
768 m->header->flags &= ~SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
773 static struct bus_container *message_get_container(sd_bus_message *m) {
776 if (m->n_containers == 0)
777 return &m->root_container;
779 assert(m->containers);
780 return m->containers + m->n_containers - 1;
783 static void *message_extend_body(sd_bus_message *m, size_t align, size_t sz) {
786 struct bus_container *c;
792 added = m->header->body_size;
794 p = buffer_extend(&m->body, &m->header->body_size, align, sz);
798 added = m->header->body_size - added;
800 for (c = m->containers; c < m->containers + m->n_containers; c++)
802 c->array_size = (uint32_t*) ((uint8_t*) m->body + ((uint8_t*) c->array_size - (uint8_t*) o));
803 *c->array_size += added;
807 if (m->error.message)
808 m->error.message = (const char*) m->body + (m->error.message - (const char*) o);
816 int message_append_basic(sd_bus_message *m, char type, const void *p, const void **stored) {
817 struct bus_container *c;
832 if (!bus_type_is_basic(type))
835 c = message_get_container(m);
837 if (c->signature && c->signature[c->index]) {
838 /* Container signature is already set */
840 if (c->signature[c->index] != type)
843 /* Maybe we can append to the signature? But only if this is the top-level container*/
844 if (c->enclosing != 0)
847 e = strextend(&c->signature, CHAR_TO_STR(type), NULL);
854 case SD_BUS_TYPE_STRING:
855 case SD_BUS_TYPE_OBJECT_PATH:
858 sz = 4 + strlen(p) + 1;
861 case SD_BUS_TYPE_SIGNATURE:
864 sz = 1 + strlen(p) + 1;
867 case SD_BUS_TYPE_BOOLEAN:
870 assert_cc(sizeof(int) == sizeof(uint32_t));
876 case SD_BUS_TYPE_UNIX_FD: {
892 fd = fcntl(z, F_DUPFD_CLOEXEC, 3);
898 f = realloc(m->fds, sizeof(int) * (m->n_fds + 1));
912 align = bus_type_get_alignment(type);
913 sz = bus_type_get_size(type);
920 a = message_extend_body(m, align, sz);
926 if (type == SD_BUS_TYPE_STRING || type == SD_BUS_TYPE_OBJECT_PATH) {
927 *(uint32_t*) a = sz - 5;
928 memcpy((uint8_t*) a + 4, p, sz - 4);
931 *stored = (const uint8_t*) a + 4;
933 } else if (type == SD_BUS_TYPE_SIGNATURE) {
934 *(uint8_t*) a = sz - 1;
935 memcpy((uint8_t*) a + 1, p, sz - 1);
938 *stored = (const uint8_t*) a + 1;
939 } else if (type == SD_BUS_TYPE_UNIX_FD) {
940 *(uint32_t*) a = fdi;
954 if (c->enclosing != SD_BUS_TYPE_ARRAY)
960 /* Truncate extended signature again */
962 c->signature[c->index] = 0;
965 close_nointr_nofail(fd);
970 int sd_bus_message_append_basic(sd_bus_message *m, char type, const void *p) {
971 return message_append_basic(m, type, p, NULL);
974 static int bus_message_open_array(
976 struct bus_container *c,
977 const char *contents,
978 uint32_t **array_size) {
991 if (!signature_is_single(contents))
994 alignment = bus_type_get_alignment(contents[0]);
998 if (c->signature && c->signature[c->index]) {
1000 /* Verify the existing signature */
1002 if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
1005 if (!startswith(c->signature + c->index + 1, contents))
1008 nindex = c->index + 1 + strlen(contents);
1010 if (c->enclosing != 0)
1013 /* Extend the existing signature */
1015 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_ARRAY), contents, NULL);
1019 nindex = e - c->signature;
1022 saved = m->header->body_size;
1023 a = message_extend_body(m, 4, 4);
1025 /* Truncate extended signature again */
1027 c->signature[c->index] = 0;
1033 if (!message_extend_body(m, alignment, 0)) {
1034 /* Add alignment between size and first element */
1036 c->signature[c->index] = 0;
1038 m->header->body_size = saved;
1042 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1045 /* m->body might have changed so let's readjust a */
1046 a = (uint8_t*) m->body + ((uint8_t*) a - (uint8_t*) b);
1053 static int bus_message_open_variant(
1055 struct bus_container *c,
1056 const char *contents) {
1066 if (!signature_is_single(contents))
1069 if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
1072 if (c->signature && c->signature[c->index]) {
1074 if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
1078 if (c->enclosing != 0)
1081 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_VARIANT), NULL);
1086 l = strlen(contents);
1087 a = message_extend_body(m, 1, 1 + l + 1);
1089 /* Truncate extended signature again */
1091 c->signature[c->index] = 0;
1097 memcpy((uint8_t*) a + 1, contents, l + 1);
1099 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1105 static int bus_message_open_struct(
1107 struct bus_container *c,
1108 const char *contents) {
1117 if (!signature_is_valid(contents, false))
1120 if (c->signature && c->signature[c->index]) {
1123 l = strlen(contents);
1125 if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
1126 !startswith(c->signature + c->index + 1, contents) ||
1127 c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
1130 nindex = c->index + 1 + l + 1;
1132 if (c->enclosing != 0)
1135 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_BEGIN), contents, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_END), NULL);
1139 nindex = e - c->signature;
1142 /* Align contents to 8 byte boundary */
1143 if (!message_extend_body(m, 8, 0)) {
1145 c->signature[c->index] = 0;
1150 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1156 static int bus_message_open_dict_entry(
1158 struct bus_container *c,
1159 const char *contents) {
1167 if (!signature_is_pair(contents))
1170 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1173 if (c->signature && c->signature[c->index]) {
1176 l = strlen(contents);
1178 if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
1179 !startswith(c->signature + c->index + 1, contents) ||
1180 c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
1183 nindex = c->index + 1 + l + 1;
1187 /* Align contents to 8 byte boundary */
1188 if (!message_extend_body(m, 8, 0))
1191 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1197 int sd_bus_message_open_container(
1200 const char *contents) {
1202 struct bus_container *c, *w;
1203 uint32_t *array_size = NULL;
1214 /* Make sure we have space for one more container */
1215 w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
1220 c = message_get_container(m);
1222 signature = strdup(contents);
1226 if (type == SD_BUS_TYPE_ARRAY)
1227 r = bus_message_open_array(m, c, contents, &array_size);
1228 else if (type == SD_BUS_TYPE_VARIANT)
1229 r = bus_message_open_variant(m, c, contents);
1230 else if (type == SD_BUS_TYPE_STRUCT)
1231 r = bus_message_open_struct(m, c, contents);
1232 else if (type == SD_BUS_TYPE_DICT_ENTRY)
1233 r = bus_message_open_dict_entry(m, c, contents);
1242 /* OK, let's fill it in */
1243 w += m->n_containers++;
1244 w->enclosing = type;
1245 w->signature = signature;
1247 w->array_size = array_size;
1253 int sd_bus_message_close_container(sd_bus_message *m) {
1254 struct bus_container *c;
1260 if (m->n_containers <= 0)
1263 c = message_get_container(m);
1264 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1265 if (c->signature && c->signature[c->index] != 0)
1281 static int type_stack_push(TypeStack *stack, unsigned max, unsigned *i, const char *types, unsigned n_struct, unsigned n_array) {
1288 stack[*i].types = types;
1289 stack[*i].n_struct = n_struct;
1290 stack[*i].n_array = n_array;
1296 static int type_stack_pop(TypeStack *stack, unsigned max, unsigned *i, const char **types, unsigned *n_struct, unsigned *n_array) {
1307 *types = stack[*i].types;
1308 *n_struct = stack[*i].n_struct;
1309 *n_array = stack[*i].n_array;
1314 int bus_message_append_ap(
1319 unsigned n_array, n_struct;
1320 TypeStack stack[BUS_CONTAINER_DEPTH];
1321 unsigned stack_ptr = 0;
1329 n_array = (unsigned) -1;
1330 n_struct = strlen(types);
1335 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
1336 r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
1342 r = sd_bus_message_close_container(m);
1350 if (n_array != (unsigned) -1)
1359 case SD_BUS_TYPE_BYTE: {
1362 x = (uint8_t) va_arg(ap, int);
1363 r = sd_bus_message_append_basic(m, *t, &x);
1367 case SD_BUS_TYPE_BOOLEAN:
1368 case SD_BUS_TYPE_INT32:
1369 case SD_BUS_TYPE_UINT32:
1370 case SD_BUS_TYPE_UNIX_FD: {
1373 /* We assume a boolean is the same as int32_t */
1374 assert_cc(sizeof(int32_t) == sizeof(int));
1376 x = va_arg(ap, uint32_t);
1377 r = sd_bus_message_append_basic(m, *t, &x);
1381 case SD_BUS_TYPE_INT16:
1382 case SD_BUS_TYPE_UINT16: {
1385 x = (uint16_t) va_arg(ap, int);
1386 r = sd_bus_message_append_basic(m, *t, &x);
1390 case SD_BUS_TYPE_INT64:
1391 case SD_BUS_TYPE_UINT64:
1392 case SD_BUS_TYPE_DOUBLE: {
1395 x = va_arg(ap, uint64_t);
1396 r = sd_bus_message_append_basic(m, *t, &x);
1400 case SD_BUS_TYPE_STRING:
1401 case SD_BUS_TYPE_OBJECT_PATH:
1402 case SD_BUS_TYPE_SIGNATURE: {
1405 x = va_arg(ap, const char*);
1406 r = sd_bus_message_append_basic(m, *t, x);
1410 case SD_BUS_TYPE_ARRAY: {
1413 r = signature_element_length(t + 1, &k);
1419 memcpy(s, t + 1, k);
1422 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, s);
1427 if (n_array == (unsigned) -1) {
1432 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
1438 n_array = va_arg(ap, unsigned);
1443 case SD_BUS_TYPE_VARIANT: {
1446 s = va_arg(ap, const char*);
1450 r = sd_bus_message_open_container(m, SD_BUS_TYPE_VARIANT, s);
1454 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
1459 n_struct = strlen(s);
1460 n_array = (unsigned) -1;
1465 case SD_BUS_TYPE_STRUCT_BEGIN:
1466 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
1469 r = signature_element_length(t, &k);
1476 memcpy(s, t + 1, k - 2);
1479 r = sd_bus_message_open_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
1484 if (n_array == (unsigned) -1) {
1489 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
1495 n_array = (unsigned) -1;
1511 int sd_bus_message_append(sd_bus_message *m, const char *types, ...) {
1522 va_start(ap, types);
1523 r = bus_message_append_ap(m, types, ap);
1529 static int buffer_peek(const void *p, uint32_t sz, size_t *rindex, size_t align, size_t nbytes, void **r) {
1535 start = ALIGN_TO((size_t) *rindex, align);
1541 /* Verify that padding is 0 */
1542 for (k = *rindex; k < start; k++)
1543 if (((const uint8_t*) p)[k] != 0)
1547 *r = (uint8_t*) p + start;
1554 static bool message_end_of_array(sd_bus_message *m, size_t index) {
1555 struct bus_container *c;
1559 c = message_get_container(m);
1563 return index >= c->begin + BUS_MESSAGE_BSWAP32(m, *c->array_size);
1566 static int message_peek_body(sd_bus_message *m, size_t *rindex, size_t align, size_t nbytes, void **ret) {
1571 if (message_end_of_array(m, *rindex))
1574 return buffer_peek(m->body, BUS_MESSAGE_BODY_SIZE(m), rindex, align, nbytes, ret);
1577 static bool validate_nul(const char *s, size_t l) {
1579 /* Check for NUL chars in the string */
1580 if (memchr(s, 0, l))
1583 /* Check for NUL termination */
1590 static bool validate_string(const char *s, size_t l) {
1592 if (!validate_nul(s, l))
1595 /* Check if valid UTF8 */
1596 if (!utf8_is_valid(s))
1602 static bool validate_signature(const char *s, size_t l) {
1604 if (!validate_nul(s, l))
1607 /* Check if valid signature */
1608 if (!signature_is_valid(s, true))
1614 static bool validate_object_path(const char *s, size_t l) {
1616 if (!validate_nul(s, l))
1619 if (!object_path_is_valid(s))
1625 int sd_bus_message_read_basic(sd_bus_message *m, char type, void *p) {
1626 struct bus_container *c;
1634 if (!bus_type_is_basic(type))
1639 c = message_get_container(m);
1641 if (!c->signature || c->signature[c->index] == 0)
1644 if (c->signature[c->index] != type)
1649 case SD_BUS_TYPE_STRING:
1650 case SD_BUS_TYPE_OBJECT_PATH: {
1655 r = message_peek_body(m, &rindex, 4, 4, &q);
1659 l = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
1660 r = message_peek_body(m, &rindex, 1, l+1, &q);
1666 if (type == SD_BUS_TYPE_OBJECT_PATH) {
1667 if (!validate_object_path(q, l))
1670 if (!validate_string(q, l))
1675 *(const char**) p = q;
1679 case SD_BUS_TYPE_SIGNATURE: {
1684 r = message_peek_body(m, &rindex, 1, 1, &q);
1689 r = message_peek_body(m, &rindex, 1, l+1, &q);
1695 if (!validate_signature(q, l))
1699 *(const char**) p = q;
1707 align = bus_type_get_alignment(type);
1708 sz = bus_type_get_size(type);
1709 assert(align > 0 && sz > 0);
1712 r = message_peek_body(m, &rindex, align, sz, &q);
1718 case SD_BUS_TYPE_BYTE:
1719 *(uint8_t*) p = *(uint8_t*) q;
1722 case SD_BUS_TYPE_BOOLEAN:
1723 *(int*) p = !!*(uint32_t*) q;
1726 case SD_BUS_TYPE_INT16:
1727 case SD_BUS_TYPE_UINT16:
1728 *(uint16_t*) p = BUS_MESSAGE_BSWAP16(m, *(uint16_t*) q);
1731 case SD_BUS_TYPE_INT32:
1732 case SD_BUS_TYPE_UINT32:
1733 *(uint32_t*) p = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
1736 case SD_BUS_TYPE_INT64:
1737 case SD_BUS_TYPE_UINT64:
1738 case SD_BUS_TYPE_DOUBLE:
1739 *(uint64_t*) p = BUS_MESSAGE_BSWAP64(m, *(uint64_t*) q);
1742 case SD_BUS_TYPE_UNIX_FD: {
1745 j = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
1749 *(int*) p = m->fds[j];
1754 assert_not_reached("Unknown basic type...");
1763 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1769 static int bus_message_enter_array(
1771 struct bus_container *c,
1772 const char *contents,
1773 uint32_t **array_size) {
1784 if (!signature_is_single(contents))
1787 alignment = bus_type_get_alignment(contents[0]);
1791 if (!c->signature || c->signature[c->index] == 0)
1794 if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
1797 if (!startswith(c->signature + c->index + 1, contents))
1801 r = message_peek_body(m, &rindex, 4, 4, &q);
1805 if (BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q) > BUS_ARRAY_MAX_SIZE)
1808 r = message_peek_body(m, &rindex, alignment, 0, NULL);
1814 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1815 c->index += 1 + strlen(contents);
1819 *array_size = (uint32_t*) q;
1824 static int bus_message_enter_variant(
1826 struct bus_container *c,
1827 const char *contents) {
1838 if (!signature_is_single(contents))
1841 if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
1844 if (!c->signature || c->signature[c->index] == 0)
1847 if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
1851 r = message_peek_body(m, &rindex, 1, 1, &q);
1856 r = message_peek_body(m, &rindex, 1, l+1, &q);
1862 if (!validate_signature(q, l))
1865 if (!streq(q, contents))
1868 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1876 static int bus_message_enter_struct(
1878 struct bus_container *c,
1879 const char *contents) {
1888 if (!signature_is_valid(contents, false))
1891 if (!c->signature || c->signature[c->index] == 0)
1894 l = strlen(contents);
1896 if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
1897 !startswith(c->signature + c->index + 1, contents) ||
1898 c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
1901 r = message_peek_body(m, &m->rindex, 8, 0, NULL);
1905 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1906 c->index += 1 + l + 1;
1911 static int bus_message_enter_dict_entry(
1913 struct bus_container *c,
1914 const char *contents) {
1923 if (!signature_is_pair(contents))
1926 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1929 if (!c->signature || c->signature[c->index] == 0)
1932 l = strlen(contents);
1934 if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
1935 !startswith(c->signature + c->index + 1, contents) ||
1936 c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
1939 r = message_peek_body(m, &m->rindex, 8, 0, NULL);
1943 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1944 c->index += 1 + l + 1;
1949 int sd_bus_message_enter_container(sd_bus_message *m, char type, const char *contents) {
1950 struct bus_container *c, *w;
1951 uint32_t *array_size = NULL;
1963 * We enforce a global limit on container depth, that is much
1964 * higher than the 32 structs and 32 arrays the specification
1965 * mandates. This is simpler to implement for us, and we need
1966 * this only to ensure our container array doesn't grow
1967 * without bounds. We are happy to return any data from a
1968 * message as long as the data itself is valid, even if the
1969 * overall message might be not.
1971 * Note that the message signature is validated when
1972 * parsing the headers, and that validation does check the
1975 * Note that the specification defines no limits on the depth
1976 * of stacked variants, but we do.
1978 if (m->n_containers >= BUS_CONTAINER_DEPTH)
1981 w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
1986 c = message_get_container(m);
1988 if (!c->signature || c->signature[c->index] == 0)
1991 signature = strdup(contents);
1995 if (type == SD_BUS_TYPE_ARRAY)
1996 r = bus_message_enter_array(m, c, contents, &array_size);
1997 else if (type == SD_BUS_TYPE_VARIANT)
1998 r = bus_message_enter_variant(m, c, contents);
1999 else if (type == SD_BUS_TYPE_STRUCT)
2000 r = bus_message_enter_struct(m, c, contents);
2001 else if (type == SD_BUS_TYPE_DICT_ENTRY)
2002 r = bus_message_enter_dict_entry(m, c, contents);
2011 /* OK, let's fill it in */
2012 w += m->n_containers++;
2013 w->enclosing = type;
2014 w->signature = signature;
2016 w->array_size = array_size;
2017 w->begin = m->rindex;
2022 int sd_bus_message_exit_container(sd_bus_message *m) {
2023 struct bus_container *c;
2029 if (m->n_containers <= 0)
2032 c = message_get_container(m);
2033 if (c->enclosing == SD_BUS_TYPE_ARRAY) {
2036 l = BUS_MESSAGE_BSWAP32(m, *c->array_size);
2037 if (c->begin + l != m->rindex)
2041 if (c->signature && c->signature[c->index] != 0)
2051 int sd_bus_message_peek_type(sd_bus_message *m, char *type, const char **contents) {
2052 struct bus_container *c;
2060 c = message_get_container(m);
2062 if (!c->signature || c->signature[c->index] == 0)
2065 if (message_end_of_array(m, m->rindex))
2068 if (bus_type_is_basic(c->signature[c->index])) {
2072 *type = c->signature[c->index];
2076 if (c->signature[c->index] == SD_BUS_TYPE_ARRAY) {
2082 r = signature_element_length(c->signature+c->index+1, &l);
2088 sig = strndup(c->signature + c->index + 1, l);
2092 free(m->peeked_signature);
2093 m->peeked_signature = sig;
2099 *type = SD_BUS_TYPE_ARRAY;
2104 if (c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ||
2105 c->signature[c->index] == SD_BUS_TYPE_DICT_ENTRY_BEGIN) {
2111 r = signature_element_length(c->signature+c->index, &l);
2116 sig = strndup(c->signature + c->index + 1, l - 2);
2120 free(m->peeked_signature);
2121 m->peeked_signature = sig;
2127 *type = c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY;
2132 if (c->signature[c->index] == SD_BUS_TYPE_VARIANT) {
2138 r = message_peek_body(m, &rindex, 1, 1, &q);
2145 r = message_peek_body(m, &rindex, 1, l+1, &q);
2151 if (!validate_signature(q, l))
2158 *type = SD_BUS_TYPE_VARIANT;
2167 *type = c->enclosing;
2173 int sd_bus_message_rewind(sd_bus_message *m, int complete) {
2174 struct bus_container *c;
2182 reset_containers(m);
2184 m->root_container.index = 0;
2186 c = message_get_container(m);
2188 c = message_get_container(m);
2191 m->rindex = c->begin;
2194 return !isempty(c->signature);
2196 static int message_read_ap(
2201 unsigned n_array, n_struct;
2202 TypeStack stack[BUS_CONTAINER_DEPTH];
2203 unsigned stack_ptr = 0;
2211 /* Ideally, we'd just call ourselves recursively on every
2212 * complex type. However, the state of a va_list that is
2213 * passed to a function is undefined after that function
2214 * returns. This means we need to docode the va_list linearly
2215 * in a single stackframe. We hence implement our own
2216 * home-grown stack in an array. */
2218 n_array = (unsigned) -1;
2219 n_struct = strlen(types);
2224 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
2225 r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
2231 r = sd_bus_message_exit_container(m);
2239 if (n_array != (unsigned) -1)
2248 case SD_BUS_TYPE_BYTE:
2249 case SD_BUS_TYPE_BOOLEAN:
2250 case SD_BUS_TYPE_INT16:
2251 case SD_BUS_TYPE_UINT16:
2252 case SD_BUS_TYPE_INT32:
2253 case SD_BUS_TYPE_UINT32:
2254 case SD_BUS_TYPE_INT64:
2255 case SD_BUS_TYPE_UINT64:
2256 case SD_BUS_TYPE_DOUBLE:
2257 case SD_BUS_TYPE_STRING:
2258 case SD_BUS_TYPE_OBJECT_PATH:
2259 case SD_BUS_TYPE_SIGNATURE:
2260 case SD_BUS_TYPE_UNIX_FD: {
2263 p = va_arg(ap, void*);
2264 r = sd_bus_message_read_basic(m, *t, p);
2273 case SD_BUS_TYPE_ARRAY: {
2276 r = signature_element_length(t + 1, &k);
2282 memcpy(s, t + 1, k);
2285 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, s);
2292 if (n_array == (unsigned) -1) {
2297 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2303 n_array = va_arg(ap, unsigned);
2308 case SD_BUS_TYPE_VARIANT: {
2311 s = va_arg(ap, const char *);
2315 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, s);
2321 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2326 n_struct = strlen(s);
2327 n_array = (unsigned) -1;
2332 case SD_BUS_TYPE_STRUCT_BEGIN:
2333 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
2336 r = signature_element_length(t, &k);
2342 memcpy(s, t + 1, k - 2);
2345 r = sd_bus_message_enter_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
2352 if (n_array == (unsigned) -1) {
2357 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2363 n_array = (unsigned) -1;
2376 int sd_bus_message_read(sd_bus_message *m, const char *types, ...) {
2387 va_start(ap, types);
2388 r = message_read_ap(m, types, ap);
2394 static int message_peek_fields(
2405 return buffer_peek(m->fields, BUS_MESSAGE_FIELDS_SIZE(m), rindex, align, nbytes, ret);
2408 static int message_peek_field_uint32(
2419 r = message_peek_fields(m, ri, 4, 4, &q);
2424 *ret = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2429 static int message_peek_field_string(
2431 bool (*validate)(const char *p),
2442 r = message_peek_field_uint32(m, ri, &l);
2446 r = message_peek_fields(m, ri, 1, l+1, &q);
2451 if (!validate_nul(q, l))
2457 if (!validate_string(q, l))
2467 static int message_peek_field_signature(
2479 r = message_peek_fields(m, ri, 1, 1, &q);
2484 r = message_peek_fields(m, ri, 1, l+1, &q);
2488 if (!validate_signature(q, l))
2497 static int message_skip_fields(
2500 uint32_t array_size,
2501 const char **signature) {
2503 size_t original_index;
2510 original_index = *ri;
2516 if (array_size != (uint32_t) -1 &&
2517 array_size <= *ri - original_index)
2524 if (t == SD_BUS_TYPE_STRING) {
2526 r = message_peek_field_string(m, NULL, ri, NULL);
2532 } else if (t == SD_BUS_TYPE_OBJECT_PATH) {
2534 r = message_peek_field_string(m, object_path_is_valid, ri, NULL);
2540 } else if (t == SD_BUS_TYPE_SIGNATURE) {
2542 r = message_peek_field_signature(m, ri, NULL);
2548 } else if (bus_type_is_basic(t)) {
2551 align = bus_type_get_alignment(t);
2552 k = bus_type_get_size(t);
2553 assert(align > 0 && k > 0);
2555 r = message_peek_fields(m, ri, align, k, NULL);
2561 } else if (t == SD_BUS_TYPE_ARRAY) {
2563 r = signature_element_length(*signature+1, &l);
2573 strncpy(sig, *signature + 1, l-1);
2576 alignment = bus_type_get_alignment(sig[0]);
2580 r = message_peek_field_uint32(m, ri, &nas);
2583 if (nas > BUS_ARRAY_MAX_SIZE)
2586 r = message_peek_fields(m, ri, alignment, 0, NULL);
2590 r = message_skip_fields(m, ri, nas, (const char**) &s);
2595 (*signature) += 1 + l;
2597 } else if (t == SD_BUS_TYPE_VARIANT) {
2600 r = message_peek_field_signature(m, ri, &s);
2604 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
2610 } else if (t == SD_BUS_TYPE_STRUCT ||
2611 t == SD_BUS_TYPE_DICT_ENTRY) {
2613 r = signature_element_length(*signature, &l);
2620 strncpy(sig, *signature + 1, l-1);
2623 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
2634 int bus_message_parse_fields(sd_bus_message *m) {
2637 uint32_t unix_fds = 0;
2641 for (ri = 0; ri < BUS_MESSAGE_FIELDS_SIZE(m); ) {
2642 const char *signature;
2645 r = message_peek_fields(m, &ri, 8, 1, (void**) &header);
2649 r = message_peek_field_signature(m, &ri, &signature);
2654 case _SD_BUS_MESSAGE_HEADER_INVALID:
2657 case SD_BUS_MESSAGE_HEADER_PATH:
2662 if (!streq(signature, "o"))
2665 r = message_peek_field_string(m, object_path_is_valid, &ri, &m->path);
2668 case SD_BUS_MESSAGE_HEADER_INTERFACE:
2673 if (!streq(signature, "s"))
2676 r = message_peek_field_string(m, interface_name_is_valid, &ri, &m->interface);
2679 case SD_BUS_MESSAGE_HEADER_MEMBER:
2684 if (!streq(signature, "s"))
2687 r = message_peek_field_string(m, member_name_is_valid, &ri, &m->member);
2690 case SD_BUS_MESSAGE_HEADER_ERROR_NAME:
2695 if (!streq(signature, "s"))
2698 r = message_peek_field_string(m, error_name_is_valid, &ri, &m->error.name);
2701 case SD_BUS_MESSAGE_HEADER_DESTINATION:
2706 if (!streq(signature, "s"))
2709 r = message_peek_field_string(m, service_name_is_valid, &ri, &m->destination);
2712 case SD_BUS_MESSAGE_HEADER_SENDER:
2717 if (!streq(signature, "s"))
2720 r = message_peek_field_string(m, service_name_is_valid, &ri, &m->sender);
2724 case SD_BUS_MESSAGE_HEADER_SIGNATURE: {
2728 if (m->root_container.signature)
2731 if (!streq(signature, "g"))
2734 r = message_peek_field_signature(m, &ri, &s);
2742 free(m->root_container.signature);
2743 m->root_container.signature = c;
2747 case SD_BUS_MESSAGE_HEADER_REPLY_SERIAL:
2748 if (m->reply_serial != 0)
2751 if (!streq(signature, "u"))
2754 r = message_peek_field_uint32(m, &ri, &m->reply_serial);
2758 if (m->reply_serial == 0)
2763 case SD_BUS_MESSAGE_HEADER_UNIX_FDS:
2767 if (!streq(signature, "u"))
2770 r = message_peek_field_uint32(m, &ri, &unix_fds);
2780 r = message_skip_fields(m, &ri, (uint32_t) -1, (const char **) &signature);
2787 if (m->n_fds != unix_fds)
2790 if (isempty(m->root_container.signature) != (BUS_MESSAGE_BODY_SIZE(m) == 0))
2793 switch (m->header->type) {
2795 case SD_BUS_MESSAGE_TYPE_SIGNAL:
2796 if (!m->path || !m->interface || !m->member)
2800 case SD_BUS_MESSAGE_TYPE_METHOD_CALL:
2802 if (!m->path || !m->member)
2807 case SD_BUS_MESSAGE_TYPE_METHOD_RETURN:
2809 if (m->reply_serial == 0)
2813 case SD_BUS_MESSAGE_TYPE_METHOD_ERROR:
2815 if (m->reply_serial == 0 || !m->error.name)
2820 /* Try to read the error message, but if we can't it's a non-issue */
2821 if (m->header->type == SD_BUS_MESSAGE_TYPE_METHOD_ERROR)
2822 sd_bus_message_read(m, "s", &m->error.message);
2827 int bus_message_seal(sd_bus_message *m, uint64_t serial) {
2835 if (m->n_containers > 0)
2838 /* If there's a non-trivial signature set, then add it in here */
2839 if (!isempty(m->root_container.signature)) {
2840 r = message_append_field_signature(m, SD_BUS_MESSAGE_HEADER_SIGNATURE, m->root_container.signature, NULL);
2846 r = message_append_field_uint32(m, SD_BUS_MESSAGE_HEADER_UNIX_FDS, m->n_fds);
2851 m->header->serial = serial;
2857 int sd_bus_message_set_destination(sd_bus_message *m, const char *destination) {
2867 return message_append_field_string(m, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &m->destination);
2870 int bus_message_dump(sd_bus_message *m) {
2876 printf("Message %p\n"
2883 "\tfields_size=%u\n"
2888 "\tdestination=%s\n"
2891 "\treply_serial=%u\n"
2893 "\terror.message=%s\n"
2901 BUS_MESSAGE_SERIAL(m),
2902 BUS_MESSAGE_FIELDS_SIZE(m),
2903 BUS_MESSAGE_BODY_SIZE(m),
2905 strna(m->interface),
2907 strna(m->destination),
2909 strna(m->root_container.signature),
2911 strna(m->error.name),
2912 strna(m->error.message),
2916 printf("\tpid=%lu\n", (unsigned long) m->pid);
2918 printf("\ttid=%lu\n", (unsigned long) m->tid);
2920 printf("\tuid=%lu\n", (unsigned long) m->uid);
2922 printf("\tgid=%lu\n", (unsigned long) m->gid);
2923 if (m->pid_starttime != 0)
2924 printf("\tpid_starttime=%llu\n", (unsigned long long) m->pid_starttime);
2926 r = sd_bus_message_rewind(m, true);
2928 log_error("Failed to rewind: %s", strerror(-r));
2932 printf("BEGIN_MESSAGE \"%s\" {\n", strempty(m->root_container.signature));
2935 _cleanup_free_ char *prefix = NULL;
2936 const char *contents = NULL;
2951 r = sd_bus_message_peek_type(m, &type, &contents);
2953 log_error("Failed to peek type: %s", strerror(-r));
2960 r = sd_bus_message_exit_container(m);
2962 log_error("Failed to exit container: %s", strerror(-r));
2968 prefix = strrep("\t", level);
2972 if (type == SD_BUS_TYPE_ARRAY)
2973 printf("%s} END_ARRAY \n", prefix);
2974 else if (type == SD_BUS_TYPE_VARIANT)
2975 printf("%s} END_VARIANT\n", prefix);
2976 else if (type == SD_BUS_TYPE_STRUCT)
2977 printf("%s} END_STRUCT\n", prefix);
2978 else if (type == SD_BUS_TYPE_DICT_ENTRY)
2979 printf("%s} END_DICT_ENTRY\n", prefix);
2984 prefix = strrep("\t", level);
2988 if (bus_type_is_container(type) > 0) {
2989 r = sd_bus_message_enter_container(m, type, contents);
2991 log_error("Failed to enter container: %s", strerror(-r));
2995 if (type == SD_BUS_TYPE_ARRAY)
2996 printf("%sBEGIN_ARRAY \"%s\" {\n", prefix, contents);
2997 else if (type == SD_BUS_TYPE_VARIANT)
2998 printf("%sBEGIN_VARIANT \"%s\" {\n", prefix, contents);
2999 else if (type == SD_BUS_TYPE_STRUCT)
3000 printf("%sBEGIN_STRUCT \"%s\" {\n", prefix, contents);
3001 else if (type == SD_BUS_TYPE_DICT_ENTRY)
3002 printf("%sBEGIN_DICT_ENTRY \"%s\" {\n", prefix, contents);
3009 r = sd_bus_message_read_basic(m, type, &basic);
3011 log_error("Failed to get basic: %s", strerror(-r));
3017 case SD_BUS_TYPE_BYTE:
3018 printf("%sBYTE: %u\n", prefix, basic.u8);
3021 case SD_BUS_TYPE_BOOLEAN:
3022 printf("%sBOOLEAN: %s\n", prefix, yes_no(basic.i));
3025 case SD_BUS_TYPE_INT16:
3026 printf("%sINT16: %i\n", prefix, basic.s16);
3029 case SD_BUS_TYPE_UINT16:
3030 printf("%sUINT16: %u\n", prefix, basic.u16);
3033 case SD_BUS_TYPE_INT32:
3034 printf("%sINT32: %i\n", prefix, basic.s32);
3037 case SD_BUS_TYPE_UINT32:
3038 printf("%sUINT32: %u\n", prefix, basic.u32);
3041 case SD_BUS_TYPE_INT64:
3042 printf("%sINT64: %lli\n", prefix, (long long) basic.s64);
3045 case SD_BUS_TYPE_UINT64:
3046 printf("%sUINT64: %llu\n", prefix, (unsigned long long) basic.u64);
3049 case SD_BUS_TYPE_DOUBLE:
3050 printf("%sDOUBLE: %g\n", prefix, basic.d64);
3053 case SD_BUS_TYPE_STRING:
3054 printf("%sSTRING: \"%s\"\n", prefix, basic.string);
3057 case SD_BUS_TYPE_OBJECT_PATH:
3058 printf("%sOBJECT_PATH: \"%s\"\n", prefix, basic.string);
3061 case SD_BUS_TYPE_SIGNATURE:
3062 printf("%sSIGNATURE: \"%s\"\n", prefix, basic.string);
3065 case SD_BUS_TYPE_UNIX_FD:
3066 printf("%sUNIX_FD: %i\n", prefix, basic.i);
3070 assert_not_reached("Unknown basic type.");
3074 printf("} END_MESSAGE\n");
3078 int bus_message_get_blob(sd_bus_message *m, void **buffer, size_t *sz) {
3086 total = BUS_MESSAGE_SIZE(m);
3092 e = mempcpy(p, m->header, sizeof(*m->header));
3095 e = mempcpy(e, m->fields, m->header->fields_size);
3097 if (m->header->fields_size % 8 != 0)
3098 e = mempset(e, 0, 8 - (m->header->fields_size % 8));
3102 e = mempcpy(e, m->body, m->header->body_size);
3104 assert(total == (size_t) ((uint8_t*) e - (uint8_t*) p));
3112 int bus_message_read_strv_extend(sd_bus_message *m, char ***l) {
3118 r = sd_bus_message_enter_container(m, 'a', "s");
3125 r = sd_bus_message_read_basic(m, 's', &s);
3131 r = strv_extend(l, s);
3136 r = sd_bus_message_exit_container(m);
3143 const char* bus_message_get_arg(sd_bus_message *m, unsigned i) {
3150 r = sd_bus_message_rewind(m, true);
3155 r = sd_bus_message_peek_type(m, &type, NULL);
3159 if (type != SD_BUS_TYPE_STRING &&
3160 type != SD_BUS_TYPE_OBJECT_PATH &&
3161 type != SD_BUS_TYPE_SIGNATURE)
3164 r = sd_bus_message_read_basic(m, type, &t);
3171 r = sd_bus_message_rewind(m, true);
3178 int bus_header_size(struct bus_header *h, size_t *sum) {
3184 if (h->endian == SD_BUS_NATIVE_ENDIAN) {
3185 fs = h->fields_size;
3187 } else if (h->endian == SD_BUS_REVERSE_ENDIAN) {
3188 fs = bswap_32(h->fields_size);
3189 bs = bswap_32(h->body_size);
3193 *sum = sizeof(struct bus_header) + ALIGN8(fs) + bs;