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 const char *sd_bus_message_get_label(sd_bus_message *m) {
702 int sd_bus_message_is_signal(sd_bus_message *m, const char *interface, const char *member) {
706 if (m->header->type != SD_BUS_MESSAGE_TYPE_SIGNAL)
709 if (interface && (!m->interface || !streq(m->interface, interface)))
712 if (member && (!m->member || !streq(m->member, member)))
718 int sd_bus_message_is_method_call(sd_bus_message *m, const char *interface, const char *member) {
722 if (m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_CALL)
725 if (interface && (!m->interface || !streq(m->interface, interface)))
728 if (member && (!m->member || !streq(m->member, member)))
734 int sd_bus_message_is_method_error(sd_bus_message *m, const char *name) {
738 if (m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_ERROR)
741 if (name && (!m->error.name || !streq(m->error.name, name)))
747 int sd_bus_message_set_no_reply(sd_bus_message *m, int b) {
752 if (m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_CALL)
756 m->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
758 m->header->flags &= ~SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
763 static struct bus_container *message_get_container(sd_bus_message *m) {
766 if (m->n_containers == 0)
767 return &m->root_container;
769 assert(m->containers);
770 return m->containers + m->n_containers - 1;
773 static void *message_extend_body(sd_bus_message *m, size_t align, size_t sz) {
776 struct bus_container *c;
782 added = m->header->body_size;
784 p = buffer_extend(&m->body, &m->header->body_size, align, sz);
788 added = m->header->body_size - added;
790 for (c = m->containers; c < m->containers + m->n_containers; c++)
792 c->array_size = (uint32_t*) ((uint8_t*) m->body + ((uint8_t*) c->array_size - (uint8_t*) o));
793 *c->array_size += added;
797 if (m->error.message)
798 m->error.message = (const char*) m->body + (m->error.message - (const char*) o);
806 int message_append_basic(sd_bus_message *m, char type, const void *p, const void **stored) {
807 struct bus_container *c;
822 if (!bus_type_is_basic(type))
825 c = message_get_container(m);
827 if (c->signature && c->signature[c->index]) {
828 /* Container signature is already set */
830 if (c->signature[c->index] != type)
833 /* Maybe we can append to the signature? But only if this is the top-level container*/
834 if (c->enclosing != 0)
837 e = strextend(&c->signature, CHAR_TO_STR(type), NULL);
844 case SD_BUS_TYPE_STRING:
845 case SD_BUS_TYPE_OBJECT_PATH:
848 sz = 4 + strlen(p) + 1;
851 case SD_BUS_TYPE_SIGNATURE:
854 sz = 1 + strlen(p) + 1;
857 case SD_BUS_TYPE_BOOLEAN:
860 assert_cc(sizeof(int) == sizeof(uint32_t));
866 case SD_BUS_TYPE_UNIX_FD: {
882 fd = fcntl(z, F_DUPFD_CLOEXEC, 3);
888 f = realloc(m->fds, sizeof(int) * (m->n_fds + 1));
902 align = bus_type_get_alignment(type);
903 sz = bus_type_get_size(type);
910 a = message_extend_body(m, align, sz);
916 if (type == SD_BUS_TYPE_STRING || type == SD_BUS_TYPE_OBJECT_PATH) {
917 *(uint32_t*) a = sz - 5;
918 memcpy((uint8_t*) a + 4, p, sz - 4);
921 *stored = (const uint8_t*) a + 4;
923 } else if (type == SD_BUS_TYPE_SIGNATURE) {
924 *(uint8_t*) a = sz - 1;
925 memcpy((uint8_t*) a + 1, p, sz - 1);
928 *stored = (const uint8_t*) a + 1;
929 } else if (type == SD_BUS_TYPE_UNIX_FD) {
930 *(uint32_t*) a = fdi;
944 if (c->enclosing != SD_BUS_TYPE_ARRAY)
950 /* Truncate extended signature again */
952 c->signature[c->index] = 0;
955 close_nointr_nofail(fd);
960 int sd_bus_message_append_basic(sd_bus_message *m, char type, const void *p) {
961 return message_append_basic(m, type, p, NULL);
964 static int bus_message_open_array(
966 struct bus_container *c,
967 const char *contents,
968 uint32_t **array_size) {
981 if (!signature_is_single(contents))
984 alignment = bus_type_get_alignment(contents[0]);
988 if (c->signature && c->signature[c->index]) {
990 /* Verify the existing signature */
992 if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
995 if (!startswith(c->signature + c->index + 1, contents))
998 nindex = c->index + 1 + strlen(contents);
1000 if (c->enclosing != 0)
1003 /* Extend the existing signature */
1005 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_ARRAY), contents, NULL);
1009 nindex = e - c->signature;
1012 saved = m->header->body_size;
1013 a = message_extend_body(m, 4, 4);
1015 /* Truncate extended signature again */
1017 c->signature[c->index] = 0;
1023 if (!message_extend_body(m, alignment, 0)) {
1024 /* Add alignment between size and first element */
1026 c->signature[c->index] = 0;
1028 m->header->body_size = saved;
1032 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1035 /* m->body might have changed so let's readjust a */
1036 a = (uint8_t*) m->body + ((uint8_t*) a - (uint8_t*) b);
1043 static int bus_message_open_variant(
1045 struct bus_container *c,
1046 const char *contents) {
1056 if (!signature_is_single(contents))
1059 if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
1062 if (c->signature && c->signature[c->index]) {
1064 if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
1068 if (c->enclosing != 0)
1071 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_VARIANT), NULL);
1076 l = strlen(contents);
1077 a = message_extend_body(m, 1, 1 + l + 1);
1079 /* Truncate extended signature again */
1081 c->signature[c->index] = 0;
1087 memcpy((uint8_t*) a + 1, contents, l + 1);
1089 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1095 static int bus_message_open_struct(
1097 struct bus_container *c,
1098 const char *contents) {
1107 if (!signature_is_valid(contents, false))
1110 if (c->signature && c->signature[c->index]) {
1113 l = strlen(contents);
1115 if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
1116 !startswith(c->signature + c->index + 1, contents) ||
1117 c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
1120 nindex = c->index + 1 + l + 1;
1122 if (c->enclosing != 0)
1125 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_BEGIN), contents, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_END), NULL);
1129 nindex = e - c->signature;
1132 /* Align contents to 8 byte boundary */
1133 if (!message_extend_body(m, 8, 0)) {
1135 c->signature[c->index] = 0;
1140 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1146 static int bus_message_open_dict_entry(
1148 struct bus_container *c,
1149 const char *contents) {
1157 if (!signature_is_pair(contents))
1160 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1163 if (c->signature && c->signature[c->index]) {
1166 l = strlen(contents);
1168 if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
1169 !startswith(c->signature + c->index + 1, contents) ||
1170 c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
1173 nindex = c->index + 1 + l + 1;
1177 /* Align contents to 8 byte boundary */
1178 if (!message_extend_body(m, 8, 0))
1181 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1187 int sd_bus_message_open_container(
1190 const char *contents) {
1192 struct bus_container *c, *w;
1193 uint32_t *array_size = NULL;
1204 /* Make sure we have space for one more container */
1205 w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
1210 c = message_get_container(m);
1212 signature = strdup(contents);
1216 if (type == SD_BUS_TYPE_ARRAY)
1217 r = bus_message_open_array(m, c, contents, &array_size);
1218 else if (type == SD_BUS_TYPE_VARIANT)
1219 r = bus_message_open_variant(m, c, contents);
1220 else if (type == SD_BUS_TYPE_STRUCT)
1221 r = bus_message_open_struct(m, c, contents);
1222 else if (type == SD_BUS_TYPE_DICT_ENTRY)
1223 r = bus_message_open_dict_entry(m, c, contents);
1232 /* OK, let's fill it in */
1233 w += m->n_containers++;
1234 w->enclosing = type;
1235 w->signature = signature;
1237 w->array_size = array_size;
1243 int sd_bus_message_close_container(sd_bus_message *m) {
1244 struct bus_container *c;
1250 if (m->n_containers <= 0)
1253 c = message_get_container(m);
1254 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1255 if (c->signature && c->signature[c->index] != 0)
1271 static int type_stack_push(TypeStack *stack, unsigned max, unsigned *i, const char *types, unsigned n_struct, unsigned n_array) {
1278 stack[*i].types = types;
1279 stack[*i].n_struct = n_struct;
1280 stack[*i].n_array = n_array;
1286 static int type_stack_pop(TypeStack *stack, unsigned max, unsigned *i, const char **types, unsigned *n_struct, unsigned *n_array) {
1297 *types = stack[*i].types;
1298 *n_struct = stack[*i].n_struct;
1299 *n_array = stack[*i].n_array;
1304 int bus_message_append_ap(
1309 unsigned n_array, n_struct;
1310 TypeStack stack[BUS_CONTAINER_DEPTH];
1311 unsigned stack_ptr = 0;
1319 n_array = (unsigned) -1;
1320 n_struct = strlen(types);
1325 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
1326 r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
1332 r = sd_bus_message_close_container(m);
1340 if (n_array != (unsigned) -1)
1349 case SD_BUS_TYPE_BYTE: {
1352 x = (uint8_t) va_arg(ap, int);
1353 r = sd_bus_message_append_basic(m, *t, &x);
1357 case SD_BUS_TYPE_BOOLEAN:
1358 case SD_BUS_TYPE_INT32:
1359 case SD_BUS_TYPE_UINT32:
1360 case SD_BUS_TYPE_UNIX_FD: {
1363 /* We assume a boolean is the same as int32_t */
1364 assert_cc(sizeof(int32_t) == sizeof(int));
1366 x = va_arg(ap, uint32_t);
1367 r = sd_bus_message_append_basic(m, *t, &x);
1371 case SD_BUS_TYPE_INT16:
1372 case SD_BUS_TYPE_UINT16: {
1375 x = (uint16_t) va_arg(ap, int);
1376 r = sd_bus_message_append_basic(m, *t, &x);
1380 case SD_BUS_TYPE_INT64:
1381 case SD_BUS_TYPE_UINT64:
1382 case SD_BUS_TYPE_DOUBLE: {
1385 x = va_arg(ap, uint64_t);
1386 r = sd_bus_message_append_basic(m, *t, &x);
1390 case SD_BUS_TYPE_STRING:
1391 case SD_BUS_TYPE_OBJECT_PATH:
1392 case SD_BUS_TYPE_SIGNATURE: {
1395 x = va_arg(ap, const char*);
1396 r = sd_bus_message_append_basic(m, *t, x);
1400 case SD_BUS_TYPE_ARRAY: {
1403 r = signature_element_length(t + 1, &k);
1409 memcpy(s, t + 1, k);
1412 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, s);
1417 if (n_array == (unsigned) -1) {
1422 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
1428 n_array = va_arg(ap, unsigned);
1433 case SD_BUS_TYPE_VARIANT: {
1436 s = va_arg(ap, const char*);
1440 r = sd_bus_message_open_container(m, SD_BUS_TYPE_VARIANT, s);
1444 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
1449 n_struct = strlen(s);
1450 n_array = (unsigned) -1;
1455 case SD_BUS_TYPE_STRUCT_BEGIN:
1456 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
1459 r = signature_element_length(t, &k);
1466 memcpy(s, t + 1, k - 2);
1469 r = sd_bus_message_open_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
1474 if (n_array == (unsigned) -1) {
1479 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
1485 n_array = (unsigned) -1;
1501 int sd_bus_message_append(sd_bus_message *m, const char *types, ...) {
1512 va_start(ap, types);
1513 r = bus_message_append_ap(m, types, ap);
1519 static int buffer_peek(const void *p, uint32_t sz, size_t *rindex, size_t align, size_t nbytes, void **r) {
1525 start = ALIGN_TO((size_t) *rindex, align);
1531 /* Verify that padding is 0 */
1532 for (k = *rindex; k < start; k++)
1533 if (((const uint8_t*) p)[k] != 0)
1537 *r = (uint8_t*) p + start;
1544 static bool message_end_of_array(sd_bus_message *m, size_t index) {
1545 struct bus_container *c;
1549 c = message_get_container(m);
1553 return index >= c->begin + BUS_MESSAGE_BSWAP32(m, *c->array_size);
1556 static int message_peek_body(sd_bus_message *m, size_t *rindex, size_t align, size_t nbytes, void **ret) {
1561 if (message_end_of_array(m, *rindex))
1564 return buffer_peek(m->body, BUS_MESSAGE_BODY_SIZE(m), rindex, align, nbytes, ret);
1567 static bool validate_nul(const char *s, size_t l) {
1569 /* Check for NUL chars in the string */
1570 if (memchr(s, 0, l))
1573 /* Check for NUL termination */
1580 static bool validate_string(const char *s, size_t l) {
1582 if (!validate_nul(s, l))
1585 /* Check if valid UTF8 */
1586 if (!utf8_is_valid(s))
1592 static bool validate_signature(const char *s, size_t l) {
1594 if (!validate_nul(s, l))
1597 /* Check if valid signature */
1598 if (!signature_is_valid(s, true))
1604 static bool validate_object_path(const char *s, size_t l) {
1606 if (!validate_nul(s, l))
1609 if (!object_path_is_valid(s))
1615 int sd_bus_message_read_basic(sd_bus_message *m, char type, void *p) {
1616 struct bus_container *c;
1624 if (!bus_type_is_basic(type))
1629 c = message_get_container(m);
1631 if (!c->signature || c->signature[c->index] == 0)
1634 if (c->signature[c->index] != type)
1639 case SD_BUS_TYPE_STRING:
1640 case SD_BUS_TYPE_OBJECT_PATH: {
1645 r = message_peek_body(m, &rindex, 4, 4, &q);
1649 l = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
1650 r = message_peek_body(m, &rindex, 1, l+1, &q);
1656 if (type == SD_BUS_TYPE_OBJECT_PATH) {
1657 if (!validate_object_path(q, l))
1660 if (!validate_string(q, l))
1665 *(const char**) p = q;
1669 case SD_BUS_TYPE_SIGNATURE: {
1674 r = message_peek_body(m, &rindex, 1, 1, &q);
1679 r = message_peek_body(m, &rindex, 1, l+1, &q);
1685 if (!validate_signature(q, l))
1689 *(const char**) p = q;
1697 align = bus_type_get_alignment(type);
1698 sz = bus_type_get_size(type);
1699 assert(align > 0 && sz > 0);
1702 r = message_peek_body(m, &rindex, align, sz, &q);
1708 case SD_BUS_TYPE_BYTE:
1709 *(uint8_t*) p = *(uint8_t*) q;
1712 case SD_BUS_TYPE_BOOLEAN:
1713 *(int*) p = !!*(uint32_t*) q;
1716 case SD_BUS_TYPE_INT16:
1717 case SD_BUS_TYPE_UINT16:
1718 *(uint16_t*) p = BUS_MESSAGE_BSWAP16(m, *(uint16_t*) q);
1721 case SD_BUS_TYPE_INT32:
1722 case SD_BUS_TYPE_UINT32:
1723 *(uint32_t*) p = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
1726 case SD_BUS_TYPE_INT64:
1727 case SD_BUS_TYPE_UINT64:
1728 case SD_BUS_TYPE_DOUBLE:
1729 *(uint64_t*) p = BUS_MESSAGE_BSWAP64(m, *(uint64_t*) q);
1732 case SD_BUS_TYPE_UNIX_FD: {
1735 j = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
1739 *(int*) p = m->fds[j];
1744 assert_not_reached("Unknown basic type...");
1753 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1759 static int bus_message_enter_array(
1761 struct bus_container *c,
1762 const char *contents,
1763 uint32_t **array_size) {
1774 if (!signature_is_single(contents))
1777 alignment = bus_type_get_alignment(contents[0]);
1781 if (!c->signature || c->signature[c->index] == 0)
1784 if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
1787 if (!startswith(c->signature + c->index + 1, contents))
1791 r = message_peek_body(m, &rindex, 4, 4, &q);
1795 if (BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q) > BUS_ARRAY_MAX_SIZE)
1798 r = message_peek_body(m, &rindex, alignment, 0, NULL);
1804 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1805 c->index += 1 + strlen(contents);
1809 *array_size = (uint32_t*) q;
1814 static int bus_message_enter_variant(
1816 struct bus_container *c,
1817 const char *contents) {
1828 if (!signature_is_single(contents))
1831 if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
1834 if (!c->signature || c->signature[c->index] == 0)
1837 if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
1841 r = message_peek_body(m, &rindex, 1, 1, &q);
1846 r = message_peek_body(m, &rindex, 1, l+1, &q);
1852 if (!validate_signature(q, l))
1855 if (!streq(q, contents))
1858 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1866 static int bus_message_enter_struct(
1868 struct bus_container *c,
1869 const char *contents) {
1878 if (!signature_is_valid(contents, false))
1881 if (!c->signature || c->signature[c->index] == 0)
1884 l = strlen(contents);
1886 if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
1887 !startswith(c->signature + c->index + 1, contents) ||
1888 c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
1891 r = message_peek_body(m, &m->rindex, 8, 0, NULL);
1895 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1896 c->index += 1 + l + 1;
1901 static int bus_message_enter_dict_entry(
1903 struct bus_container *c,
1904 const char *contents) {
1913 if (!signature_is_pair(contents))
1916 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1919 if (!c->signature || c->signature[c->index] == 0)
1922 l = strlen(contents);
1924 if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
1925 !startswith(c->signature + c->index + 1, contents) ||
1926 c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
1929 r = message_peek_body(m, &m->rindex, 8, 0, NULL);
1933 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1934 c->index += 1 + l + 1;
1939 int sd_bus_message_enter_container(sd_bus_message *m, char type, const char *contents) {
1940 struct bus_container *c, *w;
1941 uint32_t *array_size = NULL;
1953 * We enforce a global limit on container depth, that is much
1954 * higher than the 32 structs and 32 arrays the specification
1955 * mandates. This is simpler to implement for us, and we need
1956 * this only to ensure our container array doesn't grow
1957 * without bounds. We are happy to return any data from a
1958 * message as long as the data itself is valid, even if the
1959 * overall message might be not.
1961 * Note that the message signature is validated when
1962 * parsing the headers, and that validation does check the
1965 * Note that the specification defines no limits on the depth
1966 * of stacked variants, but we do.
1968 if (m->n_containers >= BUS_CONTAINER_DEPTH)
1971 w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
1976 c = message_get_container(m);
1978 if (!c->signature || c->signature[c->index] == 0)
1981 signature = strdup(contents);
1985 if (type == SD_BUS_TYPE_ARRAY)
1986 r = bus_message_enter_array(m, c, contents, &array_size);
1987 else if (type == SD_BUS_TYPE_VARIANT)
1988 r = bus_message_enter_variant(m, c, contents);
1989 else if (type == SD_BUS_TYPE_STRUCT)
1990 r = bus_message_enter_struct(m, c, contents);
1991 else if (type == SD_BUS_TYPE_DICT_ENTRY)
1992 r = bus_message_enter_dict_entry(m, c, contents);
2001 /* OK, let's fill it in */
2002 w += m->n_containers++;
2003 w->enclosing = type;
2004 w->signature = signature;
2006 w->array_size = array_size;
2007 w->begin = m->rindex;
2012 int sd_bus_message_exit_container(sd_bus_message *m) {
2013 struct bus_container *c;
2019 if (m->n_containers <= 0)
2022 c = message_get_container(m);
2023 if (c->enclosing == SD_BUS_TYPE_ARRAY) {
2026 l = BUS_MESSAGE_BSWAP32(m, *c->array_size);
2027 if (c->begin + l != m->rindex)
2031 if (c->signature && c->signature[c->index] != 0)
2041 int sd_bus_message_peek_type(sd_bus_message *m, char *type, const char **contents) {
2042 struct bus_container *c;
2050 c = message_get_container(m);
2052 if (!c->signature || c->signature[c->index] == 0)
2055 if (message_end_of_array(m, m->rindex))
2058 if (bus_type_is_basic(c->signature[c->index])) {
2062 *type = c->signature[c->index];
2066 if (c->signature[c->index] == SD_BUS_TYPE_ARRAY) {
2072 r = signature_element_length(c->signature+c->index+1, &l);
2078 sig = strndup(c->signature + c->index + 1, l);
2082 free(m->peeked_signature);
2083 m->peeked_signature = sig;
2089 *type = SD_BUS_TYPE_ARRAY;
2094 if (c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ||
2095 c->signature[c->index] == SD_BUS_TYPE_DICT_ENTRY_BEGIN) {
2101 r = signature_element_length(c->signature+c->index, &l);
2106 sig = strndup(c->signature + c->index + 1, l - 2);
2110 free(m->peeked_signature);
2111 m->peeked_signature = sig;
2117 *type = c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY;
2122 if (c->signature[c->index] == SD_BUS_TYPE_VARIANT) {
2128 r = message_peek_body(m, &rindex, 1, 1, &q);
2135 r = message_peek_body(m, &rindex, 1, l+1, &q);
2141 if (!validate_signature(q, l))
2148 *type = SD_BUS_TYPE_VARIANT;
2157 *type = c->enclosing;
2163 int sd_bus_message_rewind(sd_bus_message *m, int complete) {
2164 struct bus_container *c;
2172 reset_containers(m);
2174 m->root_container.index = 0;
2176 c = message_get_container(m);
2178 c = message_get_container(m);
2181 m->rindex = c->begin;
2184 return !isempty(c->signature);
2186 static int message_read_ap(
2191 unsigned n_array, n_struct;
2192 TypeStack stack[BUS_CONTAINER_DEPTH];
2193 unsigned stack_ptr = 0;
2201 /* Ideally, we'd just call ourselves recursively on every
2202 * complex type. However, the state of a va_list that is
2203 * passed to a function is undefined after that function
2204 * returns. This means we need to docode the va_list linearly
2205 * in a single stackframe. We hence implement our own
2206 * home-grown stack in an array. */
2208 n_array = (unsigned) -1;
2209 n_struct = strlen(types);
2214 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
2215 r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
2221 r = sd_bus_message_exit_container(m);
2229 if (n_array != (unsigned) -1)
2238 case SD_BUS_TYPE_BYTE:
2239 case SD_BUS_TYPE_BOOLEAN:
2240 case SD_BUS_TYPE_INT16:
2241 case SD_BUS_TYPE_UINT16:
2242 case SD_BUS_TYPE_INT32:
2243 case SD_BUS_TYPE_UINT32:
2244 case SD_BUS_TYPE_INT64:
2245 case SD_BUS_TYPE_UINT64:
2246 case SD_BUS_TYPE_DOUBLE:
2247 case SD_BUS_TYPE_STRING:
2248 case SD_BUS_TYPE_OBJECT_PATH:
2249 case SD_BUS_TYPE_SIGNATURE:
2250 case SD_BUS_TYPE_UNIX_FD: {
2253 p = va_arg(ap, void*);
2254 r = sd_bus_message_read_basic(m, *t, p);
2263 case SD_BUS_TYPE_ARRAY: {
2266 r = signature_element_length(t + 1, &k);
2272 memcpy(s, t + 1, k);
2275 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, s);
2282 if (n_array == (unsigned) -1) {
2287 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2293 n_array = va_arg(ap, unsigned);
2298 case SD_BUS_TYPE_VARIANT: {
2301 s = va_arg(ap, const char *);
2305 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, s);
2311 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2316 n_struct = strlen(s);
2317 n_array = (unsigned) -1;
2322 case SD_BUS_TYPE_STRUCT_BEGIN:
2323 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
2326 r = signature_element_length(t, &k);
2332 memcpy(s, t + 1, k - 2);
2335 r = sd_bus_message_enter_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
2342 if (n_array == (unsigned) -1) {
2347 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2353 n_array = (unsigned) -1;
2366 int sd_bus_message_read(sd_bus_message *m, const char *types, ...) {
2377 va_start(ap, types);
2378 r = message_read_ap(m, types, ap);
2384 static int message_peek_fields(
2395 return buffer_peek(m->fields, BUS_MESSAGE_FIELDS_SIZE(m), rindex, align, nbytes, ret);
2398 static int message_peek_field_uint32(
2409 r = message_peek_fields(m, ri, 4, 4, &q);
2414 *ret = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2419 static int message_peek_field_string(
2421 bool (*validate)(const char *p),
2432 r = message_peek_field_uint32(m, ri, &l);
2436 r = message_peek_fields(m, ri, 1, l+1, &q);
2441 if (!validate_nul(q, l))
2447 if (!validate_string(q, l))
2457 static int message_peek_field_signature(
2469 r = message_peek_fields(m, ri, 1, 1, &q);
2474 r = message_peek_fields(m, ri, 1, l+1, &q);
2478 if (!validate_signature(q, l))
2487 static int message_skip_fields(
2490 uint32_t array_size,
2491 const char **signature) {
2493 size_t original_index;
2500 original_index = *ri;
2506 if (array_size != (uint32_t) -1 &&
2507 array_size <= *ri - original_index)
2514 if (t == SD_BUS_TYPE_STRING) {
2516 r = message_peek_field_string(m, NULL, ri, NULL);
2522 } else if (t == SD_BUS_TYPE_OBJECT_PATH) {
2524 r = message_peek_field_string(m, object_path_is_valid, ri, NULL);
2530 } else if (t == SD_BUS_TYPE_SIGNATURE) {
2532 r = message_peek_field_signature(m, ri, NULL);
2538 } else if (bus_type_is_basic(t)) {
2541 align = bus_type_get_alignment(t);
2542 k = bus_type_get_size(t);
2543 assert(align > 0 && k > 0);
2545 r = message_peek_fields(m, ri, align, k, NULL);
2551 } else if (t == SD_BUS_TYPE_ARRAY) {
2553 r = signature_element_length(*signature+1, &l);
2563 strncpy(sig, *signature + 1, l-1);
2566 alignment = bus_type_get_alignment(sig[0]);
2570 r = message_peek_field_uint32(m, ri, &nas);
2573 if (nas > BUS_ARRAY_MAX_SIZE)
2576 r = message_peek_fields(m, ri, alignment, 0, NULL);
2580 r = message_skip_fields(m, ri, nas, (const char**) &s);
2585 (*signature) += 1 + l;
2587 } else if (t == SD_BUS_TYPE_VARIANT) {
2590 r = message_peek_field_signature(m, ri, &s);
2594 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
2600 } else if (t == SD_BUS_TYPE_STRUCT ||
2601 t == SD_BUS_TYPE_DICT_ENTRY) {
2603 r = signature_element_length(*signature, &l);
2610 strncpy(sig, *signature + 1, l-1);
2613 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
2624 int bus_message_parse_fields(sd_bus_message *m) {
2627 uint32_t unix_fds = 0;
2631 for (ri = 0; ri < BUS_MESSAGE_FIELDS_SIZE(m); ) {
2632 const char *signature;
2635 r = message_peek_fields(m, &ri, 8, 1, (void**) &header);
2639 r = message_peek_field_signature(m, &ri, &signature);
2644 case _SD_BUS_MESSAGE_HEADER_INVALID:
2647 case SD_BUS_MESSAGE_HEADER_PATH:
2652 if (!streq(signature, "o"))
2655 r = message_peek_field_string(m, object_path_is_valid, &ri, &m->path);
2658 case SD_BUS_MESSAGE_HEADER_INTERFACE:
2663 if (!streq(signature, "s"))
2666 r = message_peek_field_string(m, interface_name_is_valid, &ri, &m->interface);
2669 case SD_BUS_MESSAGE_HEADER_MEMBER:
2674 if (!streq(signature, "s"))
2677 r = message_peek_field_string(m, member_name_is_valid, &ri, &m->member);
2680 case SD_BUS_MESSAGE_HEADER_ERROR_NAME:
2685 if (!streq(signature, "s"))
2688 r = message_peek_field_string(m, error_name_is_valid, &ri, &m->error.name);
2691 case SD_BUS_MESSAGE_HEADER_DESTINATION:
2696 if (!streq(signature, "s"))
2699 r = message_peek_field_string(m, service_name_is_valid, &ri, &m->destination);
2702 case SD_BUS_MESSAGE_HEADER_SENDER:
2707 if (!streq(signature, "s"))
2710 r = message_peek_field_string(m, service_name_is_valid, &ri, &m->sender);
2714 case SD_BUS_MESSAGE_HEADER_SIGNATURE: {
2718 if (m->root_container.signature)
2721 if (!streq(signature, "g"))
2724 r = message_peek_field_signature(m, &ri, &s);
2732 free(m->root_container.signature);
2733 m->root_container.signature = c;
2737 case SD_BUS_MESSAGE_HEADER_REPLY_SERIAL:
2738 if (m->reply_serial != 0)
2741 if (!streq(signature, "u"))
2744 r = message_peek_field_uint32(m, &ri, &m->reply_serial);
2748 if (m->reply_serial == 0)
2753 case SD_BUS_MESSAGE_HEADER_UNIX_FDS:
2757 if (!streq(signature, "u"))
2760 r = message_peek_field_uint32(m, &ri, &unix_fds);
2770 r = message_skip_fields(m, &ri, (uint32_t) -1, (const char **) &signature);
2777 if (m->n_fds != unix_fds)
2780 if (isempty(m->root_container.signature) != (BUS_MESSAGE_BODY_SIZE(m) == 0))
2783 switch (m->header->type) {
2785 case SD_BUS_MESSAGE_TYPE_SIGNAL:
2786 if (!m->path || !m->interface || !m->member)
2790 case SD_BUS_MESSAGE_TYPE_METHOD_CALL:
2792 if (!m->path || !m->member)
2797 case SD_BUS_MESSAGE_TYPE_METHOD_RETURN:
2799 if (m->reply_serial == 0)
2803 case SD_BUS_MESSAGE_TYPE_METHOD_ERROR:
2805 if (m->reply_serial == 0 || !m->error.name)
2810 /* Try to read the error message, but if we can't it's a non-issue */
2811 if (m->header->type == SD_BUS_MESSAGE_TYPE_METHOD_ERROR)
2812 sd_bus_message_read(m, "s", &m->error.message);
2817 int bus_message_seal(sd_bus_message *m, uint64_t serial) {
2825 if (m->n_containers > 0)
2828 /* If there's a non-trivial signature set, then add it in here */
2829 if (!isempty(m->root_container.signature)) {
2830 r = message_append_field_signature(m, SD_BUS_MESSAGE_HEADER_SIGNATURE, m->root_container.signature, NULL);
2836 r = message_append_field_uint32(m, SD_BUS_MESSAGE_HEADER_UNIX_FDS, m->n_fds);
2841 m->header->serial = serial;
2847 int sd_bus_message_set_destination(sd_bus_message *m, const char *destination) {
2857 return message_append_field_string(m, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &m->destination);
2860 int bus_message_dump(sd_bus_message *m) {
2866 printf("Message %p\n"
2873 "\tfields_size=%u\n"
2878 "\tdestination=%s\n"
2881 "\treply_serial=%u\n"
2883 "\terror.message=%s\n"
2891 BUS_MESSAGE_SERIAL(m),
2892 BUS_MESSAGE_FIELDS_SIZE(m),
2893 BUS_MESSAGE_BODY_SIZE(m),
2895 strna(m->interface),
2897 strna(m->destination),
2899 strna(m->root_container.signature),
2901 strna(m->error.name),
2902 strna(m->error.message),
2906 printf("\tpid=%lu\n", (unsigned long) m->pid);
2908 printf("\ttid=%lu\n", (unsigned long) m->tid);
2910 printf("\tuid=%lu\n", (unsigned long) m->uid);
2912 printf("\tgid=%lu\n", (unsigned long) m->gid);
2915 r = sd_bus_message_rewind(m, true);
2917 log_error("Failed to rewind: %s", strerror(-r));
2921 printf("BEGIN_MESSAGE \"%s\" {\n", strempty(m->root_container.signature));
2924 _cleanup_free_ char *prefix = NULL;
2925 const char *contents = NULL;
2940 r = sd_bus_message_peek_type(m, &type, &contents);
2942 log_error("Failed to peek type: %s", strerror(-r));
2949 r = sd_bus_message_exit_container(m);
2951 log_error("Failed to exit container: %s", strerror(-r));
2957 prefix = strrep("\t", level);
2961 if (type == SD_BUS_TYPE_ARRAY)
2962 printf("%s} END_ARRAY \n", prefix);
2963 else if (type == SD_BUS_TYPE_VARIANT)
2964 printf("%s} END_VARIANT\n", prefix);
2965 else if (type == SD_BUS_TYPE_STRUCT)
2966 printf("%s} END_STRUCT\n", prefix);
2967 else if (type == SD_BUS_TYPE_DICT_ENTRY)
2968 printf("%s} END_DICT_ENTRY\n", prefix);
2973 prefix = strrep("\t", level);
2977 if (bus_type_is_container(type) > 0) {
2978 r = sd_bus_message_enter_container(m, type, contents);
2980 log_error("Failed to enter container: %s", strerror(-r));
2984 if (type == SD_BUS_TYPE_ARRAY)
2985 printf("%sBEGIN_ARRAY \"%s\" {\n", prefix, contents);
2986 else if (type == SD_BUS_TYPE_VARIANT)
2987 printf("%sBEGIN_VARIANT \"%s\" {\n", prefix, contents);
2988 else if (type == SD_BUS_TYPE_STRUCT)
2989 printf("%sBEGIN_STRUCT \"%s\" {\n", prefix, contents);
2990 else if (type == SD_BUS_TYPE_DICT_ENTRY)
2991 printf("%sBEGIN_DICT_ENTRY \"%s\" {\n", prefix, contents);
2998 r = sd_bus_message_read_basic(m, type, &basic);
3000 log_error("Failed to get basic: %s", strerror(-r));
3006 case SD_BUS_TYPE_BYTE:
3007 printf("%sBYTE: %u\n", prefix, basic.u8);
3010 case SD_BUS_TYPE_BOOLEAN:
3011 printf("%sBOOLEAN: %s\n", prefix, yes_no(basic.i));
3014 case SD_BUS_TYPE_INT16:
3015 printf("%sINT16: %i\n", prefix, basic.s16);
3018 case SD_BUS_TYPE_UINT16:
3019 printf("%sUINT16: %u\n", prefix, basic.u16);
3022 case SD_BUS_TYPE_INT32:
3023 printf("%sINT32: %i\n", prefix, basic.s32);
3026 case SD_BUS_TYPE_UINT32:
3027 printf("%sUINT32: %u\n", prefix, basic.u32);
3030 case SD_BUS_TYPE_INT64:
3031 printf("%sINT64: %lli\n", prefix, (long long) basic.s64);
3034 case SD_BUS_TYPE_UINT64:
3035 printf("%sUINT64: %llu\n", prefix, (unsigned long long) basic.u64);
3038 case SD_BUS_TYPE_DOUBLE:
3039 printf("%sDOUBLE: %g\n", prefix, basic.d64);
3042 case SD_BUS_TYPE_STRING:
3043 printf("%sSTRING: \"%s\"\n", prefix, basic.string);
3046 case SD_BUS_TYPE_OBJECT_PATH:
3047 printf("%sOBJECT_PATH: \"%s\"\n", prefix, basic.string);
3050 case SD_BUS_TYPE_SIGNATURE:
3051 printf("%sSIGNATURE: \"%s\"\n", prefix, basic.string);
3054 case SD_BUS_TYPE_UNIX_FD:
3055 printf("%sUNIX_FD: %i\n", prefix, basic.i);
3059 assert_not_reached("Unknown basic type.");
3063 printf("} END_MESSAGE\n");
3067 int bus_message_get_blob(sd_bus_message *m, void **buffer, size_t *sz) {
3075 total = BUS_MESSAGE_SIZE(m);
3081 e = mempcpy(p, m->header, sizeof(*m->header));
3084 e = mempcpy(e, m->fields, m->header->fields_size);
3086 if (m->header->fields_size % 8 != 0)
3087 e = mempset(e, 0, 8 - (m->header->fields_size % 8));
3091 e = mempcpy(e, m->body, m->header->body_size);
3093 assert(total == (size_t) ((uint8_t*) e - (uint8_t*) p));
3101 int bus_message_read_strv_extend(sd_bus_message *m, char ***l) {
3107 r = sd_bus_message_enter_container(m, 'a', "s");
3114 r = sd_bus_message_read_basic(m, 's', &s);
3120 r = strv_extend(l, s);
3125 r = sd_bus_message_exit_container(m);
3132 const char* bus_message_get_arg(sd_bus_message *m, unsigned i) {
3139 r = sd_bus_message_rewind(m, true);
3144 r = sd_bus_message_peek_type(m, &type, NULL);
3148 if (type != SD_BUS_TYPE_STRING &&
3149 type != SD_BUS_TYPE_OBJECT_PATH &&
3150 type != SD_BUS_TYPE_SIGNATURE)
3153 r = sd_bus_message_read_basic(m, type, &t);
3160 r = sd_bus_message_rewind(m, true);
3167 int bus_header_size(struct bus_header *h, size_t *sum) {
3173 if (h->endian == SD_BUS_NATIVE_ENDIAN) {
3174 fs = h->fields_size;
3176 } else if (h->endian == SD_BUS_REVERSE_ENDIAN) {
3177 fs = bswap_32(h->fields_size);
3178 bs = bswap_32(h->body_size);
3182 *sum = sizeof(struct bus_header) + ALIGN8(fs) + bs;