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);
73 free(m->cmdline_array);
76 free(m->root_container.signature);
78 free(m->peeked_signature);
82 static void* buffer_extend(void **p, uint32_t *sz, size_t align, size_t extend) {
90 start = ALIGN_TO((size_t) *sz, align);
94 return (uint8_t*) *p + start;
96 if (n > (size_t) ((uint32_t) -1))
103 /* Zero out padding */
105 memset((uint8_t*) k + *sz, 0, start - *sz);
110 return (uint8_t*) k + start;
113 static void *message_extend_fields(sd_bus_message *m, size_t align, size_t sz) {
119 p = buffer_extend(&m->fields, &m->header->fields_size, align, sz);
123 if (o != m->fields) {
124 /* Adjust quick access pointers */
127 m->path = (const char*) m->fields + (m->path - (const char*) o);
129 m->interface = (const char*) m->fields + (m->interface - (const char*) o);
131 m->member = (const char*) m->fields + (m->member - (const char*) o);
133 m->destination = (const char*) m->fields + (m->destination - (const char*) o);
135 m->sender = (const char*) m->fields + (m->sender - (const char*) o);
137 m->error.name = (const char*) m->fields + (m->error.name - (const char*) o);
140 m->free_fields = true;
145 static int message_append_field_string(
158 if (l > (size_t) (uint32_t) -1)
161 /* field id byte + signature length + signature 's' + NUL + string length + string + NUL */
162 p = message_extend_fields(m, 8, 4 + 4 + l + 1);
171 ((uint32_t*) p)[1] = l;
172 memcpy(p + 8, s, l + 1);
175 *ret = (const char*) p + 8;
180 static int message_append_field_signature(
195 /* field id byte + signature length + signature 'g' + NUL + string length + string + NUL */
196 p = message_extend_fields(m, 8, 4 + 1 + l + 1);
202 p[2] = SD_BUS_TYPE_SIGNATURE;
205 memcpy(p + 5, s, l + 1);
208 *ret = (const char*) p + 5;
213 static int message_append_field_uint32(sd_bus_message *m, uint8_t h, uint32_t x) {
218 /* field id byte + signature length + signature 'u' + NUL + value */
219 p = message_extend_fields(m, 8, 4 + 4);
225 p[2] = SD_BUS_TYPE_UINT32;
228 ((uint32_t*) p)[1] = x;
233 int bus_message_from_header(
238 const struct ucred *ucred,
241 sd_bus_message **ret) {
244 struct bus_header *h;
247 assert(buffer || length <= 0);
248 assert(fds || n_fds <= 0);
251 if (length < sizeof(struct bus_header))
261 if (h->type == _SD_BUS_MESSAGE_TYPE_INVALID)
264 if (h->endian != SD_BUS_LITTLE_ENDIAN &&
265 h->endian != SD_BUS_BIG_ENDIAN)
268 a = ALIGN(sizeof(sd_bus_message)) + ALIGN(extra);
271 label_sz = strlen(label);
289 m->uid_valid = m->gid_valid = true;
293 m->label = (char*) m + ALIGN(sizeof(sd_bus_message)) + ALIGN(extra);
294 memcpy(m->label, label, label_sz + 1);
301 int bus_message_from_malloc(
306 const struct ucred *ucred,
308 sd_bus_message **ret) {
313 r = bus_message_from_header(buffer, length, fds, n_fds, ucred, label, 0, &m);
317 if (length != BUS_MESSAGE_SIZE(m)) {
322 m->fields = (uint8_t*) buffer + sizeof(struct bus_header);
323 m->body = (uint8_t*) buffer + sizeof(struct bus_header) + ALIGN8(BUS_MESSAGE_FIELDS_SIZE(m));
326 m->iovec[0].iov_base = buffer;
327 m->iovec[0].iov_len = length;
329 r = bus_message_parse_fields(m);
333 /* We take possession of the memory and fds now */
334 m->free_header = true;
345 static sd_bus_message *message_new(sd_bus *bus, uint8_t type) {
348 m = malloc0(ALIGN(sizeof(sd_bus_message)) + sizeof(struct bus_header));
353 m->header = (struct bus_header*) ((uint8_t*) m + ALIGN(sizeof(struct sd_bus_message)));
354 m->header->endian = SD_BUS_NATIVE_ENDIAN;
355 m->header->type = type;
356 m->header->version = bus ? bus->message_version : 1;
357 m->allow_fds = !bus || bus->can_fds || (bus->state != BUS_HELLO && bus->state != BUS_RUNNING);
362 int sd_bus_message_new_signal(
365 const char *interface,
367 sd_bus_message **m) {
380 if (bus && bus->state == BUS_UNSET)
383 t = message_new(bus, SD_BUS_MESSAGE_TYPE_SIGNAL);
387 t->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
389 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_PATH, SD_BUS_TYPE_OBJECT_PATH, path, &t->path);
392 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_INTERFACE, SD_BUS_TYPE_STRING, interface, &t->interface);
395 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_MEMBER, SD_BUS_TYPE_STRING, member, &t->member);
403 sd_bus_message_unref(t);
407 int sd_bus_message_new_method_call(
409 const char *destination,
411 const char *interface,
413 sd_bus_message **m) {
424 if (bus && bus->state == BUS_UNSET)
427 t = message_new(bus, SD_BUS_MESSAGE_TYPE_METHOD_CALL);
431 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_PATH, SD_BUS_TYPE_OBJECT_PATH, path, &t->path);
434 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_MEMBER, SD_BUS_TYPE_STRING, member, &t->member);
439 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_INTERFACE, SD_BUS_TYPE_STRING, interface, &t->interface);
445 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &t->destination);
458 static int message_new_reply(
460 sd_bus_message *call,
462 sd_bus_message **m) {
471 if (call->header->type != SD_BUS_MESSAGE_TYPE_METHOD_CALL)
475 if (bus && bus->state == BUS_UNSET)
478 t = message_new(bus, type);
482 t->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
483 t->reply_serial = BUS_MESSAGE_SERIAL(call);
485 r = message_append_field_uint32(t, SD_BUS_MESSAGE_HEADER_REPLY_SERIAL, t->reply_serial);
490 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, call->sender, &t->sender);
495 t->dont_send = !!(call->header->flags & SD_BUS_MESSAGE_NO_REPLY_EXPECTED);
505 int sd_bus_message_new_method_return(
507 sd_bus_message *call,
508 sd_bus_message **m) {
510 return message_new_reply(bus, call, SD_BUS_MESSAGE_TYPE_METHOD_RETURN, m);
513 int sd_bus_message_new_method_error(
515 sd_bus_message *call,
516 const sd_bus_error *e,
517 sd_bus_message **m) {
522 if (!sd_bus_error_is_set(e))
527 r = message_new_reply(bus, call, SD_BUS_MESSAGE_TYPE_METHOD_ERROR, &t);
531 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_ERROR_NAME, SD_BUS_TYPE_STRING, e->name, &t->error.name);
536 r = message_append_basic(t, SD_BUS_TYPE_STRING, e->message, (const void**) &t->error.message);
549 sd_bus_message* sd_bus_message_ref(sd_bus_message *m) {
553 assert(m->n_ref > 0);
559 sd_bus_message* sd_bus_message_unref(sd_bus_message *m) {
563 assert(m->n_ref > 0);
572 int sd_bus_message_get_type(sd_bus_message *m, uint8_t *type) {
578 *type = m->header->type;
582 int sd_bus_message_get_serial(sd_bus_message *m, uint64_t *serial) {
587 if (m->header->serial == 0)
590 *serial = BUS_MESSAGE_SERIAL(m);
594 int sd_bus_message_get_reply_serial(sd_bus_message *m, uint64_t *serial) {
599 if (m->reply_serial == 0)
602 *serial = m->reply_serial;
606 int sd_bus_message_get_no_reply(sd_bus_message *m) {
610 return m->header->type == SD_BUS_MESSAGE_TYPE_METHOD_CALL ? !!(m->header->flags & SD_BUS_MESSAGE_NO_REPLY_EXPECTED) : 0;
613 const char *sd_bus_message_get_path(sd_bus_message *m) {
620 const char *sd_bus_message_get_interface(sd_bus_message *m) {
627 const char *sd_bus_message_get_member(sd_bus_message *m) {
633 const char *sd_bus_message_get_destination(sd_bus_message *m) {
637 return m->destination;
640 const char *sd_bus_message_get_sender(sd_bus_message *m) {
647 const sd_bus_error *sd_bus_message_get_error(sd_bus_message *m) {
651 if (!sd_bus_error_is_set(&m->error))
657 int sd_bus_message_get_uid(sd_bus_message *m, uid_t *uid) {
669 int sd_bus_message_get_gid(sd_bus_message *m, gid_t *gid) {
681 int sd_bus_message_get_pid(sd_bus_message *m, pid_t *pid) {
693 int sd_bus_message_get_tid(sd_bus_message *m, pid_t *tid) {
705 int sd_bus_message_get_pid_starttime(sd_bus_message *m, uint64_t *usec) {
710 if (m->pid_starttime <= 0)
713 *usec = m->pid_starttime;
717 int sd_bus_message_get_selinux_context(sd_bus_message *m, const char **ret) {
727 int sd_bus_message_get_monotonic_timestamp(sd_bus_message *m, uint64_t *usec) {
732 if (m->monotonic <= 0)
735 *usec = m->monotonic;
739 int sd_bus_message_get_realtime_timestamp(sd_bus_message *m, uint64_t *usec) {
744 if (m->realtime <= 0)
751 int sd_bus_message_get_comm(sd_bus_message *m, const char **ret) {
763 int sd_bus_message_get_tid_comm(sd_bus_message *m, const char **ret) {
775 int sd_bus_message_get_exe(sd_bus_message *m, const char **ret) {
787 int sd_bus_message_get_cgroup(sd_bus_message *m, const char **ret) {
799 int sd_bus_message_get_cmdline(sd_bus_message *m, char ***cmdline) {
810 for (p = m->cmdline, n = 0; p < m->cmdline + m->cmdline_length; p++)
814 m->cmdline_array = new(char*, n + 1);
815 if (!m->cmdline_array)
818 for (p = m->cmdline, i = 0, first = true; p < m->cmdline + m->cmdline_length; p++) {
820 m->cmdline_array[i++] = (char*) p;
825 m->cmdline_array[i] = NULL;
826 *cmdline = m->cmdline_array;
831 int sd_bus_message_is_signal(sd_bus_message *m, const char *interface, const char *member) {
835 if (m->header->type != SD_BUS_MESSAGE_TYPE_SIGNAL)
838 if (interface && (!m->interface || !streq(m->interface, interface)))
841 if (member && (!m->member || !streq(m->member, member)))
847 int sd_bus_message_is_method_call(sd_bus_message *m, const char *interface, const char *member) {
851 if (m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_CALL)
854 if (interface && (!m->interface || !streq(m->interface, interface)))
857 if (member && (!m->member || !streq(m->member, member)))
863 int sd_bus_message_is_method_error(sd_bus_message *m, const char *name) {
867 if (m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_ERROR)
870 if (name && (!m->error.name || !streq(m->error.name, name)))
876 int sd_bus_message_set_no_reply(sd_bus_message *m, int b) {
881 if (m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_CALL)
885 m->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
887 m->header->flags &= ~SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
892 static struct bus_container *message_get_container(sd_bus_message *m) {
895 if (m->n_containers == 0)
896 return &m->root_container;
898 assert(m->containers);
899 return m->containers + m->n_containers - 1;
902 static void *message_extend_body(sd_bus_message *m, size_t align, size_t sz) {
905 struct bus_container *c;
911 added = m->header->body_size;
913 p = buffer_extend(&m->body, &m->header->body_size, align, sz);
917 added = m->header->body_size - added;
919 for (c = m->containers; c < m->containers + m->n_containers; c++)
921 c->array_size = (uint32_t*) ((uint8_t*) m->body + ((uint8_t*) c->array_size - (uint8_t*) o));
922 *c->array_size += added;
926 if (m->error.message)
927 m->error.message = (const char*) m->body + (m->error.message - (const char*) o);
935 int message_append_basic(sd_bus_message *m, char type, const void *p, const void **stored) {
936 struct bus_container *c;
951 if (!bus_type_is_basic(type))
954 c = message_get_container(m);
956 if (c->signature && c->signature[c->index]) {
957 /* Container signature is already set */
959 if (c->signature[c->index] != type)
962 /* Maybe we can append to the signature? But only if this is the top-level container*/
963 if (c->enclosing != 0)
966 e = strextend(&c->signature, CHAR_TO_STR(type), NULL);
973 case SD_BUS_TYPE_STRING:
974 case SD_BUS_TYPE_OBJECT_PATH:
977 sz = 4 + strlen(p) + 1;
980 case SD_BUS_TYPE_SIGNATURE:
983 sz = 1 + strlen(p) + 1;
986 case SD_BUS_TYPE_BOOLEAN:
989 assert_cc(sizeof(int) == sizeof(uint32_t));
995 case SD_BUS_TYPE_UNIX_FD: {
1011 fd = fcntl(z, F_DUPFD_CLOEXEC, 3);
1017 f = realloc(m->fds, sizeof(int) * (m->n_fds + 1));
1031 align = bus_type_get_alignment(type);
1032 sz = bus_type_get_size(type);
1039 a = message_extend_body(m, align, sz);
1045 if (type == SD_BUS_TYPE_STRING || type == SD_BUS_TYPE_OBJECT_PATH) {
1046 *(uint32_t*) a = sz - 5;
1047 memcpy((uint8_t*) a + 4, p, sz - 4);
1050 *stored = (const uint8_t*) a + 4;
1052 } else if (type == SD_BUS_TYPE_SIGNATURE) {
1053 *(uint8_t*) a = sz - 1;
1054 memcpy((uint8_t*) a + 1, p, sz - 1);
1057 *stored = (const uint8_t*) a + 1;
1058 } else if (type == SD_BUS_TYPE_UNIX_FD) {
1059 *(uint32_t*) a = fdi;
1073 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1079 /* Truncate extended signature again */
1081 c->signature[c->index] = 0;
1084 close_nointr_nofail(fd);
1089 int sd_bus_message_append_basic(sd_bus_message *m, char type, const void *p) {
1090 return message_append_basic(m, type, p, NULL);
1093 static int bus_message_open_array(
1095 struct bus_container *c,
1096 const char *contents,
1097 uint32_t **array_size) {
1110 if (!signature_is_single(contents))
1113 alignment = bus_type_get_alignment(contents[0]);
1117 if (c->signature && c->signature[c->index]) {
1119 /* Verify the existing signature */
1121 if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
1124 if (!startswith(c->signature + c->index + 1, contents))
1127 nindex = c->index + 1 + strlen(contents);
1129 if (c->enclosing != 0)
1132 /* Extend the existing signature */
1134 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_ARRAY), contents, NULL);
1138 nindex = e - c->signature;
1141 saved = m->header->body_size;
1142 a = message_extend_body(m, 4, 4);
1144 /* Truncate extended signature again */
1146 c->signature[c->index] = 0;
1152 if (!message_extend_body(m, alignment, 0)) {
1153 /* Add alignment between size and first element */
1155 c->signature[c->index] = 0;
1157 m->header->body_size = saved;
1161 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1164 /* m->body might have changed so let's readjust a */
1165 a = (uint8_t*) m->body + ((uint8_t*) a - (uint8_t*) b);
1172 static int bus_message_open_variant(
1174 struct bus_container *c,
1175 const char *contents) {
1185 if (!signature_is_single(contents))
1188 if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
1191 if (c->signature && c->signature[c->index]) {
1193 if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
1197 if (c->enclosing != 0)
1200 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_VARIANT), NULL);
1205 l = strlen(contents);
1206 a = message_extend_body(m, 1, 1 + l + 1);
1208 /* Truncate extended signature again */
1210 c->signature[c->index] = 0;
1216 memcpy((uint8_t*) a + 1, contents, l + 1);
1218 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1224 static int bus_message_open_struct(
1226 struct bus_container *c,
1227 const char *contents) {
1236 if (!signature_is_valid(contents, false))
1239 if (c->signature && c->signature[c->index]) {
1242 l = strlen(contents);
1244 if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
1245 !startswith(c->signature + c->index + 1, contents) ||
1246 c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
1249 nindex = c->index + 1 + l + 1;
1251 if (c->enclosing != 0)
1254 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_BEGIN), contents, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_END), NULL);
1258 nindex = e - c->signature;
1261 /* Align contents to 8 byte boundary */
1262 if (!message_extend_body(m, 8, 0)) {
1264 c->signature[c->index] = 0;
1269 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1275 static int bus_message_open_dict_entry(
1277 struct bus_container *c,
1278 const char *contents) {
1286 if (!signature_is_pair(contents))
1289 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1292 if (c->signature && c->signature[c->index]) {
1295 l = strlen(contents);
1297 if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
1298 !startswith(c->signature + c->index + 1, contents) ||
1299 c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
1302 nindex = c->index + 1 + l + 1;
1306 /* Align contents to 8 byte boundary */
1307 if (!message_extend_body(m, 8, 0))
1310 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1316 int sd_bus_message_open_container(
1319 const char *contents) {
1321 struct bus_container *c, *w;
1322 uint32_t *array_size = NULL;
1333 /* Make sure we have space for one more container */
1334 w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
1339 c = message_get_container(m);
1341 signature = strdup(contents);
1345 if (type == SD_BUS_TYPE_ARRAY)
1346 r = bus_message_open_array(m, c, contents, &array_size);
1347 else if (type == SD_BUS_TYPE_VARIANT)
1348 r = bus_message_open_variant(m, c, contents);
1349 else if (type == SD_BUS_TYPE_STRUCT)
1350 r = bus_message_open_struct(m, c, contents);
1351 else if (type == SD_BUS_TYPE_DICT_ENTRY)
1352 r = bus_message_open_dict_entry(m, c, contents);
1361 /* OK, let's fill it in */
1362 w += m->n_containers++;
1363 w->enclosing = type;
1364 w->signature = signature;
1366 w->array_size = array_size;
1372 int sd_bus_message_close_container(sd_bus_message *m) {
1373 struct bus_container *c;
1379 if (m->n_containers <= 0)
1382 c = message_get_container(m);
1383 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1384 if (c->signature && c->signature[c->index] != 0)
1400 static int type_stack_push(TypeStack *stack, unsigned max, unsigned *i, const char *types, unsigned n_struct, unsigned n_array) {
1407 stack[*i].types = types;
1408 stack[*i].n_struct = n_struct;
1409 stack[*i].n_array = n_array;
1415 static int type_stack_pop(TypeStack *stack, unsigned max, unsigned *i, const char **types, unsigned *n_struct, unsigned *n_array) {
1426 *types = stack[*i].types;
1427 *n_struct = stack[*i].n_struct;
1428 *n_array = stack[*i].n_array;
1433 int bus_message_append_ap(
1438 unsigned n_array, n_struct;
1439 TypeStack stack[BUS_CONTAINER_DEPTH];
1440 unsigned stack_ptr = 0;
1448 n_array = (unsigned) -1;
1449 n_struct = strlen(types);
1454 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
1455 r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
1461 r = sd_bus_message_close_container(m);
1469 if (n_array != (unsigned) -1)
1478 case SD_BUS_TYPE_BYTE: {
1481 x = (uint8_t) va_arg(ap, int);
1482 r = sd_bus_message_append_basic(m, *t, &x);
1486 case SD_BUS_TYPE_BOOLEAN:
1487 case SD_BUS_TYPE_INT32:
1488 case SD_BUS_TYPE_UINT32:
1489 case SD_BUS_TYPE_UNIX_FD: {
1492 /* We assume a boolean is the same as int32_t */
1493 assert_cc(sizeof(int32_t) == sizeof(int));
1495 x = va_arg(ap, uint32_t);
1496 r = sd_bus_message_append_basic(m, *t, &x);
1500 case SD_BUS_TYPE_INT16:
1501 case SD_BUS_TYPE_UINT16: {
1504 x = (uint16_t) va_arg(ap, int);
1505 r = sd_bus_message_append_basic(m, *t, &x);
1509 case SD_BUS_TYPE_INT64:
1510 case SD_BUS_TYPE_UINT64:
1511 case SD_BUS_TYPE_DOUBLE: {
1514 x = va_arg(ap, uint64_t);
1515 r = sd_bus_message_append_basic(m, *t, &x);
1519 case SD_BUS_TYPE_STRING:
1520 case SD_BUS_TYPE_OBJECT_PATH:
1521 case SD_BUS_TYPE_SIGNATURE: {
1524 x = va_arg(ap, const char*);
1525 r = sd_bus_message_append_basic(m, *t, x);
1529 case SD_BUS_TYPE_ARRAY: {
1532 r = signature_element_length(t + 1, &k);
1538 memcpy(s, t + 1, k);
1541 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, s);
1546 if (n_array == (unsigned) -1) {
1551 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
1557 n_array = va_arg(ap, unsigned);
1562 case SD_BUS_TYPE_VARIANT: {
1565 s = va_arg(ap, const char*);
1569 r = sd_bus_message_open_container(m, SD_BUS_TYPE_VARIANT, s);
1573 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
1578 n_struct = strlen(s);
1579 n_array = (unsigned) -1;
1584 case SD_BUS_TYPE_STRUCT_BEGIN:
1585 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
1588 r = signature_element_length(t, &k);
1595 memcpy(s, t + 1, k - 2);
1598 r = sd_bus_message_open_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
1603 if (n_array == (unsigned) -1) {
1608 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
1614 n_array = (unsigned) -1;
1630 int sd_bus_message_append(sd_bus_message *m, const char *types, ...) {
1641 va_start(ap, types);
1642 r = bus_message_append_ap(m, types, ap);
1648 static int buffer_peek(const void *p, uint32_t sz, size_t *rindex, size_t align, size_t nbytes, void **r) {
1654 start = ALIGN_TO((size_t) *rindex, align);
1660 /* Verify that padding is 0 */
1661 for (k = *rindex; k < start; k++)
1662 if (((const uint8_t*) p)[k] != 0)
1666 *r = (uint8_t*) p + start;
1673 static bool message_end_of_array(sd_bus_message *m, size_t index) {
1674 struct bus_container *c;
1678 c = message_get_container(m);
1682 return index >= c->begin + BUS_MESSAGE_BSWAP32(m, *c->array_size);
1685 static int message_peek_body(sd_bus_message *m, size_t *rindex, size_t align, size_t nbytes, void **ret) {
1690 if (message_end_of_array(m, *rindex))
1693 return buffer_peek(m->body, BUS_MESSAGE_BODY_SIZE(m), rindex, align, nbytes, ret);
1696 static bool validate_nul(const char *s, size_t l) {
1698 /* Check for NUL chars in the string */
1699 if (memchr(s, 0, l))
1702 /* Check for NUL termination */
1709 static bool validate_string(const char *s, size_t l) {
1711 if (!validate_nul(s, l))
1714 /* Check if valid UTF8 */
1715 if (!utf8_is_valid(s))
1721 static bool validate_signature(const char *s, size_t l) {
1723 if (!validate_nul(s, l))
1726 /* Check if valid signature */
1727 if (!signature_is_valid(s, true))
1733 static bool validate_object_path(const char *s, size_t l) {
1735 if (!validate_nul(s, l))
1738 if (!object_path_is_valid(s))
1744 int sd_bus_message_read_basic(sd_bus_message *m, char type, void *p) {
1745 struct bus_container *c;
1753 if (!bus_type_is_basic(type))
1758 c = message_get_container(m);
1760 if (!c->signature || c->signature[c->index] == 0)
1763 if (c->signature[c->index] != type)
1768 case SD_BUS_TYPE_STRING:
1769 case SD_BUS_TYPE_OBJECT_PATH: {
1774 r = message_peek_body(m, &rindex, 4, 4, &q);
1778 l = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
1779 r = message_peek_body(m, &rindex, 1, l+1, &q);
1785 if (type == SD_BUS_TYPE_OBJECT_PATH) {
1786 if (!validate_object_path(q, l))
1789 if (!validate_string(q, l))
1794 *(const char**) p = q;
1798 case SD_BUS_TYPE_SIGNATURE: {
1803 r = message_peek_body(m, &rindex, 1, 1, &q);
1808 r = message_peek_body(m, &rindex, 1, l+1, &q);
1814 if (!validate_signature(q, l))
1818 *(const char**) p = q;
1826 align = bus_type_get_alignment(type);
1827 sz = bus_type_get_size(type);
1828 assert(align > 0 && sz > 0);
1831 r = message_peek_body(m, &rindex, align, sz, &q);
1837 case SD_BUS_TYPE_BYTE:
1838 *(uint8_t*) p = *(uint8_t*) q;
1841 case SD_BUS_TYPE_BOOLEAN:
1842 *(int*) p = !!*(uint32_t*) q;
1845 case SD_BUS_TYPE_INT16:
1846 case SD_BUS_TYPE_UINT16:
1847 *(uint16_t*) p = BUS_MESSAGE_BSWAP16(m, *(uint16_t*) q);
1850 case SD_BUS_TYPE_INT32:
1851 case SD_BUS_TYPE_UINT32:
1852 *(uint32_t*) p = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
1855 case SD_BUS_TYPE_INT64:
1856 case SD_BUS_TYPE_UINT64:
1857 case SD_BUS_TYPE_DOUBLE:
1858 *(uint64_t*) p = BUS_MESSAGE_BSWAP64(m, *(uint64_t*) q);
1861 case SD_BUS_TYPE_UNIX_FD: {
1864 j = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
1868 *(int*) p = m->fds[j];
1873 assert_not_reached("Unknown basic type...");
1882 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1888 static int bus_message_enter_array(
1890 struct bus_container *c,
1891 const char *contents,
1892 uint32_t **array_size) {
1903 if (!signature_is_single(contents))
1906 alignment = bus_type_get_alignment(contents[0]);
1910 if (!c->signature || c->signature[c->index] == 0)
1913 if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
1916 if (!startswith(c->signature + c->index + 1, contents))
1920 r = message_peek_body(m, &rindex, 4, 4, &q);
1924 if (BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q) > BUS_ARRAY_MAX_SIZE)
1927 r = message_peek_body(m, &rindex, alignment, 0, NULL);
1933 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1934 c->index += 1 + strlen(contents);
1938 *array_size = (uint32_t*) q;
1943 static int bus_message_enter_variant(
1945 struct bus_container *c,
1946 const char *contents) {
1957 if (!signature_is_single(contents))
1960 if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
1963 if (!c->signature || c->signature[c->index] == 0)
1966 if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
1970 r = message_peek_body(m, &rindex, 1, 1, &q);
1975 r = message_peek_body(m, &rindex, 1, l+1, &q);
1981 if (!validate_signature(q, l))
1984 if (!streq(q, contents))
1987 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1995 static int bus_message_enter_struct(
1997 struct bus_container *c,
1998 const char *contents) {
2007 if (!signature_is_valid(contents, false))
2010 if (!c->signature || c->signature[c->index] == 0)
2013 l = strlen(contents);
2015 if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
2016 !startswith(c->signature + c->index + 1, contents) ||
2017 c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
2020 r = message_peek_body(m, &m->rindex, 8, 0, NULL);
2024 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2025 c->index += 1 + l + 1;
2030 static int bus_message_enter_dict_entry(
2032 struct bus_container *c,
2033 const char *contents) {
2042 if (!signature_is_pair(contents))
2045 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2048 if (!c->signature || c->signature[c->index] == 0)
2051 l = strlen(contents);
2053 if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
2054 !startswith(c->signature + c->index + 1, contents) ||
2055 c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
2058 r = message_peek_body(m, &m->rindex, 8, 0, NULL);
2062 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2063 c->index += 1 + l + 1;
2068 int sd_bus_message_enter_container(sd_bus_message *m, char type, const char *contents) {
2069 struct bus_container *c, *w;
2070 uint32_t *array_size = NULL;
2082 * We enforce a global limit on container depth, that is much
2083 * higher than the 32 structs and 32 arrays the specification
2084 * mandates. This is simpler to implement for us, and we need
2085 * this only to ensure our container array doesn't grow
2086 * without bounds. We are happy to return any data from a
2087 * message as long as the data itself is valid, even if the
2088 * overall message might be not.
2090 * Note that the message signature is validated when
2091 * parsing the headers, and that validation does check the
2094 * Note that the specification defines no limits on the depth
2095 * of stacked variants, but we do.
2097 if (m->n_containers >= BUS_CONTAINER_DEPTH)
2100 w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
2105 c = message_get_container(m);
2107 if (!c->signature || c->signature[c->index] == 0)
2110 signature = strdup(contents);
2114 if (type == SD_BUS_TYPE_ARRAY)
2115 r = bus_message_enter_array(m, c, contents, &array_size);
2116 else if (type == SD_BUS_TYPE_VARIANT)
2117 r = bus_message_enter_variant(m, c, contents);
2118 else if (type == SD_BUS_TYPE_STRUCT)
2119 r = bus_message_enter_struct(m, c, contents);
2120 else if (type == SD_BUS_TYPE_DICT_ENTRY)
2121 r = bus_message_enter_dict_entry(m, c, contents);
2130 /* OK, let's fill it in */
2131 w += m->n_containers++;
2132 w->enclosing = type;
2133 w->signature = signature;
2135 w->array_size = array_size;
2136 w->begin = m->rindex;
2141 int sd_bus_message_exit_container(sd_bus_message *m) {
2142 struct bus_container *c;
2148 if (m->n_containers <= 0)
2151 c = message_get_container(m);
2152 if (c->enclosing == SD_BUS_TYPE_ARRAY) {
2155 l = BUS_MESSAGE_BSWAP32(m, *c->array_size);
2156 if (c->begin + l != m->rindex)
2160 if (c->signature && c->signature[c->index] != 0)
2170 int sd_bus_message_peek_type(sd_bus_message *m, char *type, const char **contents) {
2171 struct bus_container *c;
2179 c = message_get_container(m);
2181 if (!c->signature || c->signature[c->index] == 0)
2184 if (message_end_of_array(m, m->rindex))
2187 if (bus_type_is_basic(c->signature[c->index])) {
2191 *type = c->signature[c->index];
2195 if (c->signature[c->index] == SD_BUS_TYPE_ARRAY) {
2201 r = signature_element_length(c->signature+c->index+1, &l);
2207 sig = strndup(c->signature + c->index + 1, l);
2211 free(m->peeked_signature);
2212 m->peeked_signature = sig;
2218 *type = SD_BUS_TYPE_ARRAY;
2223 if (c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ||
2224 c->signature[c->index] == SD_BUS_TYPE_DICT_ENTRY_BEGIN) {
2230 r = signature_element_length(c->signature+c->index, &l);
2235 sig = strndup(c->signature + c->index + 1, l - 2);
2239 free(m->peeked_signature);
2240 m->peeked_signature = sig;
2246 *type = c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY;
2251 if (c->signature[c->index] == SD_BUS_TYPE_VARIANT) {
2257 r = message_peek_body(m, &rindex, 1, 1, &q);
2264 r = message_peek_body(m, &rindex, 1, l+1, &q);
2270 if (!validate_signature(q, l))
2277 *type = SD_BUS_TYPE_VARIANT;
2286 *type = c->enclosing;
2292 int sd_bus_message_rewind(sd_bus_message *m, int complete) {
2293 struct bus_container *c;
2301 reset_containers(m);
2303 m->root_container.index = 0;
2305 c = message_get_container(m);
2307 c = message_get_container(m);
2310 m->rindex = c->begin;
2313 return !isempty(c->signature);
2315 static int message_read_ap(
2320 unsigned n_array, n_struct;
2321 TypeStack stack[BUS_CONTAINER_DEPTH];
2322 unsigned stack_ptr = 0;
2330 /* Ideally, we'd just call ourselves recursively on every
2331 * complex type. However, the state of a va_list that is
2332 * passed to a function is undefined after that function
2333 * returns. This means we need to docode the va_list linearly
2334 * in a single stackframe. We hence implement our own
2335 * home-grown stack in an array. */
2337 n_array = (unsigned) -1;
2338 n_struct = strlen(types);
2343 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
2344 r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
2350 r = sd_bus_message_exit_container(m);
2358 if (n_array != (unsigned) -1)
2367 case SD_BUS_TYPE_BYTE:
2368 case SD_BUS_TYPE_BOOLEAN:
2369 case SD_BUS_TYPE_INT16:
2370 case SD_BUS_TYPE_UINT16:
2371 case SD_BUS_TYPE_INT32:
2372 case SD_BUS_TYPE_UINT32:
2373 case SD_BUS_TYPE_INT64:
2374 case SD_BUS_TYPE_UINT64:
2375 case SD_BUS_TYPE_DOUBLE:
2376 case SD_BUS_TYPE_STRING:
2377 case SD_BUS_TYPE_OBJECT_PATH:
2378 case SD_BUS_TYPE_SIGNATURE:
2379 case SD_BUS_TYPE_UNIX_FD: {
2382 p = va_arg(ap, void*);
2383 r = sd_bus_message_read_basic(m, *t, p);
2392 case SD_BUS_TYPE_ARRAY: {
2395 r = signature_element_length(t + 1, &k);
2401 memcpy(s, t + 1, k);
2404 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, s);
2411 if (n_array == (unsigned) -1) {
2416 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2422 n_array = va_arg(ap, unsigned);
2427 case SD_BUS_TYPE_VARIANT: {
2430 s = va_arg(ap, const char *);
2434 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, s);
2440 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2445 n_struct = strlen(s);
2446 n_array = (unsigned) -1;
2451 case SD_BUS_TYPE_STRUCT_BEGIN:
2452 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
2455 r = signature_element_length(t, &k);
2461 memcpy(s, t + 1, k - 2);
2464 r = sd_bus_message_enter_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
2471 if (n_array == (unsigned) -1) {
2476 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2482 n_array = (unsigned) -1;
2495 int sd_bus_message_read(sd_bus_message *m, const char *types, ...) {
2506 va_start(ap, types);
2507 r = message_read_ap(m, types, ap);
2513 static int message_peek_fields(
2524 return buffer_peek(m->fields, BUS_MESSAGE_FIELDS_SIZE(m), rindex, align, nbytes, ret);
2527 static int message_peek_field_uint32(
2538 r = message_peek_fields(m, ri, 4, 4, &q);
2543 *ret = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2548 static int message_peek_field_string(
2550 bool (*validate)(const char *p),
2561 r = message_peek_field_uint32(m, ri, &l);
2565 r = message_peek_fields(m, ri, 1, l+1, &q);
2570 if (!validate_nul(q, l))
2576 if (!validate_string(q, l))
2586 static int message_peek_field_signature(
2598 r = message_peek_fields(m, ri, 1, 1, &q);
2603 r = message_peek_fields(m, ri, 1, l+1, &q);
2607 if (!validate_signature(q, l))
2616 static int message_skip_fields(
2619 uint32_t array_size,
2620 const char **signature) {
2622 size_t original_index;
2629 original_index = *ri;
2635 if (array_size != (uint32_t) -1 &&
2636 array_size <= *ri - original_index)
2643 if (t == SD_BUS_TYPE_STRING) {
2645 r = message_peek_field_string(m, NULL, ri, NULL);
2651 } else if (t == SD_BUS_TYPE_OBJECT_PATH) {
2653 r = message_peek_field_string(m, object_path_is_valid, ri, NULL);
2659 } else if (t == SD_BUS_TYPE_SIGNATURE) {
2661 r = message_peek_field_signature(m, ri, NULL);
2667 } else if (bus_type_is_basic(t)) {
2670 align = bus_type_get_alignment(t);
2671 k = bus_type_get_size(t);
2672 assert(align > 0 && k > 0);
2674 r = message_peek_fields(m, ri, align, k, NULL);
2680 } else if (t == SD_BUS_TYPE_ARRAY) {
2682 r = signature_element_length(*signature+1, &l);
2692 strncpy(sig, *signature + 1, l-1);
2695 alignment = bus_type_get_alignment(sig[0]);
2699 r = message_peek_field_uint32(m, ri, &nas);
2702 if (nas > BUS_ARRAY_MAX_SIZE)
2705 r = message_peek_fields(m, ri, alignment, 0, NULL);
2709 r = message_skip_fields(m, ri, nas, (const char**) &s);
2714 (*signature) += 1 + l;
2716 } else if (t == SD_BUS_TYPE_VARIANT) {
2719 r = message_peek_field_signature(m, ri, &s);
2723 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
2729 } else if (t == SD_BUS_TYPE_STRUCT ||
2730 t == SD_BUS_TYPE_DICT_ENTRY) {
2732 r = signature_element_length(*signature, &l);
2739 strncpy(sig, *signature + 1, l-1);
2742 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
2753 int bus_message_parse_fields(sd_bus_message *m) {
2756 uint32_t unix_fds = 0;
2760 for (ri = 0; ri < BUS_MESSAGE_FIELDS_SIZE(m); ) {
2761 const char *signature;
2764 r = message_peek_fields(m, &ri, 8, 1, (void**) &header);
2768 r = message_peek_field_signature(m, &ri, &signature);
2773 case _SD_BUS_MESSAGE_HEADER_INVALID:
2776 case SD_BUS_MESSAGE_HEADER_PATH:
2781 if (!streq(signature, "o"))
2784 r = message_peek_field_string(m, object_path_is_valid, &ri, &m->path);
2787 case SD_BUS_MESSAGE_HEADER_INTERFACE:
2792 if (!streq(signature, "s"))
2795 r = message_peek_field_string(m, interface_name_is_valid, &ri, &m->interface);
2798 case SD_BUS_MESSAGE_HEADER_MEMBER:
2803 if (!streq(signature, "s"))
2806 r = message_peek_field_string(m, member_name_is_valid, &ri, &m->member);
2809 case SD_BUS_MESSAGE_HEADER_ERROR_NAME:
2814 if (!streq(signature, "s"))
2817 r = message_peek_field_string(m, error_name_is_valid, &ri, &m->error.name);
2820 case SD_BUS_MESSAGE_HEADER_DESTINATION:
2825 if (!streq(signature, "s"))
2828 r = message_peek_field_string(m, service_name_is_valid, &ri, &m->destination);
2831 case SD_BUS_MESSAGE_HEADER_SENDER:
2836 if (!streq(signature, "s"))
2839 r = message_peek_field_string(m, service_name_is_valid, &ri, &m->sender);
2843 case SD_BUS_MESSAGE_HEADER_SIGNATURE: {
2847 if (m->root_container.signature)
2850 if (!streq(signature, "g"))
2853 r = message_peek_field_signature(m, &ri, &s);
2861 free(m->root_container.signature);
2862 m->root_container.signature = c;
2866 case SD_BUS_MESSAGE_HEADER_REPLY_SERIAL:
2867 if (m->reply_serial != 0)
2870 if (!streq(signature, "u"))
2873 r = message_peek_field_uint32(m, &ri, &m->reply_serial);
2877 if (m->reply_serial == 0)
2882 case SD_BUS_MESSAGE_HEADER_UNIX_FDS:
2886 if (!streq(signature, "u"))
2889 r = message_peek_field_uint32(m, &ri, &unix_fds);
2899 r = message_skip_fields(m, &ri, (uint32_t) -1, (const char **) &signature);
2906 if (m->n_fds != unix_fds)
2909 if (isempty(m->root_container.signature) != (BUS_MESSAGE_BODY_SIZE(m) == 0))
2912 switch (m->header->type) {
2914 case SD_BUS_MESSAGE_TYPE_SIGNAL:
2915 if (!m->path || !m->interface || !m->member)
2919 case SD_BUS_MESSAGE_TYPE_METHOD_CALL:
2921 if (!m->path || !m->member)
2926 case SD_BUS_MESSAGE_TYPE_METHOD_RETURN:
2928 if (m->reply_serial == 0)
2932 case SD_BUS_MESSAGE_TYPE_METHOD_ERROR:
2934 if (m->reply_serial == 0 || !m->error.name)
2939 /* Try to read the error message, but if we can't it's a non-issue */
2940 if (m->header->type == SD_BUS_MESSAGE_TYPE_METHOD_ERROR)
2941 sd_bus_message_read(m, "s", &m->error.message);
2946 int bus_message_seal(sd_bus_message *m, uint64_t serial) {
2955 if (m->n_containers > 0)
2958 /* If there's a non-trivial signature set, then add it in here */
2959 if (!isempty(m->root_container.signature)) {
2960 r = message_append_field_signature(m, SD_BUS_MESSAGE_HEADER_SIGNATURE, m->root_container.signature, NULL);
2966 r = message_append_field_uint32(m, SD_BUS_MESSAGE_HEADER_UNIX_FDS, m->n_fds);
2971 l = BUS_MESSAGE_FIELDS_SIZE(m);
2975 /* Add padding at the end, since we know the body
2976 * needs to start at an 8 byte alignment. */
2979 p = message_extend_fields(m, 1, a);
2984 m->header->fields_size -= a;
2987 m->header->serial = serial;
2993 int sd_bus_message_set_destination(sd_bus_message *m, const char *destination) {
3003 return message_append_field_string(m, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &m->destination);
3006 int bus_message_dump(sd_bus_message *m) {
3007 char **cmdline = NULL;
3013 printf("Message %p\n"
3020 "\tfields_size=%u\n"
3025 "\tdestination=%s\n"
3028 "\treply_serial=%u\n"
3030 "\terror.message=%s\n"
3038 BUS_MESSAGE_SERIAL(m),
3039 BUS_MESSAGE_FIELDS_SIZE(m),
3040 BUS_MESSAGE_BODY_SIZE(m),
3042 strna(m->interface),
3044 strna(m->destination),
3046 strna(m->root_container.signature),
3048 strna(m->error.name),
3049 strna(m->error.message),
3053 printf("\tpid=%lu\n", (unsigned long) m->pid);
3055 printf("\ttid=%lu\n", (unsigned long) m->tid);
3057 printf("\tuid=%lu\n", (unsigned long) m->uid);
3059 printf("\tgid=%lu\n", (unsigned long) m->gid);
3060 if (m->pid_starttime != 0)
3061 printf("\tpid_starttime=%llu\n", (unsigned long long) m->pid_starttime);
3062 if (m->monotonic != 0)
3063 printf("\tmonotonic=%llu\n", (unsigned long long) m->monotonic);
3064 if (m->realtime != 0)
3065 printf("\trealtime=%llu\n", (unsigned long long) m->realtime);
3067 printf("\texe=[%s]\n", m->exe);
3069 printf("\tcomm=[%s]\n", m->comm);
3071 printf("\ttid_comm=[%s]\n", m->tid_comm);
3073 printf("\tlabel=[%s]\n", m->label);
3075 printf("\tcgroup=[%s]\n", m->cgroup);
3077 if (sd_bus_message_get_cmdline(m, &cmdline) >= 0) {
3080 fputs("\tcmdline=[", stdout);
3081 STRV_FOREACH(c, cmdline) {
3088 fputs("]\n", stdout);
3091 r = sd_bus_message_rewind(m, true);
3093 log_error("Failed to rewind: %s", strerror(-r));
3097 printf("BEGIN_MESSAGE \"%s\" {\n", strempty(m->root_container.signature));
3100 _cleanup_free_ char *prefix = NULL;
3101 const char *contents = NULL;
3116 r = sd_bus_message_peek_type(m, &type, &contents);
3118 log_error("Failed to peek type: %s", strerror(-r));
3125 r = sd_bus_message_exit_container(m);
3127 log_error("Failed to exit container: %s", strerror(-r));
3133 prefix = strrep("\t", level);
3137 if (type == SD_BUS_TYPE_ARRAY)
3138 printf("%s} END_ARRAY \n", prefix);
3139 else if (type == SD_BUS_TYPE_VARIANT)
3140 printf("%s} END_VARIANT\n", prefix);
3141 else if (type == SD_BUS_TYPE_STRUCT)
3142 printf("%s} END_STRUCT\n", prefix);
3143 else if (type == SD_BUS_TYPE_DICT_ENTRY)
3144 printf("%s} END_DICT_ENTRY\n", prefix);
3149 prefix = strrep("\t", level);
3153 if (bus_type_is_container(type) > 0) {
3154 r = sd_bus_message_enter_container(m, type, contents);
3156 log_error("Failed to enter container: %s", strerror(-r));
3160 if (type == SD_BUS_TYPE_ARRAY)
3161 printf("%sBEGIN_ARRAY \"%s\" {\n", prefix, contents);
3162 else if (type == SD_BUS_TYPE_VARIANT)
3163 printf("%sBEGIN_VARIANT \"%s\" {\n", prefix, contents);
3164 else if (type == SD_BUS_TYPE_STRUCT)
3165 printf("%sBEGIN_STRUCT \"%s\" {\n", prefix, contents);
3166 else if (type == SD_BUS_TYPE_DICT_ENTRY)
3167 printf("%sBEGIN_DICT_ENTRY \"%s\" {\n", prefix, contents);
3174 r = sd_bus_message_read_basic(m, type, &basic);
3176 log_error("Failed to get basic: %s", strerror(-r));
3182 case SD_BUS_TYPE_BYTE:
3183 printf("%sBYTE: %u\n", prefix, basic.u8);
3186 case SD_BUS_TYPE_BOOLEAN:
3187 printf("%sBOOLEAN: %s\n", prefix, yes_no(basic.i));
3190 case SD_BUS_TYPE_INT16:
3191 printf("%sINT16: %i\n", prefix, basic.s16);
3194 case SD_BUS_TYPE_UINT16:
3195 printf("%sUINT16: %u\n", prefix, basic.u16);
3198 case SD_BUS_TYPE_INT32:
3199 printf("%sINT32: %i\n", prefix, basic.s32);
3202 case SD_BUS_TYPE_UINT32:
3203 printf("%sUINT32: %u\n", prefix, basic.u32);
3206 case SD_BUS_TYPE_INT64:
3207 printf("%sINT64: %lli\n", prefix, (long long) basic.s64);
3210 case SD_BUS_TYPE_UINT64:
3211 printf("%sUINT64: %llu\n", prefix, (unsigned long long) basic.u64);
3214 case SD_BUS_TYPE_DOUBLE:
3215 printf("%sDOUBLE: %g\n", prefix, basic.d64);
3218 case SD_BUS_TYPE_STRING:
3219 printf("%sSTRING: \"%s\"\n", prefix, basic.string);
3222 case SD_BUS_TYPE_OBJECT_PATH:
3223 printf("%sOBJECT_PATH: \"%s\"\n", prefix, basic.string);
3226 case SD_BUS_TYPE_SIGNATURE:
3227 printf("%sSIGNATURE: \"%s\"\n", prefix, basic.string);
3230 case SD_BUS_TYPE_UNIX_FD:
3231 printf("%sUNIX_FD: %i\n", prefix, basic.i);
3235 assert_not_reached("Unknown basic type.");
3239 printf("} END_MESSAGE\n");
3243 int bus_message_get_blob(sd_bus_message *m, void **buffer, size_t *sz) {
3251 total = BUS_MESSAGE_SIZE(m);
3257 e = mempcpy(p, m->header, sizeof(*m->header));
3260 e = mempcpy(e, m->fields, m->header->fields_size);
3262 if (m->header->fields_size % 8 != 0)
3263 e = mempset(e, 0, 8 - (m->header->fields_size % 8));
3267 e = mempcpy(e, m->body, m->header->body_size);
3269 assert(total == (size_t) ((uint8_t*) e - (uint8_t*) p));
3277 int bus_message_read_strv_extend(sd_bus_message *m, char ***l) {
3283 r = sd_bus_message_enter_container(m, 'a', "s");
3290 r = sd_bus_message_read_basic(m, 's', &s);
3296 r = strv_extend(l, s);
3301 r = sd_bus_message_exit_container(m);
3308 const char* bus_message_get_arg(sd_bus_message *m, unsigned i) {
3310 const char *t = NULL;
3315 r = sd_bus_message_rewind(m, true);
3319 for (j = 0; j <= i; j++) {
3322 r = sd_bus_message_peek_type(m, &type, NULL);
3326 if (type != SD_BUS_TYPE_STRING &&
3327 type != SD_BUS_TYPE_OBJECT_PATH &&
3328 type != SD_BUS_TYPE_SIGNATURE)
3331 r = sd_bus_message_read_basic(m, type, &t);
3339 int bus_header_size(struct bus_header *h, size_t *sum) {
3345 if (h->endian == SD_BUS_NATIVE_ENDIAN) {
3346 fs = h->fields_size;
3348 } else if (h->endian == SD_BUS_REVERSE_ENDIAN) {
3349 fs = bswap_32(h->fields_size);
3350 bs = bswap_32(h->body_size);
3354 *sum = sizeof(struct bus_header) + ALIGN8(fs) + bs;