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/>.
30 #include "bus-message.h"
31 #include "bus-internal.h"
33 #include "bus-signature.h"
35 static int message_parse_fields(sd_bus_message *m);
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) {
66 close_many(m->fds, m->n_fds);
71 free(m->root_container.signature);
73 free(m->peeked_signature);
77 static void* buffer_extend(void **p, uint32_t *sz, size_t align, size_t extend) {
85 start = ALIGN_TO((size_t) *sz, align);
89 return (uint8_t*) *p + start;
91 if (n > (size_t) ((uint32_t) -1))
98 /* Zero out padding */
100 memset((uint8_t*) k + *sz, 0, start - *sz);
105 return (uint8_t*) k + start;
108 static void *message_extend_fields(sd_bus_message *m, size_t align, size_t sz) {
114 p = buffer_extend(&m->fields, &m->header->fields_size, align, sz);
118 if (o != m->fields) {
119 /* Adjust quick access pointers */
122 m->path = (const char*) m->fields + (m->path - (const char*) o);
124 m->interface = (const char*) m->fields + (m->interface - (const char*) o);
126 m->member = (const char*) m->fields + (m->member - (const char*) o);
128 m->destination = (const char*) m->fields + (m->destination - (const char*) o);
130 m->sender = (const char*) m->fields + (m->sender - (const char*) o);
132 m->error.name = (const char*) m->fields + (m->error.name - (const char*) o);
135 m->free_fields = true;
140 static int message_append_field_string(
153 if (l > (size_t) (uint32_t) -1)
156 /* field id byte + signature length + signature 's' + NUL + string length + string + NUL */
157 p = message_extend_fields(m, 8, 4 + 4 + l + 1);
166 ((uint32_t*) p)[1] = l;
167 memcpy(p + 8, s, l + 1);
170 *ret = (const char*) p + 8;
175 static int message_append_field_signature(
190 /* field id byte + signature length + signature 'g' + NUL + string length + string + NUL */
191 p = message_extend_fields(m, 8, 4 + 1 + l + 1);
197 p[2] = SD_BUS_TYPE_SIGNATURE;
200 memcpy(p + 5, s, l + 1);
203 *ret = (const char*) p + 5;
208 static int message_append_field_uint32(sd_bus_message *m, uint8_t h, uint32_t x) {
213 /* field id byte + signature length + signature 'u' + NUL + value */
214 p = message_extend_fields(m, 8, 4 + 4);
220 p[2] = SD_BUS_TYPE_UINT32;
223 ((uint32_t*) p)[1] = x;
228 int bus_message_from_malloc(
233 const struct ucred *ucred,
235 sd_bus_message **ret) {
238 struct bus_header *h;
239 size_t total, fs, bs, label_sz, a;
242 assert(buffer || length <= 0);
243 assert(fds || n_fds <= 0);
246 if (length < sizeof(struct bus_header))
256 if (h->type == _SD_BUS_MESSAGE_TYPE_INVALID)
259 if (h->endian == SD_BUS_NATIVE_ENDIAN) {
262 } else if (h->endian == SD_BUS_REVERSE_ENDIAN) {
263 fs = bswap_32(h->fields_size);
264 bs = bswap_32(h->body_size);
268 total = sizeof(struct bus_header) + ALIGN8(fs) + bs;
273 label_sz = strlen(label);
274 a = ALIGN(sizeof(sd_bus_message)) + label_sz + 1;
276 a = sizeof(sd_bus_message);
285 m->fields = (uint8_t*) buffer + sizeof(struct bus_header);
286 m->body = (uint8_t*) buffer + sizeof(struct bus_header) + ALIGN8(fs);
294 m->uid_valid = m->gid_valid = true;
298 m->label = (char*) m + ALIGN(sizeof(sd_bus_message));
299 memcpy(m->label, label, label_sz + 1);
303 m->iovec[0].iov_base = buffer;
304 m->iovec[0].iov_len = length;
306 r = message_parse_fields(m);
310 /* We take possession of the memory and fds now */
311 m->free_header = true;
322 static sd_bus_message *message_new(sd_bus *bus, uint8_t type) {
325 m = malloc0(ALIGN(sizeof(sd_bus_message)) + sizeof(struct bus_header));
330 m->header = (struct bus_header*) ((uint8_t*) m + ALIGN(sizeof(struct sd_bus_message)));
331 m->header->endian = SD_BUS_NATIVE_ENDIAN;
332 m->header->type = type;
333 m->header->version = bus ? bus->message_version : 1;
334 m->allow_fds = !bus || bus->can_fds || (bus->state != BUS_HELLO && bus->state != BUS_RUNNING);
339 int sd_bus_message_new_signal(
342 const char *interface,
344 sd_bus_message **m) {
357 if (bus && bus->state == BUS_UNSET)
360 t = message_new(bus, SD_BUS_MESSAGE_TYPE_SIGNAL);
364 t->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
366 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_PATH, SD_BUS_TYPE_OBJECT_PATH, path, &t->path);
369 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_INTERFACE, SD_BUS_TYPE_STRING, interface, &t->interface);
372 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_MEMBER, SD_BUS_TYPE_STRING, member, &t->member);
380 sd_bus_message_unref(t);
384 int sd_bus_message_new_method_call(
386 const char *destination,
388 const char *interface,
390 sd_bus_message **m) {
401 if (bus && bus->state == BUS_UNSET)
404 t = message_new(bus, SD_BUS_MESSAGE_TYPE_METHOD_CALL);
408 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_PATH, SD_BUS_TYPE_OBJECT_PATH, path, &t->path);
411 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_MEMBER, SD_BUS_TYPE_STRING, member, &t->member);
416 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_INTERFACE, SD_BUS_TYPE_STRING, interface, &t->interface);
422 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &t->destination);
435 static int message_new_reply(
437 sd_bus_message *call,
439 sd_bus_message **m) {
448 if (call->header->type != SD_BUS_MESSAGE_TYPE_METHOD_CALL)
452 if (bus && bus->state == BUS_UNSET)
455 t = message_new(bus, type);
459 t->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
460 t->reply_serial = BUS_MESSAGE_SERIAL(call);
462 r = message_append_field_uint32(t, SD_BUS_MESSAGE_HEADER_REPLY_SERIAL, t->reply_serial);
467 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, call->sender, &t->sender);
472 t->dont_send = !!(call->header->flags & SD_BUS_MESSAGE_NO_REPLY_EXPECTED);
482 int sd_bus_message_new_method_return(
484 sd_bus_message *call,
485 sd_bus_message **m) {
487 return message_new_reply(bus, call, SD_BUS_MESSAGE_TYPE_METHOD_RETURN, m);
490 int sd_bus_message_new_method_error(
492 sd_bus_message *call,
493 const sd_bus_error *e,
494 sd_bus_message **m) {
499 if (!sd_bus_error_is_set(e))
504 r = message_new_reply(bus, call, SD_BUS_MESSAGE_TYPE_METHOD_ERROR, &t);
508 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_ERROR_NAME, SD_BUS_TYPE_STRING, e->name, &t->error.name);
513 r = message_append_basic(t, SD_BUS_TYPE_STRING, e->message, (const void**) &t->error.message);
526 sd_bus_message* sd_bus_message_ref(sd_bus_message *m) {
530 assert(m->n_ref > 0);
536 sd_bus_message* sd_bus_message_unref(sd_bus_message *m) {
540 assert(m->n_ref > 0);
549 int sd_bus_message_get_type(sd_bus_message *m, uint8_t *type) {
555 *type = m->header->type;
559 int sd_bus_message_get_serial(sd_bus_message *m, uint64_t *serial) {
564 if (m->header->serial == 0)
567 *serial = BUS_MESSAGE_SERIAL(m);
571 int sd_bus_message_get_reply_serial(sd_bus_message *m, uint64_t *serial) {
576 if (m->reply_serial == 0)
579 *serial = m->reply_serial;
583 int sd_bus_message_get_no_reply(sd_bus_message *m) {
587 return m->header->type == SD_BUS_MESSAGE_TYPE_METHOD_CALL ? !!(m->header->flags & SD_BUS_MESSAGE_NO_REPLY_EXPECTED) : 0;
590 const char *sd_bus_message_get_path(sd_bus_message *m) {
597 const char *sd_bus_message_get_interface(sd_bus_message *m) {
604 const char *sd_bus_message_get_member(sd_bus_message *m) {
610 const char *sd_bus_message_get_destination(sd_bus_message *m) {
614 return m->destination;
617 const char *sd_bus_message_get_sender(sd_bus_message *m) {
624 const sd_bus_error *sd_bus_message_get_error(sd_bus_message *m) {
628 if (!sd_bus_error_is_set(&m->error))
634 int sd_bus_message_get_uid(sd_bus_message *m, uid_t *uid) {
644 int sd_bus_message_get_gid(sd_bus_message *m, gid_t *gid) {
654 int sd_bus_message_get_pid(sd_bus_message *m, pid_t *pid) {
664 int sd_bus_message_get_tid(sd_bus_message *m, pid_t *tid) {
674 const char *sd_bus_message_get_label(sd_bus_message *m) {
681 int sd_bus_message_is_signal(sd_bus_message *m, const char *interface, const char *member) {
685 if (m->header->type != SD_BUS_MESSAGE_TYPE_SIGNAL)
688 if (interface && (!m->interface || !streq(m->interface, interface)))
691 if (member && (!m->member || !streq(m->member, member)))
697 int sd_bus_message_is_method_call(sd_bus_message *m, const char *interface, const char *member) {
701 if (m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_CALL)
704 if (interface && (!m->interface || !streq(m->interface, interface)))
707 if (member && (!m->member || !streq(m->member, member)))
713 int sd_bus_message_is_method_error(sd_bus_message *m, const char *name) {
717 if (m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_ERROR)
720 if (name && (!m->error.name || !streq(m->error.name, name)))
726 int sd_bus_message_set_no_reply(sd_bus_message *m, int b) {
731 if (m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_CALL)
735 m->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
737 m->header->flags &= ~SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
742 static struct bus_container *message_get_container(sd_bus_message *m) {
745 if (m->n_containers == 0)
746 return &m->root_container;
748 assert(m->containers);
749 return m->containers + m->n_containers - 1;
752 static void *message_extend_body(sd_bus_message *m, size_t align, size_t sz) {
755 struct bus_container *c;
761 added = m->header->body_size;
763 p = buffer_extend(&m->body, &m->header->body_size, align, sz);
767 added = m->header->body_size - added;
769 for (c = m->containers; c < m->containers + m->n_containers; c++)
771 c->array_size = (uint32_t*) ((uint8_t*) m->body + ((uint8_t*) c->array_size - (uint8_t*) o));
772 *c->array_size += added;
776 if (m->error.message)
777 m->error.message = (const char*) m->body + (m->error.message - (const char*) o);
785 int message_append_basic(sd_bus_message *m, char type, const void *p, const void **stored) {
786 struct bus_container *c;
801 if (!bus_type_is_basic(type))
804 c = message_get_container(m);
806 if (c->signature && c->signature[c->index]) {
807 /* Container signature is already set */
809 if (c->signature[c->index] != type)
812 /* Maybe we can append to the signature? But only if this is the top-level container*/
813 if (c->enclosing != 0)
816 e = strextend(&c->signature, CHAR_TO_STR(type), NULL);
823 case SD_BUS_TYPE_STRING:
824 case SD_BUS_TYPE_OBJECT_PATH:
827 sz = 4 + strlen(p) + 1;
830 case SD_BUS_TYPE_SIGNATURE:
833 sz = 1 + strlen(p) + 1;
836 case SD_BUS_TYPE_BOOLEAN:
839 assert_cc(sizeof(int) == sizeof(uint32_t));
845 case SD_BUS_TYPE_UNIX_FD: {
861 fd = fcntl(z, F_DUPFD_CLOEXEC, 3);
867 f = realloc(m->fds, sizeof(int) * (m->n_fds + 1));
881 align = bus_type_get_alignment(type);
882 sz = bus_type_get_size(type);
889 a = message_extend_body(m, align, sz);
895 if (type == SD_BUS_TYPE_STRING || type == SD_BUS_TYPE_OBJECT_PATH) {
896 *(uint32_t*) a = sz - 5;
897 memcpy((uint8_t*) a + 4, p, sz - 4);
900 *stored = (const uint8_t*) a + 4;
902 } else if (type == SD_BUS_TYPE_SIGNATURE) {
903 *(uint8_t*) a = sz - 1;
904 memcpy((uint8_t*) a + 1, p, sz - 1);
907 *stored = (const uint8_t*) a + 1;
908 } else if (type == SD_BUS_TYPE_UNIX_FD) {
909 *(uint32_t*) a = fdi;
923 if (c->enclosing != SD_BUS_TYPE_ARRAY)
929 /* Truncate extended signature again */
931 c->signature[c->index] = 0;
934 close_nointr_nofail(fd);
939 int sd_bus_message_append_basic(sd_bus_message *m, char type, const void *p) {
940 return message_append_basic(m, type, p, NULL);
943 static int bus_message_open_array(
945 struct bus_container *c,
946 const char *contents,
947 uint32_t **array_size) {
960 if (!signature_is_single(contents))
963 alignment = bus_type_get_alignment(contents[0]);
967 if (c->signature && c->signature[c->index]) {
969 /* Verify the existing signature */
971 if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
974 if (!startswith(c->signature + c->index + 1, contents))
977 nindex = c->index + 1 + strlen(contents);
979 if (c->enclosing != 0)
982 /* Extend the existing signature */
984 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_ARRAY), contents, NULL);
988 nindex = e - c->signature;
991 saved = m->header->body_size;
992 a = message_extend_body(m, 4, 4);
994 /* Truncate extended signature again */
996 c->signature[c->index] = 0;
1002 if (!message_extend_body(m, alignment, 0)) {
1003 /* Add alignment between size and first element */
1005 c->signature[c->index] = 0;
1007 m->header->body_size = saved;
1011 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1014 /* m->body might have changed so let's readjust a */
1015 a = (uint8_t*) m->body + ((uint8_t*) a - (uint8_t*) b);
1022 static int bus_message_open_variant(
1024 struct bus_container *c,
1025 const char *contents) {
1035 if (!signature_is_single(contents))
1038 if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
1041 if (c->signature && c->signature[c->index]) {
1043 if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
1047 if (c->enclosing != 0)
1050 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_VARIANT), NULL);
1055 l = strlen(contents);
1056 a = message_extend_body(m, 1, 1 + l + 1);
1058 /* Truncate extended signature again */
1060 c->signature[c->index] = 0;
1066 memcpy((uint8_t*) a + 1, contents, l + 1);
1068 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1074 static int bus_message_open_struct(
1076 struct bus_container *c,
1077 const char *contents) {
1086 if (!signature_is_valid(contents, false))
1089 if (c->signature && c->signature[c->index]) {
1092 l = strlen(contents);
1094 if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
1095 !startswith(c->signature + c->index + 1, contents) ||
1096 c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
1099 nindex = c->index + 1 + l + 1;
1101 if (c->enclosing != 0)
1104 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_BEGIN), contents, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_END), NULL);
1108 nindex = e - c->signature;
1111 /* Align contents to 8 byte boundary */
1112 if (!message_extend_body(m, 8, 0)) {
1114 c->signature[c->index] = 0;
1119 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1125 static int bus_message_open_dict_entry(
1127 struct bus_container *c,
1128 const char *contents) {
1136 if (!signature_is_pair(contents))
1139 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1142 if (c->signature && c->signature[c->index]) {
1145 l = strlen(contents);
1147 if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
1148 !startswith(c->signature + c->index + 1, contents) ||
1149 c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
1152 nindex = c->index + 1 + l + 1;
1156 /* Align contents to 8 byte boundary */
1157 if (!message_extend_body(m, 8, 0))
1160 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1166 int sd_bus_message_open_container(
1169 const char *contents) {
1171 struct bus_container *c, *w;
1172 uint32_t *array_size = NULL;
1183 /* Make sure we have space for one more container */
1184 w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
1189 c = message_get_container(m);
1191 signature = strdup(contents);
1195 if (type == SD_BUS_TYPE_ARRAY)
1196 r = bus_message_open_array(m, c, contents, &array_size);
1197 else if (type == SD_BUS_TYPE_VARIANT)
1198 r = bus_message_open_variant(m, c, contents);
1199 else if (type == SD_BUS_TYPE_STRUCT)
1200 r = bus_message_open_struct(m, c, contents);
1201 else if (type == SD_BUS_TYPE_DICT_ENTRY)
1202 r = bus_message_open_dict_entry(m, c, contents);
1211 /* OK, let's fill it in */
1212 w += m->n_containers++;
1213 w->enclosing = type;
1214 w->signature = signature;
1216 w->array_size = array_size;
1222 int sd_bus_message_close_container(sd_bus_message *m) {
1223 struct bus_container *c;
1229 if (m->n_containers <= 0)
1232 c = message_get_container(m);
1233 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1234 if (c->signature && c->signature[c->index] != 0)
1250 static int type_stack_push(TypeStack *stack, unsigned max, unsigned *i, const char *types, unsigned n_struct, unsigned n_array) {
1257 stack[*i].types = types;
1258 stack[*i].n_struct = n_struct;
1259 stack[*i].n_array = n_array;
1265 static int type_stack_pop(TypeStack *stack, unsigned max, unsigned *i, const char **types, unsigned *n_struct, unsigned *n_array) {
1276 *types = stack[*i].types;
1277 *n_struct = stack[*i].n_struct;
1278 *n_array = stack[*i].n_array;
1283 int bus_message_append_ap(
1288 unsigned n_array, n_struct;
1289 TypeStack stack[BUS_CONTAINER_DEPTH];
1290 unsigned stack_ptr = 0;
1298 n_array = (unsigned) -1;
1299 n_struct = strlen(types);
1304 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
1305 r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
1311 r = sd_bus_message_close_container(m);
1319 if (n_array != (unsigned) -1)
1328 case SD_BUS_TYPE_BYTE: {
1331 x = (uint8_t) va_arg(ap, int);
1332 r = sd_bus_message_append_basic(m, *t, &x);
1336 case SD_BUS_TYPE_BOOLEAN:
1337 case SD_BUS_TYPE_INT32:
1338 case SD_BUS_TYPE_UINT32:
1339 case SD_BUS_TYPE_UNIX_FD: {
1342 /* We assume a boolean is the same as int32_t */
1343 assert_cc(sizeof(int32_t) == sizeof(int));
1345 x = va_arg(ap, uint32_t);
1346 r = sd_bus_message_append_basic(m, *t, &x);
1350 case SD_BUS_TYPE_INT16:
1351 case SD_BUS_TYPE_UINT16: {
1354 x = (uint16_t) va_arg(ap, int);
1355 r = sd_bus_message_append_basic(m, *t, &x);
1359 case SD_BUS_TYPE_INT64:
1360 case SD_BUS_TYPE_UINT64:
1361 case SD_BUS_TYPE_DOUBLE: {
1364 x = va_arg(ap, uint64_t);
1365 r = sd_bus_message_append_basic(m, *t, &x);
1369 case SD_BUS_TYPE_STRING:
1370 case SD_BUS_TYPE_OBJECT_PATH:
1371 case SD_BUS_TYPE_SIGNATURE: {
1374 x = va_arg(ap, const char*);
1375 r = sd_bus_message_append_basic(m, *t, x);
1379 case SD_BUS_TYPE_ARRAY: {
1382 r = signature_element_length(t + 1, &k);
1388 memcpy(s, t + 1, k);
1391 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, s);
1396 if (n_array == (unsigned) -1) {
1401 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
1407 n_array = va_arg(ap, unsigned);
1412 case SD_BUS_TYPE_VARIANT: {
1415 s = va_arg(ap, const char*);
1419 r = sd_bus_message_open_container(m, SD_BUS_TYPE_VARIANT, s);
1423 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
1428 n_struct = strlen(s);
1429 n_array = (unsigned) -1;
1434 case SD_BUS_TYPE_STRUCT_BEGIN:
1435 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
1438 r = signature_element_length(t, &k);
1445 memcpy(s, t + 1, k - 2);
1448 r = sd_bus_message_open_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
1453 if (n_array == (unsigned) -1) {
1458 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
1464 n_array = (unsigned) -1;
1480 int sd_bus_message_append(sd_bus_message *m, const char *types, ...) {
1491 va_start(ap, types);
1492 r = bus_message_append_ap(m, types, ap);
1498 static int buffer_peek(const void *p, uint32_t sz, size_t *rindex, size_t align, size_t nbytes, void **r) {
1504 start = ALIGN_TO((size_t) *rindex, align);
1510 /* Verify that padding is 0 */
1511 for (k = *rindex; k < start; k++)
1512 if (((const uint8_t*) p)[k] != 0)
1516 *r = (uint8_t*) p + start;
1523 static bool message_end_of_array(sd_bus_message *m, size_t index) {
1524 struct bus_container *c;
1528 c = message_get_container(m);
1532 return index >= c->begin + BUS_MESSAGE_BSWAP32(m, *c->array_size);
1535 static int message_peek_body(sd_bus_message *m, size_t *rindex, size_t align, size_t nbytes, void **ret) {
1540 if (message_end_of_array(m, *rindex))
1543 return buffer_peek(m->body, BUS_MESSAGE_BODY_SIZE(m), rindex, align, nbytes, ret);
1546 static bool validate_nul(const char *s, size_t l) {
1548 /* Check for NUL chars in the string */
1549 if (memchr(s, 0, l))
1552 /* Check for NUL termination */
1559 static bool validate_string(const char *s, size_t l) {
1561 if (!validate_nul(s, l))
1564 /* Check if valid UTF8 */
1565 if (!utf8_is_valid(s))
1571 static bool validate_signature(const char *s, size_t l) {
1573 if (!validate_nul(s, l))
1576 /* Check if valid signature */
1577 if (!signature_is_valid(s, true))
1583 static bool validate_object_path(const char *s, size_t l) {
1585 if (!validate_nul(s, l))
1588 if (!object_path_is_valid(s))
1594 int sd_bus_message_read_basic(sd_bus_message *m, char type, void *p) {
1595 struct bus_container *c;
1603 if (!bus_type_is_basic(type))
1608 c = message_get_container(m);
1610 if (!c->signature || c->signature[c->index] == 0)
1613 if (c->signature[c->index] != type)
1618 case SD_BUS_TYPE_STRING:
1619 case SD_BUS_TYPE_OBJECT_PATH: {
1624 r = message_peek_body(m, &rindex, 4, 4, &q);
1628 l = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
1629 r = message_peek_body(m, &rindex, 1, l+1, &q);
1635 if (type == SD_BUS_TYPE_OBJECT_PATH) {
1636 if (!validate_object_path(q, l))
1639 if (!validate_string(q, l))
1644 *(const char**) p = q;
1648 case SD_BUS_TYPE_SIGNATURE: {
1653 r = message_peek_body(m, &rindex, 1, 1, &q);
1658 r = message_peek_body(m, &rindex, 1, l+1, &q);
1664 if (!validate_signature(q, l))
1668 *(const char**) p = q;
1676 align = bus_type_get_alignment(type);
1677 sz = bus_type_get_size(type);
1678 assert(align > 0 && sz > 0);
1681 r = message_peek_body(m, &rindex, align, sz, &q);
1687 case SD_BUS_TYPE_BYTE:
1688 *(uint8_t*) p = *(uint8_t*) q;
1691 case SD_BUS_TYPE_BOOLEAN:
1692 *(int*) p = !!*(uint32_t*) q;
1695 case SD_BUS_TYPE_INT16:
1696 case SD_BUS_TYPE_UINT16:
1697 *(uint16_t*) p = BUS_MESSAGE_BSWAP16(m, *(uint16_t*) q);
1700 case SD_BUS_TYPE_INT32:
1701 case SD_BUS_TYPE_UINT32:
1702 *(uint32_t*) p = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
1705 case SD_BUS_TYPE_INT64:
1706 case SD_BUS_TYPE_UINT64:
1707 case SD_BUS_TYPE_DOUBLE:
1708 *(uint64_t*) p = BUS_MESSAGE_BSWAP64(m, *(uint64_t*) q);
1711 case SD_BUS_TYPE_UNIX_FD: {
1714 j = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
1718 *(int*) p = m->fds[j];
1723 assert_not_reached("Unknown basic type...");
1732 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1738 static int bus_message_enter_array(
1740 struct bus_container *c,
1741 const char *contents,
1742 uint32_t **array_size) {
1753 if (!signature_is_single(contents))
1756 alignment = bus_type_get_alignment(contents[0]);
1760 if (!c->signature || c->signature[c->index] == 0)
1763 if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
1766 if (!startswith(c->signature + c->index + 1, contents))
1770 r = message_peek_body(m, &rindex, 4, 4, &q);
1774 if (BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q) > BUS_ARRAY_MAX_SIZE)
1777 r = message_peek_body(m, &rindex, alignment, 0, NULL);
1783 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1784 c->index += 1 + strlen(contents);
1788 *array_size = (uint32_t*) q;
1793 static int bus_message_enter_variant(
1795 struct bus_container *c,
1796 const char *contents) {
1807 if (!signature_is_single(contents))
1810 if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
1813 if (!c->signature || c->signature[c->index] == 0)
1816 if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
1820 r = message_peek_body(m, &rindex, 1, 1, &q);
1825 r = message_peek_body(m, &rindex, 1, l+1, &q);
1831 if (!validate_signature(q, l))
1834 if (!streq(q, contents))
1837 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1845 static int bus_message_enter_struct(
1847 struct bus_container *c,
1848 const char *contents) {
1857 if (!signature_is_valid(contents, false))
1860 if (!c->signature || c->signature[c->index] == 0)
1863 l = strlen(contents);
1865 if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
1866 !startswith(c->signature + c->index + 1, contents) ||
1867 c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
1870 r = message_peek_body(m, &m->rindex, 8, 0, NULL);
1874 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1875 c->index += 1 + l + 1;
1880 static int bus_message_enter_dict_entry(
1882 struct bus_container *c,
1883 const char *contents) {
1892 if (!signature_is_pair(contents))
1895 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1898 if (!c->signature || c->signature[c->index] == 0)
1901 l = strlen(contents);
1903 if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
1904 !startswith(c->signature + c->index + 1, contents) ||
1905 c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
1908 r = message_peek_body(m, &m->rindex, 8, 0, NULL);
1912 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1913 c->index += 1 + l + 1;
1918 int sd_bus_message_enter_container(sd_bus_message *m, char type, const char *contents) {
1919 struct bus_container *c, *w;
1920 uint32_t *array_size = NULL;
1932 * We enforce a global limit on container depth, that is much
1933 * higher than the 32 structs and 32 arrays the specification
1934 * mandates. This is simpler to implement for us, and we need
1935 * this only to ensure our container array doesn't grow
1936 * without bounds. We are happy to return any data from a
1937 * message as long as the data itself is valid, even if the
1938 * overall message might be not.
1940 * Note that the message signature is validated when
1941 * parsing the headers, and that validation does check the
1944 * Note that the specification defines no limits on the depth
1945 * of stacked variants, but we do.
1947 if (m->n_containers >= BUS_CONTAINER_DEPTH)
1950 w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
1955 c = message_get_container(m);
1957 if (!c->signature || c->signature[c->index] == 0)
1960 signature = strdup(contents);
1964 if (type == SD_BUS_TYPE_ARRAY)
1965 r = bus_message_enter_array(m, c, contents, &array_size);
1966 else if (type == SD_BUS_TYPE_VARIANT)
1967 r = bus_message_enter_variant(m, c, contents);
1968 else if (type == SD_BUS_TYPE_STRUCT)
1969 r = bus_message_enter_struct(m, c, contents);
1970 else if (type == SD_BUS_TYPE_DICT_ENTRY)
1971 r = bus_message_enter_dict_entry(m, c, contents);
1980 /* OK, let's fill it in */
1981 w += m->n_containers++;
1982 w->enclosing = type;
1983 w->signature = signature;
1985 w->array_size = array_size;
1986 w->begin = m->rindex;
1991 int sd_bus_message_exit_container(sd_bus_message *m) {
1992 struct bus_container *c;
1998 if (m->n_containers <= 0)
2001 c = message_get_container(m);
2002 if (c->enclosing == SD_BUS_TYPE_ARRAY) {
2005 l = BUS_MESSAGE_BSWAP32(m, *c->array_size);
2006 if (c->begin + l != m->rindex)
2010 if (c->signature && c->signature[c->index] != 0)
2020 int sd_bus_message_peek_type(sd_bus_message *m, char *type, const char **contents) {
2021 struct bus_container *c;
2029 c = message_get_container(m);
2031 if (!c->signature || c->signature[c->index] == 0)
2034 if (message_end_of_array(m, m->rindex))
2037 if (bus_type_is_basic(c->signature[c->index])) {
2041 *type = c->signature[c->index];
2045 if (c->signature[c->index] == SD_BUS_TYPE_ARRAY) {
2051 r = signature_element_length(c->signature+c->index+1, &l);
2057 sig = strndup(c->signature + c->index + 1, l);
2061 free(m->peeked_signature);
2062 m->peeked_signature = sig;
2068 *type = SD_BUS_TYPE_ARRAY;
2073 if (c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ||
2074 c->signature[c->index] == SD_BUS_TYPE_DICT_ENTRY_BEGIN) {
2080 r = signature_element_length(c->signature+c->index, &l);
2085 sig = strndup(c->signature + c->index + 1, l - 2);
2089 free(m->peeked_signature);
2090 m->peeked_signature = sig;
2096 *type = c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY;
2101 if (c->signature[c->index] == SD_BUS_TYPE_VARIANT) {
2107 r = message_peek_body(m, &rindex, 1, 1, &q);
2114 r = message_peek_body(m, &rindex, 1, l+1, &q);
2120 if (!validate_signature(q, l))
2127 *type = SD_BUS_TYPE_VARIANT;
2136 *type = c->enclosing;
2142 int sd_bus_message_rewind(sd_bus_message *m, int complete) {
2143 struct bus_container *c;
2151 reset_containers(m);
2153 m->root_container.index = 0;
2155 c = message_get_container(m);
2157 c = message_get_container(m);
2160 m->rindex = c->begin;
2163 return !isempty(c->signature);
2165 static int message_read_ap(
2170 unsigned n_array, n_struct;
2171 TypeStack stack[BUS_CONTAINER_DEPTH];
2172 unsigned stack_ptr = 0;
2180 /* Ideally, we'd just call ourselves recursively on every
2181 * complex type. However, the state of a va_list that is
2182 * passed to a function is undefined after that function
2183 * returns. This means we need to docode the va_list linearly
2184 * in a single stackframe. We hence implement our own
2185 * home-grown stack in an array. */
2187 n_array = (unsigned) -1;
2188 n_struct = strlen(types);
2193 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
2194 r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
2200 r = sd_bus_message_exit_container(m);
2208 if (n_array != (unsigned) -1)
2217 case SD_BUS_TYPE_BYTE:
2218 case SD_BUS_TYPE_BOOLEAN:
2219 case SD_BUS_TYPE_INT16:
2220 case SD_BUS_TYPE_UINT16:
2221 case SD_BUS_TYPE_INT32:
2222 case SD_BUS_TYPE_UINT32:
2223 case SD_BUS_TYPE_INT64:
2224 case SD_BUS_TYPE_UINT64:
2225 case SD_BUS_TYPE_DOUBLE:
2226 case SD_BUS_TYPE_STRING:
2227 case SD_BUS_TYPE_OBJECT_PATH:
2228 case SD_BUS_TYPE_SIGNATURE:
2229 case SD_BUS_TYPE_UNIX_FD: {
2232 p = va_arg(ap, void*);
2233 r = sd_bus_message_read_basic(m, *t, p);
2242 case SD_BUS_TYPE_ARRAY: {
2245 r = signature_element_length(t + 1, &k);
2251 memcpy(s, t + 1, k);
2254 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, s);
2261 if (n_array == (unsigned) -1) {
2266 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2272 n_array = va_arg(ap, unsigned);
2277 case SD_BUS_TYPE_VARIANT: {
2280 s = va_arg(ap, const char *);
2284 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, s);
2290 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2295 n_struct = strlen(s);
2296 n_array = (unsigned) -1;
2301 case SD_BUS_TYPE_STRUCT_BEGIN:
2302 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
2305 r = signature_element_length(t, &k);
2311 memcpy(s, t + 1, k - 2);
2314 r = sd_bus_message_enter_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
2321 if (n_array == (unsigned) -1) {
2326 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2332 n_array = (unsigned) -1;
2345 int sd_bus_message_read(sd_bus_message *m, const char *types, ...) {
2356 va_start(ap, types);
2357 r = message_read_ap(m, types, ap);
2363 static int message_peek_fields(
2374 return buffer_peek(m->fields, BUS_MESSAGE_FIELDS_SIZE(m), rindex, align, nbytes, ret);
2377 static int message_peek_field_uint32(
2388 r = message_peek_fields(m, ri, 4, 4, &q);
2393 *ret = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2398 static int message_peek_field_string(
2400 bool (*validate)(const char *p),
2411 r = message_peek_field_uint32(m, ri, &l);
2415 r = message_peek_fields(m, ri, 1, l+1, &q);
2420 if (!validate_nul(q, l))
2426 if (!validate_string(q, l))
2436 static int message_peek_field_signature(
2448 r = message_peek_fields(m, ri, 1, 1, &q);
2453 r = message_peek_fields(m, ri, 1, l+1, &q);
2457 if (!validate_signature(q, l))
2466 static int message_skip_fields(
2469 uint32_t array_size,
2470 const char **signature) {
2472 size_t original_index;
2479 original_index = *ri;
2485 if (array_size != (uint32_t) -1 &&
2486 array_size <= *ri - original_index)
2493 if (t == SD_BUS_TYPE_STRING) {
2495 r = message_peek_field_string(m, NULL, ri, NULL);
2501 } else if (t == SD_BUS_TYPE_OBJECT_PATH) {
2503 r = message_peek_field_string(m, object_path_is_valid, ri, NULL);
2509 } else if (t == SD_BUS_TYPE_SIGNATURE) {
2511 r = message_peek_field_signature(m, ri, NULL);
2517 } else if (bus_type_is_basic(t)) {
2520 align = bus_type_get_alignment(t);
2521 k = bus_type_get_size(t);
2522 assert(align > 0 && k > 0);
2524 r = message_peek_fields(m, ri, align, k, NULL);
2530 } else if (t == SD_BUS_TYPE_ARRAY) {
2532 r = signature_element_length(*signature+1, &l);
2542 strncpy(sig, *signature + 1, l-1);
2545 alignment = bus_type_get_alignment(sig[0]);
2549 r = message_peek_field_uint32(m, ri, &nas);
2552 if (nas > BUS_ARRAY_MAX_SIZE)
2555 r = message_peek_fields(m, ri, alignment, 0, NULL);
2559 r = message_skip_fields(m, ri, nas, (const char**) &s);
2564 (*signature) += 1 + l;
2566 } else if (t == SD_BUS_TYPE_VARIANT) {
2569 r = message_peek_field_signature(m, ri, &s);
2573 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
2579 } else if (t == SD_BUS_TYPE_STRUCT ||
2580 t == SD_BUS_TYPE_DICT_ENTRY) {
2582 r = signature_element_length(*signature, &l);
2589 strncpy(sig, *signature + 1, l-1);
2592 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
2603 static int message_parse_fields(sd_bus_message *m) {
2606 uint32_t unix_fds = 0;
2610 for (ri = 0; ri < BUS_MESSAGE_FIELDS_SIZE(m); ) {
2611 const char *signature;
2614 r = message_peek_fields(m, &ri, 8, 1, (void**) &header);
2618 r = message_peek_field_signature(m, &ri, &signature);
2623 case _SD_BUS_MESSAGE_HEADER_INVALID:
2626 case SD_BUS_MESSAGE_HEADER_PATH:
2631 if (!streq(signature, "o"))
2634 r = message_peek_field_string(m, object_path_is_valid, &ri, &m->path);
2637 case SD_BUS_MESSAGE_HEADER_INTERFACE:
2642 if (!streq(signature, "s"))
2645 r = message_peek_field_string(m, interface_name_is_valid, &ri, &m->interface);
2648 case SD_BUS_MESSAGE_HEADER_MEMBER:
2653 if (!streq(signature, "s"))
2656 r = message_peek_field_string(m, member_name_is_valid, &ri, &m->member);
2659 case SD_BUS_MESSAGE_HEADER_ERROR_NAME:
2664 if (!streq(signature, "s"))
2667 r = message_peek_field_string(m, error_name_is_valid, &ri, &m->error.name);
2670 case SD_BUS_MESSAGE_HEADER_DESTINATION:
2675 if (!streq(signature, "s"))
2678 r = message_peek_field_string(m, service_name_is_valid, &ri, &m->destination);
2681 case SD_BUS_MESSAGE_HEADER_SENDER:
2686 if (!streq(signature, "s"))
2689 r = message_peek_field_string(m, service_name_is_valid, &ri, &m->sender);
2693 case SD_BUS_MESSAGE_HEADER_SIGNATURE: {
2697 if (m->root_container.signature)
2700 if (!streq(signature, "g"))
2703 r = message_peek_field_signature(m, &ri, &s);
2711 free(m->root_container.signature);
2712 m->root_container.signature = c;
2716 case SD_BUS_MESSAGE_HEADER_REPLY_SERIAL:
2717 if (m->reply_serial != 0)
2720 if (!streq(signature, "u"))
2723 r = message_peek_field_uint32(m, &ri, &m->reply_serial);
2727 if (m->reply_serial == 0)
2732 case SD_BUS_MESSAGE_HEADER_UNIX_FDS:
2736 if (!streq(signature, "u"))
2739 r = message_peek_field_uint32(m, &ri, &unix_fds);
2749 r = message_skip_fields(m, &ri, (uint32_t) -1, (const char **) &signature);
2756 if (m->n_fds != unix_fds)
2759 if (isempty(m->root_container.signature) != (BUS_MESSAGE_BODY_SIZE(m) == 0))
2762 switch (m->header->type) {
2764 case SD_BUS_MESSAGE_TYPE_SIGNAL:
2765 if (!m->path || !m->interface || !m->member)
2769 case SD_BUS_MESSAGE_TYPE_METHOD_CALL:
2771 if (!m->path || !m->member)
2776 case SD_BUS_MESSAGE_TYPE_METHOD_RETURN:
2778 if (m->reply_serial == 0)
2782 case SD_BUS_MESSAGE_TYPE_METHOD_ERROR:
2784 if (m->reply_serial == 0 || !m->error.name)
2789 /* Try to read the error message, but if we can't it's a non-issue */
2790 if (m->header->type == SD_BUS_MESSAGE_TYPE_METHOD_ERROR)
2791 sd_bus_message_read(m, "s", &m->error.message);
2796 int bus_message_seal(sd_bus_message *m, uint64_t serial) {
2804 if (m->n_containers > 0)
2807 /* If there's a non-trivial signature set, then add it in here */
2808 if (!isempty(m->root_container.signature)) {
2809 r = message_append_field_signature(m, SD_BUS_MESSAGE_HEADER_SIGNATURE, m->root_container.signature, NULL);
2815 r = message_append_field_uint32(m, SD_BUS_MESSAGE_HEADER_UNIX_FDS, m->n_fds);
2820 m->header->serial = serial;
2826 int sd_bus_message_set_destination(sd_bus_message *m, const char *destination) {
2836 return message_append_field_string(m, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &m->destination);
2839 int bus_message_dump(sd_bus_message *m) {
2845 printf("Message %p\n"
2852 "\tfields_size=%u\n"
2857 "\tdestination=%s\n"
2860 "\treply_serial=%u\n"
2862 "\terror.message=%s\n"
2870 BUS_MESSAGE_SERIAL(m),
2871 BUS_MESSAGE_FIELDS_SIZE(m),
2872 BUS_MESSAGE_BODY_SIZE(m),
2874 strna(m->interface),
2876 strna(m->destination),
2878 strna(m->root_container.signature),
2880 strna(m->error.name),
2881 strna(m->error.message),
2884 r = sd_bus_message_rewind(m, true);
2886 log_error("Failed to rewind: %s", strerror(-r));
2890 printf("BEGIN_MESSAGE \"%s\" {\n", strempty(m->root_container.signature));
2893 _cleanup_free_ char *prefix = NULL;
2894 const char *contents = NULL;
2909 r = sd_bus_message_peek_type(m, &type, &contents);
2911 log_error("Failed to peek type: %s", strerror(-r));
2918 r = sd_bus_message_exit_container(m);
2920 log_error("Failed to exit container: %s", strerror(-r));
2926 prefix = strrep("\t", level);
2930 if (type == SD_BUS_TYPE_ARRAY)
2931 printf("%s} END_ARRAY \n", prefix);
2932 else if (type == SD_BUS_TYPE_VARIANT)
2933 printf("%s} END_VARIANT\n", prefix);
2934 else if (type == SD_BUS_TYPE_STRUCT)
2935 printf("%s} END_STRUCT\n", prefix);
2936 else if (type == SD_BUS_TYPE_DICT_ENTRY)
2937 printf("%s} END_DICT_ENTRY\n", prefix);
2942 prefix = strrep("\t", level);
2946 if (bus_type_is_container(type) > 0) {
2947 r = sd_bus_message_enter_container(m, type, contents);
2949 log_error("Failed to enter container: %s", strerror(-r));
2953 if (type == SD_BUS_TYPE_ARRAY)
2954 printf("%sBEGIN_ARRAY \"%s\" {\n", prefix, contents);
2955 else if (type == SD_BUS_TYPE_VARIANT)
2956 printf("%sBEGIN_VARIANT \"%s\" {\n", prefix, contents);
2957 else if (type == SD_BUS_TYPE_STRUCT)
2958 printf("%sBEGIN_STRUCT \"%s\" {\n", prefix, contents);
2959 else if (type == SD_BUS_TYPE_DICT_ENTRY)
2960 printf("%sBEGIN_DICT_ENTRY \"%s\" {\n", prefix, contents);
2967 r = sd_bus_message_read_basic(m, type, &basic);
2969 log_error("Failed to get basic: %s", strerror(-r));
2975 case SD_BUS_TYPE_BYTE:
2976 printf("%sBYTE: %u\n", prefix, basic.u8);
2979 case SD_BUS_TYPE_BOOLEAN:
2980 printf("%sBOOLEAN: %s\n", prefix, yes_no(basic.i));
2983 case SD_BUS_TYPE_INT16:
2984 printf("%sINT16: %i\n", prefix, basic.s16);
2987 case SD_BUS_TYPE_UINT16:
2988 printf("%sUINT16: %u\n", prefix, basic.u16);
2991 case SD_BUS_TYPE_INT32:
2992 printf("%sINT32: %i\n", prefix, basic.s32);
2995 case SD_BUS_TYPE_UINT32:
2996 printf("%sUINT32: %u\n", prefix, basic.u32);
2999 case SD_BUS_TYPE_INT64:
3000 printf("%sINT64: %lli\n", prefix, (long long) basic.s64);
3003 case SD_BUS_TYPE_UINT64:
3004 printf("%sUINT64: %llu\n", prefix, (unsigned long long) basic.u64);
3007 case SD_BUS_TYPE_DOUBLE:
3008 printf("%sDOUBLE: %g\n", prefix, basic.d64);
3011 case SD_BUS_TYPE_STRING:
3012 printf("%sSTRING: \"%s\"\n", prefix, basic.string);
3015 case SD_BUS_TYPE_OBJECT_PATH:
3016 printf("%sOBJECT_PATH: \"%s\"\n", prefix, basic.string);
3019 case SD_BUS_TYPE_SIGNATURE:
3020 printf("%sSIGNATURE: \"%s\"\n", prefix, basic.string);
3023 case SD_BUS_TYPE_UNIX_FD:
3024 printf("%sUNIX_FD: %i\n", prefix, basic.i);
3028 assert_not_reached("Unknown basic type.");
3032 printf("} END_MESSAGE\n");
3036 int bus_message_get_blob(sd_bus_message *m, void **buffer, size_t *sz) {
3044 total = bus_message_size(m);
3050 e = mempcpy(p, m->header, sizeof(*m->header));
3053 e = mempcpy(e, m->fields, m->header->fields_size);
3055 if (m->header->fields_size % 8 != 0)
3056 e = mempset(e, 0, 8 - (m->header->fields_size % 8));
3060 e = mempcpy(e, m->body, m->header->body_size);
3062 assert(total == (size_t) ((uint8_t*) e - (uint8_t*) p));
3070 int bus_message_read_strv_extend(sd_bus_message *m, char ***l) {
3076 r = sd_bus_message_enter_container(m, 'a', "s");
3083 r = sd_bus_message_read_basic(m, 's', &s);
3089 r = strv_extend(l, s);
3094 r = sd_bus_message_exit_container(m);
3101 const char* bus_message_get_arg(sd_bus_message *m, unsigned i) {
3108 r = sd_bus_message_rewind(m, true);
3113 r = sd_bus_message_peek_type(m, &type, NULL);
3117 if (type != SD_BUS_TYPE_STRING &&
3118 type != SD_BUS_TYPE_OBJECT_PATH &&
3119 type != SD_BUS_TYPE_SIGNATURE)
3122 r = sd_bus_message_read_basic(m, type, &t);
3129 r = sd_bus_message_rewind(m, true);
3136 size_t bus_message_size(sd_bus_message *m) {
3141 sizeof(*m->header) +
3142 ALIGN8(m->header->fields_size) +
3143 m->header->body_size;