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"
29 #include "cgroup-util.h"
32 #include "bus-message.h"
33 #include "bus-internal.h"
35 #include "bus-signature.h"
37 static int message_append_basic(sd_bus_message *m, char type, const void *p, const void **stored);
39 static void reset_containers(sd_bus_message *m) {
44 for (i = 0; i < m->n_containers; i++)
45 free(m->containers[i].signature);
51 m->root_container.index = 0;
54 static void message_free(sd_bus_message *m) {
70 close_many(m->fds, m->n_fds);
74 free(m->cmdline_array);
77 free(m->root_container.signature);
79 free(m->peeked_signature);
87 static void* buffer_extend(void **p, uint32_t *sz, size_t align, size_t extend) {
95 start = ALIGN_TO((size_t) *sz, align);
99 return (uint8_t*) *p + start;
101 if (n > (size_t) ((uint32_t) -1))
108 /* Zero out padding */
110 memset((uint8_t*) k + *sz, 0, start - *sz);
115 return (uint8_t*) k + start;
118 static void *message_extend_fields(sd_bus_message *m, size_t align, size_t sz) {
124 p = buffer_extend(&m->fields, &m->header->fields_size, align, sz);
128 if (o != m->fields) {
129 /* Adjust quick access pointers */
132 m->path = (const char*) m->fields + (m->path - (const char*) o);
134 m->interface = (const char*) m->fields + (m->interface - (const char*) o);
136 m->member = (const char*) m->fields + (m->member - (const char*) o);
138 m->destination = (const char*) m->fields + (m->destination - (const char*) o);
140 m->sender = (const char*) m->fields + (m->sender - (const char*) o);
142 m->error.name = (const char*) m->fields + (m->error.name - (const char*) o);
145 m->free_fields = true;
150 static int message_append_field_string(
163 if (l > (size_t) (uint32_t) -1)
166 /* field id byte + signature length + signature 's' + NUL + string length + string + NUL */
167 p = message_extend_fields(m, 8, 4 + 4 + l + 1);
176 ((uint32_t*) p)[1] = l;
177 memcpy(p + 8, s, l + 1);
180 *ret = (const char*) p + 8;
185 static int message_append_field_signature(
200 /* field id byte + signature length + signature 'g' + NUL + string length + string + NUL */
201 p = message_extend_fields(m, 8, 4 + 1 + l + 1);
207 p[2] = SD_BUS_TYPE_SIGNATURE;
210 memcpy(p + 5, s, l + 1);
213 *ret = (const char*) p + 5;
218 static int message_append_field_uint32(sd_bus_message *m, uint8_t h, uint32_t x) {
223 /* field id byte + signature length + signature 'u' + NUL + value */
224 p = message_extend_fields(m, 8, 4 + 4);
230 p[2] = SD_BUS_TYPE_UINT32;
233 ((uint32_t*) p)[1] = x;
238 int bus_message_from_header(
243 const struct ucred *ucred,
246 sd_bus_message **ret) {
249 struct bus_header *h;
252 assert(buffer || length <= 0);
253 assert(fds || n_fds <= 0);
256 if (length < sizeof(struct bus_header))
266 if (h->type == _SD_BUS_MESSAGE_TYPE_INVALID)
269 if (h->endian != SD_BUS_LITTLE_ENDIAN &&
270 h->endian != SD_BUS_BIG_ENDIAN)
273 a = ALIGN(sizeof(sd_bus_message)) + ALIGN(extra);
276 label_sz = strlen(label);
294 m->uid_valid = m->gid_valid = true;
298 m->label = (char*) m + ALIGN(sizeof(sd_bus_message)) + ALIGN(extra);
299 memcpy(m->label, label, label_sz + 1);
306 int bus_message_from_malloc(
311 const struct ucred *ucred,
313 sd_bus_message **ret) {
318 r = bus_message_from_header(buffer, length, fds, n_fds, ucred, label, 0, &m);
322 if (length != BUS_MESSAGE_SIZE(m)) {
327 m->fields = (uint8_t*) buffer + sizeof(struct bus_header);
328 m->body = (uint8_t*) buffer + sizeof(struct bus_header) + ALIGN8(BUS_MESSAGE_FIELDS_SIZE(m));
331 m->iovec[0].iov_base = buffer;
332 m->iovec[0].iov_len = length;
334 r = bus_message_parse_fields(m);
338 /* We take possession of the memory and fds now */
339 m->free_header = true;
350 static sd_bus_message *message_new(sd_bus *bus, uint8_t type) {
353 m = malloc0(ALIGN(sizeof(sd_bus_message)) + sizeof(struct bus_header));
358 m->header = (struct bus_header*) ((uint8_t*) m + ALIGN(sizeof(struct sd_bus_message)));
359 m->header->endian = SD_BUS_NATIVE_ENDIAN;
360 m->header->type = type;
361 m->header->version = bus ? bus->message_version : 1;
362 m->allow_fds = !bus || bus->can_fds || (bus->state != BUS_HELLO && bus->state != BUS_RUNNING);
367 int sd_bus_message_new_signal(
370 const char *interface,
372 sd_bus_message **m) {
385 if (bus && bus->state == BUS_UNSET)
388 t = message_new(bus, SD_BUS_MESSAGE_TYPE_SIGNAL);
392 t->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
394 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_PATH, SD_BUS_TYPE_OBJECT_PATH, path, &t->path);
397 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_INTERFACE, SD_BUS_TYPE_STRING, interface, &t->interface);
400 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_MEMBER, SD_BUS_TYPE_STRING, member, &t->member);
408 sd_bus_message_unref(t);
412 int sd_bus_message_new_method_call(
414 const char *destination,
416 const char *interface,
418 sd_bus_message **m) {
429 if (bus && bus->state == BUS_UNSET)
432 t = message_new(bus, SD_BUS_MESSAGE_TYPE_METHOD_CALL);
436 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_PATH, SD_BUS_TYPE_OBJECT_PATH, path, &t->path);
439 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_MEMBER, SD_BUS_TYPE_STRING, member, &t->member);
444 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_INTERFACE, SD_BUS_TYPE_STRING, interface, &t->interface);
450 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &t->destination);
463 static int message_new_reply(
465 sd_bus_message *call,
467 sd_bus_message **m) {
476 if (call->header->type != SD_BUS_MESSAGE_TYPE_METHOD_CALL)
480 if (bus && bus->state == BUS_UNSET)
483 t = message_new(bus, type);
487 t->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
488 t->reply_serial = BUS_MESSAGE_SERIAL(call);
490 r = message_append_field_uint32(t, SD_BUS_MESSAGE_HEADER_REPLY_SERIAL, t->reply_serial);
495 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, call->sender, &t->sender);
500 t->dont_send = !!(call->header->flags & SD_BUS_MESSAGE_NO_REPLY_EXPECTED);
510 int sd_bus_message_new_method_return(
512 sd_bus_message *call,
513 sd_bus_message **m) {
515 return message_new_reply(bus, call, SD_BUS_MESSAGE_TYPE_METHOD_RETURN, m);
518 int sd_bus_message_new_method_error(
520 sd_bus_message *call,
521 const sd_bus_error *e,
522 sd_bus_message **m) {
527 if (!sd_bus_error_is_set(e))
532 r = message_new_reply(bus, call, SD_BUS_MESSAGE_TYPE_METHOD_ERROR, &t);
536 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_ERROR_NAME, SD_BUS_TYPE_STRING, e->name, &t->error.name);
541 r = message_append_basic(t, SD_BUS_TYPE_STRING, e->message, (const void**) &t->error.message);
554 sd_bus_message* sd_bus_message_ref(sd_bus_message *m) {
558 assert(m->n_ref > 0);
564 sd_bus_message* sd_bus_message_unref(sd_bus_message *m) {
568 assert(m->n_ref > 0);
577 int sd_bus_message_get_type(sd_bus_message *m, uint8_t *type) {
583 *type = m->header->type;
587 int sd_bus_message_get_serial(sd_bus_message *m, uint64_t *serial) {
592 if (m->header->serial == 0)
595 *serial = BUS_MESSAGE_SERIAL(m);
599 int sd_bus_message_get_reply_serial(sd_bus_message *m, uint64_t *serial) {
604 if (m->reply_serial == 0)
607 *serial = m->reply_serial;
611 int sd_bus_message_get_no_reply(sd_bus_message *m) {
615 return m->header->type == SD_BUS_MESSAGE_TYPE_METHOD_CALL ? !!(m->header->flags & SD_BUS_MESSAGE_NO_REPLY_EXPECTED) : 0;
618 const char *sd_bus_message_get_path(sd_bus_message *m) {
625 const char *sd_bus_message_get_interface(sd_bus_message *m) {
632 const char *sd_bus_message_get_member(sd_bus_message *m) {
638 const char *sd_bus_message_get_destination(sd_bus_message *m) {
642 return m->destination;
645 const char *sd_bus_message_get_sender(sd_bus_message *m) {
652 const sd_bus_error *sd_bus_message_get_error(sd_bus_message *m) {
656 if (!sd_bus_error_is_set(&m->error))
662 int sd_bus_message_get_uid(sd_bus_message *m, uid_t *uid) {
674 int sd_bus_message_get_gid(sd_bus_message *m, gid_t *gid) {
686 int sd_bus_message_get_pid(sd_bus_message *m, pid_t *pid) {
698 int sd_bus_message_get_tid(sd_bus_message *m, pid_t *tid) {
710 int sd_bus_message_get_pid_starttime(sd_bus_message *m, uint64_t *usec) {
715 if (m->pid_starttime <= 0)
718 *usec = m->pid_starttime;
722 int sd_bus_message_get_selinux_context(sd_bus_message *m, const char **ret) {
732 int sd_bus_message_get_monotonic_timestamp(sd_bus_message *m, uint64_t *usec) {
737 if (m->monotonic <= 0)
740 *usec = m->monotonic;
744 int sd_bus_message_get_realtime_timestamp(sd_bus_message *m, uint64_t *usec) {
749 if (m->realtime <= 0)
756 int sd_bus_message_get_comm(sd_bus_message *m, const char **ret) {
768 int sd_bus_message_get_tid_comm(sd_bus_message *m, const char **ret) {
780 int sd_bus_message_get_exe(sd_bus_message *m, const char **ret) {
792 int sd_bus_message_get_cgroup(sd_bus_message *m, const char **ret) {
804 int sd_bus_message_get_unit(sd_bus_message *m, const char **ret) {
815 r = cg_path_get_unit(m->cgroup, &m->unit);
824 int sd_bus_message_get_user_unit(sd_bus_message *m, const char **ret) {
835 r = cg_path_get_user_unit(m->cgroup, &m->user_unit);
844 int sd_bus_message_get_session(sd_bus_message *m, const char **ret) {
855 r = cg_path_get_session(m->cgroup, &m->session);
864 int sd_bus_message_get_owner_uid(sd_bus_message *m, uid_t *uid) {
872 return cg_path_get_owner_uid(m->cgroup, uid);
875 int sd_bus_message_get_cmdline(sd_bus_message *m, char ***cmdline) {
886 for (p = m->cmdline, n = 0; p < m->cmdline + m->cmdline_length; p++)
890 m->cmdline_array = new(char*, n + 1);
891 if (!m->cmdline_array)
894 for (p = m->cmdline, i = 0, first = true; p < m->cmdline + m->cmdline_length; p++) {
896 m->cmdline_array[i++] = (char*) p;
901 m->cmdline_array[i] = NULL;
902 *cmdline = m->cmdline_array;
907 int sd_bus_message_is_signal(sd_bus_message *m, const char *interface, const char *member) {
911 if (m->header->type != SD_BUS_MESSAGE_TYPE_SIGNAL)
914 if (interface && (!m->interface || !streq(m->interface, interface)))
917 if (member && (!m->member || !streq(m->member, member)))
923 int sd_bus_message_is_method_call(sd_bus_message *m, const char *interface, const char *member) {
927 if (m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_CALL)
930 if (interface && (!m->interface || !streq(m->interface, interface)))
933 if (member && (!m->member || !streq(m->member, member)))
939 int sd_bus_message_is_method_error(sd_bus_message *m, const char *name) {
943 if (m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_ERROR)
946 if (name && (!m->error.name || !streq(m->error.name, name)))
952 int sd_bus_message_set_no_reply(sd_bus_message *m, int b) {
957 if (m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_CALL)
961 m->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
963 m->header->flags &= ~SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
968 static struct bus_container *message_get_container(sd_bus_message *m) {
971 if (m->n_containers == 0)
972 return &m->root_container;
974 assert(m->containers);
975 return m->containers + m->n_containers - 1;
978 static void *message_extend_body(sd_bus_message *m, size_t align, size_t sz) {
981 struct bus_container *c;
987 added = m->header->body_size;
989 p = buffer_extend(&m->body, &m->header->body_size, align, sz);
993 added = m->header->body_size - added;
995 for (c = m->containers; c < m->containers + m->n_containers; c++)
997 c->array_size = (uint32_t*) ((uint8_t*) m->body + ((uint8_t*) c->array_size - (uint8_t*) o));
998 *c->array_size += added;
1002 if (m->error.message)
1003 m->error.message = (const char*) m->body + (m->error.message - (const char*) o);
1006 m->free_body = true;
1011 int message_append_basic(sd_bus_message *m, char type, const void *p, const void **stored) {
1012 struct bus_container *c;
1027 if (!bus_type_is_basic(type))
1030 c = message_get_container(m);
1032 if (c->signature && c->signature[c->index]) {
1033 /* Container signature is already set */
1035 if (c->signature[c->index] != type)
1038 /* Maybe we can append to the signature? But only if this is the top-level container*/
1039 if (c->enclosing != 0)
1042 e = strextend(&c->signature, CHAR_TO_STR(type), NULL);
1049 case SD_BUS_TYPE_STRING:
1050 case SD_BUS_TYPE_OBJECT_PATH:
1053 sz = 4 + strlen(p) + 1;
1056 case SD_BUS_TYPE_SIGNATURE:
1059 sz = 1 + strlen(p) + 1;
1062 case SD_BUS_TYPE_BOOLEAN:
1065 assert_cc(sizeof(int) == sizeof(uint32_t));
1071 case SD_BUS_TYPE_UNIX_FD: {
1074 if (!m->allow_fds) {
1087 fd = fcntl(z, F_DUPFD_CLOEXEC, 3);
1093 f = realloc(m->fds, sizeof(int) * (m->n_fds + 1));
1107 align = bus_type_get_alignment(type);
1108 sz = bus_type_get_size(type);
1115 a = message_extend_body(m, align, sz);
1121 if (type == SD_BUS_TYPE_STRING || type == SD_BUS_TYPE_OBJECT_PATH) {
1122 *(uint32_t*) a = sz - 5;
1123 memcpy((uint8_t*) a + 4, p, sz - 4);
1126 *stored = (const uint8_t*) a + 4;
1128 } else if (type == SD_BUS_TYPE_SIGNATURE) {
1129 *(uint8_t*) a = sz - 1;
1130 memcpy((uint8_t*) a + 1, p, sz - 1);
1133 *stored = (const uint8_t*) a + 1;
1134 } else if (type == SD_BUS_TYPE_UNIX_FD) {
1135 *(uint32_t*) a = fdi;
1149 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1155 /* Truncate extended signature again */
1157 c->signature[c->index] = 0;
1160 close_nointr_nofail(fd);
1165 int sd_bus_message_append_basic(sd_bus_message *m, char type, const void *p) {
1166 return message_append_basic(m, type, p, NULL);
1169 static int bus_message_open_array(
1171 struct bus_container *c,
1172 const char *contents,
1173 uint32_t **array_size) {
1186 if (!signature_is_single(contents))
1189 alignment = bus_type_get_alignment(contents[0]);
1193 if (c->signature && c->signature[c->index]) {
1195 /* Verify the existing signature */
1197 if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
1200 if (!startswith(c->signature + c->index + 1, contents))
1203 nindex = c->index + 1 + strlen(contents);
1205 if (c->enclosing != 0)
1208 /* Extend the existing signature */
1210 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_ARRAY), contents, NULL);
1214 nindex = e - c->signature;
1217 saved = m->header->body_size;
1218 a = message_extend_body(m, 4, 4);
1220 /* Truncate extended signature again */
1222 c->signature[c->index] = 0;
1228 if (!message_extend_body(m, alignment, 0)) {
1229 /* Add alignment between size and first element */
1231 c->signature[c->index] = 0;
1233 m->header->body_size = saved;
1237 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1240 /* m->body might have changed so let's readjust a */
1241 a = (uint8_t*) m->body + ((uint8_t*) a - (uint8_t*) b);
1248 static int bus_message_open_variant(
1250 struct bus_container *c,
1251 const char *contents) {
1261 if (!signature_is_single(contents))
1264 if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
1267 if (c->signature && c->signature[c->index]) {
1269 if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
1273 if (c->enclosing != 0)
1276 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_VARIANT), NULL);
1281 l = strlen(contents);
1282 a = message_extend_body(m, 1, 1 + l + 1);
1284 /* Truncate extended signature again */
1286 c->signature[c->index] = 0;
1292 memcpy((uint8_t*) a + 1, contents, l + 1);
1294 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1300 static int bus_message_open_struct(
1302 struct bus_container *c,
1303 const char *contents) {
1312 if (!signature_is_valid(contents, false))
1315 if (c->signature && c->signature[c->index]) {
1318 l = strlen(contents);
1320 if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
1321 !startswith(c->signature + c->index + 1, contents) ||
1322 c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
1325 nindex = c->index + 1 + l + 1;
1327 if (c->enclosing != 0)
1330 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_BEGIN), contents, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_END), NULL);
1334 nindex = e - c->signature;
1337 /* Align contents to 8 byte boundary */
1338 if (!message_extend_body(m, 8, 0)) {
1340 c->signature[c->index] = 0;
1345 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1351 static int bus_message_open_dict_entry(
1353 struct bus_container *c,
1354 const char *contents) {
1362 if (!signature_is_pair(contents))
1365 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1368 if (c->signature && c->signature[c->index]) {
1371 l = strlen(contents);
1373 if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
1374 !startswith(c->signature + c->index + 1, contents) ||
1375 c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
1378 nindex = c->index + 1 + l + 1;
1382 /* Align contents to 8 byte boundary */
1383 if (!message_extend_body(m, 8, 0))
1386 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1392 int sd_bus_message_open_container(
1395 const char *contents) {
1397 struct bus_container *c, *w;
1398 uint32_t *array_size = NULL;
1409 /* Make sure we have space for one more container */
1410 w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
1415 c = message_get_container(m);
1417 signature = strdup(contents);
1421 if (type == SD_BUS_TYPE_ARRAY)
1422 r = bus_message_open_array(m, c, contents, &array_size);
1423 else if (type == SD_BUS_TYPE_VARIANT)
1424 r = bus_message_open_variant(m, c, contents);
1425 else if (type == SD_BUS_TYPE_STRUCT)
1426 r = bus_message_open_struct(m, c, contents);
1427 else if (type == SD_BUS_TYPE_DICT_ENTRY)
1428 r = bus_message_open_dict_entry(m, c, contents);
1437 /* OK, let's fill it in */
1438 w += m->n_containers++;
1439 w->enclosing = type;
1440 w->signature = signature;
1442 w->array_size = array_size;
1448 int sd_bus_message_close_container(sd_bus_message *m) {
1449 struct bus_container *c;
1455 if (m->n_containers <= 0)
1458 c = message_get_container(m);
1459 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1460 if (c->signature && c->signature[c->index] != 0)
1476 static int type_stack_push(TypeStack *stack, unsigned max, unsigned *i, const char *types, unsigned n_struct, unsigned n_array) {
1483 stack[*i].types = types;
1484 stack[*i].n_struct = n_struct;
1485 stack[*i].n_array = n_array;
1491 static int type_stack_pop(TypeStack *stack, unsigned max, unsigned *i, const char **types, unsigned *n_struct, unsigned *n_array) {
1502 *types = stack[*i].types;
1503 *n_struct = stack[*i].n_struct;
1504 *n_array = stack[*i].n_array;
1509 int bus_message_append_ap(
1514 unsigned n_array, n_struct;
1515 TypeStack stack[BUS_CONTAINER_DEPTH];
1516 unsigned stack_ptr = 0;
1524 n_array = (unsigned) -1;
1525 n_struct = strlen(types);
1530 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
1531 r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
1537 r = sd_bus_message_close_container(m);
1545 if (n_array != (unsigned) -1)
1554 case SD_BUS_TYPE_BYTE: {
1557 x = (uint8_t) va_arg(ap, int);
1558 r = sd_bus_message_append_basic(m, *t, &x);
1562 case SD_BUS_TYPE_BOOLEAN:
1563 case SD_BUS_TYPE_INT32:
1564 case SD_BUS_TYPE_UINT32:
1565 case SD_BUS_TYPE_UNIX_FD: {
1568 /* We assume a boolean is the same as int32_t */
1569 assert_cc(sizeof(int32_t) == sizeof(int));
1571 x = va_arg(ap, uint32_t);
1572 r = sd_bus_message_append_basic(m, *t, &x);
1576 case SD_BUS_TYPE_INT16:
1577 case SD_BUS_TYPE_UINT16: {
1580 x = (uint16_t) va_arg(ap, int);
1581 r = sd_bus_message_append_basic(m, *t, &x);
1585 case SD_BUS_TYPE_INT64:
1586 case SD_BUS_TYPE_UINT64:
1587 case SD_BUS_TYPE_DOUBLE: {
1590 x = va_arg(ap, uint64_t);
1591 r = sd_bus_message_append_basic(m, *t, &x);
1595 case SD_BUS_TYPE_STRING:
1596 case SD_BUS_TYPE_OBJECT_PATH:
1597 case SD_BUS_TYPE_SIGNATURE: {
1600 x = va_arg(ap, const char*);
1601 r = sd_bus_message_append_basic(m, *t, x);
1605 case SD_BUS_TYPE_ARRAY: {
1608 r = signature_element_length(t + 1, &k);
1614 memcpy(s, t + 1, k);
1617 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, s);
1622 if (n_array == (unsigned) -1) {
1627 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
1633 n_array = va_arg(ap, unsigned);
1638 case SD_BUS_TYPE_VARIANT: {
1641 s = va_arg(ap, const char*);
1645 r = sd_bus_message_open_container(m, SD_BUS_TYPE_VARIANT, s);
1649 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
1654 n_struct = strlen(s);
1655 n_array = (unsigned) -1;
1660 case SD_BUS_TYPE_STRUCT_BEGIN:
1661 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
1664 r = signature_element_length(t, &k);
1671 memcpy(s, t + 1, k - 2);
1674 r = sd_bus_message_open_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
1679 if (n_array == (unsigned) -1) {
1684 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
1690 n_array = (unsigned) -1;
1706 int sd_bus_message_append(sd_bus_message *m, const char *types, ...) {
1717 va_start(ap, types);
1718 r = bus_message_append_ap(m, types, ap);
1724 static int buffer_peek(const void *p, uint32_t sz, size_t *rindex, size_t align, size_t nbytes, void **r) {
1730 start = ALIGN_TO((size_t) *rindex, align);
1736 /* Verify that padding is 0 */
1737 for (k = *rindex; k < start; k++)
1738 if (((const uint8_t*) p)[k] != 0)
1742 *r = (uint8_t*) p + start;
1749 static bool message_end_of_array(sd_bus_message *m, size_t index) {
1750 struct bus_container *c;
1754 c = message_get_container(m);
1758 return index >= c->begin + BUS_MESSAGE_BSWAP32(m, *c->array_size);
1761 static int message_peek_body(sd_bus_message *m, size_t *rindex, size_t align, size_t nbytes, void **ret) {
1766 if (message_end_of_array(m, *rindex))
1769 return buffer_peek(m->body, BUS_MESSAGE_BODY_SIZE(m), rindex, align, nbytes, ret);
1772 static bool validate_nul(const char *s, size_t l) {
1774 /* Check for NUL chars in the string */
1775 if (memchr(s, 0, l))
1778 /* Check for NUL termination */
1785 static bool validate_string(const char *s, size_t l) {
1787 if (!validate_nul(s, l))
1790 /* Check if valid UTF8 */
1791 if (!utf8_is_valid(s))
1797 static bool validate_signature(const char *s, size_t l) {
1799 if (!validate_nul(s, l))
1802 /* Check if valid signature */
1803 if (!signature_is_valid(s, true))
1809 static bool validate_object_path(const char *s, size_t l) {
1811 if (!validate_nul(s, l))
1814 if (!object_path_is_valid(s))
1820 int sd_bus_message_read_basic(sd_bus_message *m, char type, void *p) {
1821 struct bus_container *c;
1829 if (!bus_type_is_basic(type))
1834 c = message_get_container(m);
1836 if (!c->signature || c->signature[c->index] == 0)
1839 if (c->signature[c->index] != type)
1844 case SD_BUS_TYPE_STRING:
1845 case SD_BUS_TYPE_OBJECT_PATH: {
1850 r = message_peek_body(m, &rindex, 4, 4, &q);
1854 l = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
1855 r = message_peek_body(m, &rindex, 1, l+1, &q);
1861 if (type == SD_BUS_TYPE_OBJECT_PATH) {
1862 if (!validate_object_path(q, l))
1865 if (!validate_string(q, l))
1870 *(const char**) p = q;
1874 case SD_BUS_TYPE_SIGNATURE: {
1879 r = message_peek_body(m, &rindex, 1, 1, &q);
1884 r = message_peek_body(m, &rindex, 1, l+1, &q);
1890 if (!validate_signature(q, l))
1894 *(const char**) p = q;
1902 align = bus_type_get_alignment(type);
1903 sz = bus_type_get_size(type);
1904 assert(align > 0 && sz > 0);
1907 r = message_peek_body(m, &rindex, align, sz, &q);
1913 case SD_BUS_TYPE_BYTE:
1914 *(uint8_t*) p = *(uint8_t*) q;
1917 case SD_BUS_TYPE_BOOLEAN:
1918 *(int*) p = !!*(uint32_t*) q;
1921 case SD_BUS_TYPE_INT16:
1922 case SD_BUS_TYPE_UINT16:
1923 *(uint16_t*) p = BUS_MESSAGE_BSWAP16(m, *(uint16_t*) q);
1926 case SD_BUS_TYPE_INT32:
1927 case SD_BUS_TYPE_UINT32:
1928 *(uint32_t*) p = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
1931 case SD_BUS_TYPE_INT64:
1932 case SD_BUS_TYPE_UINT64:
1933 case SD_BUS_TYPE_DOUBLE:
1934 *(uint64_t*) p = BUS_MESSAGE_BSWAP64(m, *(uint64_t*) q);
1937 case SD_BUS_TYPE_UNIX_FD: {
1940 j = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
1944 *(int*) p = m->fds[j];
1949 assert_not_reached("Unknown basic type...");
1958 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1964 static int bus_message_enter_array(
1966 struct bus_container *c,
1967 const char *contents,
1968 uint32_t **array_size) {
1979 if (!signature_is_single(contents))
1982 alignment = bus_type_get_alignment(contents[0]);
1986 if (!c->signature || c->signature[c->index] == 0)
1989 if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
1992 if (!startswith(c->signature + c->index + 1, contents))
1996 r = message_peek_body(m, &rindex, 4, 4, &q);
2000 if (BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q) > BUS_ARRAY_MAX_SIZE)
2003 r = message_peek_body(m, &rindex, alignment, 0, NULL);
2009 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2010 c->index += 1 + strlen(contents);
2014 *array_size = (uint32_t*) q;
2019 static int bus_message_enter_variant(
2021 struct bus_container *c,
2022 const char *contents) {
2033 if (!signature_is_single(contents))
2036 if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
2039 if (!c->signature || c->signature[c->index] == 0)
2042 if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
2046 r = message_peek_body(m, &rindex, 1, 1, &q);
2051 r = message_peek_body(m, &rindex, 1, l+1, &q);
2057 if (!validate_signature(q, l))
2060 if (!streq(q, contents))
2063 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2071 static int bus_message_enter_struct(
2073 struct bus_container *c,
2074 const char *contents) {
2083 if (!signature_is_valid(contents, false))
2086 if (!c->signature || c->signature[c->index] == 0)
2089 l = strlen(contents);
2091 if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
2092 !startswith(c->signature + c->index + 1, contents) ||
2093 c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
2096 r = message_peek_body(m, &m->rindex, 8, 0, NULL);
2100 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2101 c->index += 1 + l + 1;
2106 static int bus_message_enter_dict_entry(
2108 struct bus_container *c,
2109 const char *contents) {
2118 if (!signature_is_pair(contents))
2121 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2124 if (!c->signature || c->signature[c->index] == 0)
2127 l = strlen(contents);
2129 if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
2130 !startswith(c->signature + c->index + 1, contents) ||
2131 c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
2134 r = message_peek_body(m, &m->rindex, 8, 0, NULL);
2138 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2139 c->index += 1 + l + 1;
2144 int sd_bus_message_enter_container(sd_bus_message *m, char type, const char *contents) {
2145 struct bus_container *c, *w;
2146 uint32_t *array_size = NULL;
2158 * We enforce a global limit on container depth, that is much
2159 * higher than the 32 structs and 32 arrays the specification
2160 * mandates. This is simpler to implement for us, and we need
2161 * this only to ensure our container array doesn't grow
2162 * without bounds. We are happy to return any data from a
2163 * message as long as the data itself is valid, even if the
2164 * overall message might be not.
2166 * Note that the message signature is validated when
2167 * parsing the headers, and that validation does check the
2170 * Note that the specification defines no limits on the depth
2171 * of stacked variants, but we do.
2173 if (m->n_containers >= BUS_CONTAINER_DEPTH)
2176 w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
2181 c = message_get_container(m);
2183 if (!c->signature || c->signature[c->index] == 0)
2186 signature = strdup(contents);
2190 if (type == SD_BUS_TYPE_ARRAY)
2191 r = bus_message_enter_array(m, c, contents, &array_size);
2192 else if (type == SD_BUS_TYPE_VARIANT)
2193 r = bus_message_enter_variant(m, c, contents);
2194 else if (type == SD_BUS_TYPE_STRUCT)
2195 r = bus_message_enter_struct(m, c, contents);
2196 else if (type == SD_BUS_TYPE_DICT_ENTRY)
2197 r = bus_message_enter_dict_entry(m, c, contents);
2206 /* OK, let's fill it in */
2207 w += m->n_containers++;
2208 w->enclosing = type;
2209 w->signature = signature;
2211 w->array_size = array_size;
2212 w->begin = m->rindex;
2217 int sd_bus_message_exit_container(sd_bus_message *m) {
2218 struct bus_container *c;
2224 if (m->n_containers <= 0)
2227 c = message_get_container(m);
2228 if (c->enclosing == SD_BUS_TYPE_ARRAY) {
2231 l = BUS_MESSAGE_BSWAP32(m, *c->array_size);
2232 if (c->begin + l != m->rindex)
2236 if (c->signature && c->signature[c->index] != 0)
2246 int sd_bus_message_peek_type(sd_bus_message *m, char *type, const char **contents) {
2247 struct bus_container *c;
2255 c = message_get_container(m);
2257 if (!c->signature || c->signature[c->index] == 0)
2260 if (message_end_of_array(m, m->rindex))
2263 if (bus_type_is_basic(c->signature[c->index])) {
2267 *type = c->signature[c->index];
2271 if (c->signature[c->index] == SD_BUS_TYPE_ARRAY) {
2277 r = signature_element_length(c->signature+c->index+1, &l);
2283 sig = strndup(c->signature + c->index + 1, l);
2287 free(m->peeked_signature);
2288 m->peeked_signature = sig;
2294 *type = SD_BUS_TYPE_ARRAY;
2299 if (c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ||
2300 c->signature[c->index] == SD_BUS_TYPE_DICT_ENTRY_BEGIN) {
2306 r = signature_element_length(c->signature+c->index, &l);
2311 sig = strndup(c->signature + c->index + 1, l - 2);
2315 free(m->peeked_signature);
2316 m->peeked_signature = sig;
2322 *type = c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY;
2327 if (c->signature[c->index] == SD_BUS_TYPE_VARIANT) {
2333 r = message_peek_body(m, &rindex, 1, 1, &q);
2340 r = message_peek_body(m, &rindex, 1, l+1, &q);
2346 if (!validate_signature(q, l))
2353 *type = SD_BUS_TYPE_VARIANT;
2362 *type = c->enclosing;
2368 int sd_bus_message_rewind(sd_bus_message *m, int complete) {
2369 struct bus_container *c;
2377 reset_containers(m);
2379 m->root_container.index = 0;
2381 c = message_get_container(m);
2383 c = message_get_container(m);
2386 m->rindex = c->begin;
2389 return !isempty(c->signature);
2391 static int message_read_ap(
2396 unsigned n_array, n_struct;
2397 TypeStack stack[BUS_CONTAINER_DEPTH];
2398 unsigned stack_ptr = 0;
2406 /* Ideally, we'd just call ourselves recursively on every
2407 * complex type. However, the state of a va_list that is
2408 * passed to a function is undefined after that function
2409 * returns. This means we need to docode the va_list linearly
2410 * in a single stackframe. We hence implement our own
2411 * home-grown stack in an array. */
2413 n_array = (unsigned) -1;
2414 n_struct = strlen(types);
2419 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
2420 r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
2426 r = sd_bus_message_exit_container(m);
2434 if (n_array != (unsigned) -1)
2443 case SD_BUS_TYPE_BYTE:
2444 case SD_BUS_TYPE_BOOLEAN:
2445 case SD_BUS_TYPE_INT16:
2446 case SD_BUS_TYPE_UINT16:
2447 case SD_BUS_TYPE_INT32:
2448 case SD_BUS_TYPE_UINT32:
2449 case SD_BUS_TYPE_INT64:
2450 case SD_BUS_TYPE_UINT64:
2451 case SD_BUS_TYPE_DOUBLE:
2452 case SD_BUS_TYPE_STRING:
2453 case SD_BUS_TYPE_OBJECT_PATH:
2454 case SD_BUS_TYPE_SIGNATURE:
2455 case SD_BUS_TYPE_UNIX_FD: {
2458 p = va_arg(ap, void*);
2459 r = sd_bus_message_read_basic(m, *t, p);
2468 case SD_BUS_TYPE_ARRAY: {
2471 r = signature_element_length(t + 1, &k);
2477 memcpy(s, t + 1, k);
2480 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, s);
2487 if (n_array == (unsigned) -1) {
2492 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2498 n_array = va_arg(ap, unsigned);
2503 case SD_BUS_TYPE_VARIANT: {
2506 s = va_arg(ap, const char *);
2510 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, s);
2516 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2521 n_struct = strlen(s);
2522 n_array = (unsigned) -1;
2527 case SD_BUS_TYPE_STRUCT_BEGIN:
2528 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
2531 r = signature_element_length(t, &k);
2537 memcpy(s, t + 1, k - 2);
2540 r = sd_bus_message_enter_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
2547 if (n_array == (unsigned) -1) {
2552 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2558 n_array = (unsigned) -1;
2571 int sd_bus_message_read(sd_bus_message *m, const char *types, ...) {
2582 va_start(ap, types);
2583 r = message_read_ap(m, types, ap);
2589 static int message_peek_fields(
2600 return buffer_peek(m->fields, BUS_MESSAGE_FIELDS_SIZE(m), rindex, align, nbytes, ret);
2603 static int message_peek_field_uint32(
2614 r = message_peek_fields(m, ri, 4, 4, &q);
2619 *ret = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2624 static int message_peek_field_string(
2626 bool (*validate)(const char *p),
2637 r = message_peek_field_uint32(m, ri, &l);
2641 r = message_peek_fields(m, ri, 1, l+1, &q);
2646 if (!validate_nul(q, l))
2652 if (!validate_string(q, l))
2662 static int message_peek_field_signature(
2674 r = message_peek_fields(m, ri, 1, 1, &q);
2679 r = message_peek_fields(m, ri, 1, l+1, &q);
2683 if (!validate_signature(q, l))
2692 static int message_skip_fields(
2695 uint32_t array_size,
2696 const char **signature) {
2698 size_t original_index;
2705 original_index = *ri;
2711 if (array_size != (uint32_t) -1 &&
2712 array_size <= *ri - original_index)
2719 if (t == SD_BUS_TYPE_STRING) {
2721 r = message_peek_field_string(m, NULL, ri, NULL);
2727 } else if (t == SD_BUS_TYPE_OBJECT_PATH) {
2729 r = message_peek_field_string(m, object_path_is_valid, ri, NULL);
2735 } else if (t == SD_BUS_TYPE_SIGNATURE) {
2737 r = message_peek_field_signature(m, ri, NULL);
2743 } else if (bus_type_is_basic(t)) {
2746 align = bus_type_get_alignment(t);
2747 k = bus_type_get_size(t);
2748 assert(align > 0 && k > 0);
2750 r = message_peek_fields(m, ri, align, k, NULL);
2756 } else if (t == SD_BUS_TYPE_ARRAY) {
2758 r = signature_element_length(*signature+1, &l);
2768 strncpy(sig, *signature + 1, l-1);
2771 alignment = bus_type_get_alignment(sig[0]);
2775 r = message_peek_field_uint32(m, ri, &nas);
2778 if (nas > BUS_ARRAY_MAX_SIZE)
2781 r = message_peek_fields(m, ri, alignment, 0, NULL);
2785 r = message_skip_fields(m, ri, nas, (const char**) &s);
2790 (*signature) += 1 + l;
2792 } else if (t == SD_BUS_TYPE_VARIANT) {
2795 r = message_peek_field_signature(m, ri, &s);
2799 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
2805 } else if (t == SD_BUS_TYPE_STRUCT ||
2806 t == SD_BUS_TYPE_DICT_ENTRY) {
2808 r = signature_element_length(*signature, &l);
2815 strncpy(sig, *signature + 1, l-1);
2818 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
2829 int bus_message_parse_fields(sd_bus_message *m) {
2832 uint32_t unix_fds = 0;
2836 for (ri = 0; ri < BUS_MESSAGE_FIELDS_SIZE(m); ) {
2837 const char *signature;
2840 r = message_peek_fields(m, &ri, 8, 1, (void**) &header);
2844 r = message_peek_field_signature(m, &ri, &signature);
2849 case _SD_BUS_MESSAGE_HEADER_INVALID:
2852 case SD_BUS_MESSAGE_HEADER_PATH:
2857 if (!streq(signature, "o"))
2860 r = message_peek_field_string(m, object_path_is_valid, &ri, &m->path);
2863 case SD_BUS_MESSAGE_HEADER_INTERFACE:
2868 if (!streq(signature, "s"))
2871 r = message_peek_field_string(m, interface_name_is_valid, &ri, &m->interface);
2874 case SD_BUS_MESSAGE_HEADER_MEMBER:
2879 if (!streq(signature, "s"))
2882 r = message_peek_field_string(m, member_name_is_valid, &ri, &m->member);
2885 case SD_BUS_MESSAGE_HEADER_ERROR_NAME:
2890 if (!streq(signature, "s"))
2893 r = message_peek_field_string(m, error_name_is_valid, &ri, &m->error.name);
2896 case SD_BUS_MESSAGE_HEADER_DESTINATION:
2901 if (!streq(signature, "s"))
2904 r = message_peek_field_string(m, service_name_is_valid, &ri, &m->destination);
2907 case SD_BUS_MESSAGE_HEADER_SENDER:
2912 if (!streq(signature, "s"))
2915 r = message_peek_field_string(m, service_name_is_valid, &ri, &m->sender);
2919 case SD_BUS_MESSAGE_HEADER_SIGNATURE: {
2923 if (m->root_container.signature)
2926 if (!streq(signature, "g"))
2929 r = message_peek_field_signature(m, &ri, &s);
2937 free(m->root_container.signature);
2938 m->root_container.signature = c;
2942 case SD_BUS_MESSAGE_HEADER_REPLY_SERIAL:
2943 if (m->reply_serial != 0)
2946 if (!streq(signature, "u"))
2949 r = message_peek_field_uint32(m, &ri, &m->reply_serial);
2953 if (m->reply_serial == 0)
2958 case SD_BUS_MESSAGE_HEADER_UNIX_FDS:
2962 if (!streq(signature, "u"))
2965 r = message_peek_field_uint32(m, &ri, &unix_fds);
2975 r = message_skip_fields(m, &ri, (uint32_t) -1, (const char **) &signature);
2982 if (m->n_fds != unix_fds)
2985 if (isempty(m->root_container.signature) != (BUS_MESSAGE_BODY_SIZE(m) == 0))
2988 switch (m->header->type) {
2990 case SD_BUS_MESSAGE_TYPE_SIGNAL:
2991 if (!m->path || !m->interface || !m->member)
2995 case SD_BUS_MESSAGE_TYPE_METHOD_CALL:
2997 if (!m->path || !m->member)
3002 case SD_BUS_MESSAGE_TYPE_METHOD_RETURN:
3004 if (m->reply_serial == 0)
3008 case SD_BUS_MESSAGE_TYPE_METHOD_ERROR:
3010 if (m->reply_serial == 0 || !m->error.name)
3015 /* Try to read the error message, but if we can't it's a non-issue */
3016 if (m->header->type == SD_BUS_MESSAGE_TYPE_METHOD_ERROR)
3017 sd_bus_message_read(m, "s", &m->error.message);
3022 int bus_message_seal(sd_bus_message *m, uint64_t serial) {
3031 if (m->n_containers > 0)
3034 /* If there's a non-trivial signature set, then add it in here */
3035 if (!isempty(m->root_container.signature)) {
3036 r = message_append_field_signature(m, SD_BUS_MESSAGE_HEADER_SIGNATURE, m->root_container.signature, NULL);
3042 r = message_append_field_uint32(m, SD_BUS_MESSAGE_HEADER_UNIX_FDS, m->n_fds);
3047 l = BUS_MESSAGE_FIELDS_SIZE(m);
3051 /* Add padding at the end, since we know the body
3052 * needs to start at an 8 byte alignment. */
3055 p = message_extend_fields(m, 1, a);
3060 m->header->fields_size -= a;
3063 m->header->serial = serial;
3069 int sd_bus_message_set_destination(sd_bus_message *m, const char *destination) {
3079 return message_append_field_string(m, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &m->destination);
3082 int bus_message_dump(sd_bus_message *m) {
3083 const char *u = NULL, *uu = NULL, *s = NULL;
3084 char **cmdline = NULL;
3091 printf("Message %p\n"
3098 "\tfields_size=%u\n"
3103 "\tdestination=%s\n"
3106 "\treply_serial=%u\n"
3108 "\terror.message=%s\n"
3116 BUS_MESSAGE_SERIAL(m),
3117 BUS_MESSAGE_FIELDS_SIZE(m),
3118 BUS_MESSAGE_BODY_SIZE(m),
3120 strna(m->interface),
3122 strna(m->destination),
3124 strna(m->root_container.signature),
3126 strna(m->error.name),
3127 strna(m->error.message),
3131 printf("\tpid=%lu\n", (unsigned long) m->pid);
3133 printf("\ttid=%lu\n", (unsigned long) m->tid);
3135 printf("\tuid=%lu\n", (unsigned long) m->uid);
3137 printf("\tgid=%lu\n", (unsigned long) m->gid);
3138 if (m->pid_starttime != 0)
3139 printf("\tpid_starttime=%llu\n", (unsigned long long) m->pid_starttime);
3140 if (m->monotonic != 0)
3141 printf("\tmonotonic=%llu\n", (unsigned long long) m->monotonic);
3142 if (m->realtime != 0)
3143 printf("\trealtime=%llu\n", (unsigned long long) m->realtime);
3145 printf("\texe=[%s]\n", m->exe);
3147 printf("\tcomm=[%s]\n", m->comm);
3149 printf("\ttid_comm=[%s]\n", m->tid_comm);
3151 printf("\tlabel=[%s]\n", m->label);
3153 printf("\tcgroup=[%s]\n", m->cgroup);
3155 sd_bus_message_get_unit(m, &u);
3157 printf("\tunit=[%s]\n", u);
3158 sd_bus_message_get_user_unit(m, &uu);
3160 printf("\tuser_unit=[%s]\n", uu);
3161 sd_bus_message_get_session(m, &s);
3163 printf("\tsession=[%s]\n", s);
3164 if (sd_bus_message_get_owner_uid(m, &owner) >= 0)
3165 printf("\towner_uid=%lu\n", (unsigned long) owner);
3167 if (sd_bus_message_get_cmdline(m, &cmdline) >= 0) {
3170 fputs("\tcmdline=[", stdout);
3171 STRV_FOREACH(c, cmdline) {
3178 fputs("]\n", stdout);
3181 r = sd_bus_message_rewind(m, true);
3183 log_error("Failed to rewind: %s", strerror(-r));
3187 printf("BEGIN_MESSAGE \"%s\" {\n", strempty(m->root_container.signature));
3190 _cleanup_free_ char *prefix = NULL;
3191 const char *contents = NULL;
3206 r = sd_bus_message_peek_type(m, &type, &contents);
3208 log_error("Failed to peek type: %s", strerror(-r));
3215 r = sd_bus_message_exit_container(m);
3217 log_error("Failed to exit container: %s", strerror(-r));
3223 prefix = strrep("\t", level);
3227 if (type == SD_BUS_TYPE_ARRAY)
3228 printf("%s} END_ARRAY \n", prefix);
3229 else if (type == SD_BUS_TYPE_VARIANT)
3230 printf("%s} END_VARIANT\n", prefix);
3231 else if (type == SD_BUS_TYPE_STRUCT)
3232 printf("%s} END_STRUCT\n", prefix);
3233 else if (type == SD_BUS_TYPE_DICT_ENTRY)
3234 printf("%s} END_DICT_ENTRY\n", prefix);
3239 prefix = strrep("\t", level);
3243 if (bus_type_is_container(type) > 0) {
3244 r = sd_bus_message_enter_container(m, type, contents);
3246 log_error("Failed to enter container: %s", strerror(-r));
3250 if (type == SD_BUS_TYPE_ARRAY)
3251 printf("%sBEGIN_ARRAY \"%s\" {\n", prefix, contents);
3252 else if (type == SD_BUS_TYPE_VARIANT)
3253 printf("%sBEGIN_VARIANT \"%s\" {\n", prefix, contents);
3254 else if (type == SD_BUS_TYPE_STRUCT)
3255 printf("%sBEGIN_STRUCT \"%s\" {\n", prefix, contents);
3256 else if (type == SD_BUS_TYPE_DICT_ENTRY)
3257 printf("%sBEGIN_DICT_ENTRY \"%s\" {\n", prefix, contents);
3264 r = sd_bus_message_read_basic(m, type, &basic);
3266 log_error("Failed to get basic: %s", strerror(-r));
3272 case SD_BUS_TYPE_BYTE:
3273 printf("%sBYTE: %u\n", prefix, basic.u8);
3276 case SD_BUS_TYPE_BOOLEAN:
3277 printf("%sBOOLEAN: %s\n", prefix, yes_no(basic.i));
3280 case SD_BUS_TYPE_INT16:
3281 printf("%sINT16: %i\n", prefix, basic.s16);
3284 case SD_BUS_TYPE_UINT16:
3285 printf("%sUINT16: %u\n", prefix, basic.u16);
3288 case SD_BUS_TYPE_INT32:
3289 printf("%sINT32: %i\n", prefix, basic.s32);
3292 case SD_BUS_TYPE_UINT32:
3293 printf("%sUINT32: %u\n", prefix, basic.u32);
3296 case SD_BUS_TYPE_INT64:
3297 printf("%sINT64: %lli\n", prefix, (long long) basic.s64);
3300 case SD_BUS_TYPE_UINT64:
3301 printf("%sUINT64: %llu\n", prefix, (unsigned long long) basic.u64);
3304 case SD_BUS_TYPE_DOUBLE:
3305 printf("%sDOUBLE: %g\n", prefix, basic.d64);
3308 case SD_BUS_TYPE_STRING:
3309 printf("%sSTRING: \"%s\"\n", prefix, basic.string);
3312 case SD_BUS_TYPE_OBJECT_PATH:
3313 printf("%sOBJECT_PATH: \"%s\"\n", prefix, basic.string);
3316 case SD_BUS_TYPE_SIGNATURE:
3317 printf("%sSIGNATURE: \"%s\"\n", prefix, basic.string);
3320 case SD_BUS_TYPE_UNIX_FD:
3321 printf("%sUNIX_FD: %i\n", prefix, basic.i);
3325 assert_not_reached("Unknown basic type.");
3329 printf("} END_MESSAGE\n");
3333 int bus_message_get_blob(sd_bus_message *m, void **buffer, size_t *sz) {
3341 total = BUS_MESSAGE_SIZE(m);
3347 e = mempcpy(p, m->header, sizeof(*m->header));
3350 e = mempcpy(e, m->fields, m->header->fields_size);
3352 if (m->header->fields_size % 8 != 0)
3353 e = mempset(e, 0, 8 - (m->header->fields_size % 8));
3357 e = mempcpy(e, m->body, m->header->body_size);
3359 assert(total == (size_t) ((uint8_t*) e - (uint8_t*) p));
3367 int bus_message_read_strv_extend(sd_bus_message *m, char ***l) {
3373 r = sd_bus_message_enter_container(m, 'a', "s");
3380 r = sd_bus_message_read_basic(m, 's', &s);
3386 r = strv_extend(l, s);
3391 r = sd_bus_message_exit_container(m);
3398 const char* bus_message_get_arg(sd_bus_message *m, unsigned i) {
3400 const char *t = NULL;
3405 r = sd_bus_message_rewind(m, true);
3409 for (j = 0; j <= i; j++) {
3412 r = sd_bus_message_peek_type(m, &type, NULL);
3416 if (type != SD_BUS_TYPE_STRING &&
3417 type != SD_BUS_TYPE_OBJECT_PATH &&
3418 type != SD_BUS_TYPE_SIGNATURE)
3421 r = sd_bus_message_read_basic(m, type, &t);
3429 int bus_header_size(struct bus_header *h, size_t *sum) {
3435 if (h->endian == SD_BUS_NATIVE_ENDIAN) {
3436 fs = h->fields_size;
3438 } else if (h->endian == SD_BUS_REVERSE_ENDIAN) {
3439 fs = bswap_32(h->fields_size);
3440 bs = bswap_32(h->body_size);
3444 *sum = sizeof(struct bus_header) + ALIGN8(fs) + bs;