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_get_audit_sessionid(sd_bus_message *m, uint32_t *sessionid) {
915 *sessionid = m->audit->sessionid;
919 int sd_bus_message_get_audit_loginuid(sd_bus_message *m, uid_t *uid) {
927 *uid = m->audit->loginuid;
931 int sd_bus_message_has_effective_cap(sd_bus_message *m, int capability) {
941 sz = m->capability_size / 4;
942 if ((unsigned) capability >= sz*8)
945 return !!(m->capability[2 * sz + (capability / 8)] & (1 << (capability % 8)));
948 int sd_bus_message_is_signal(sd_bus_message *m, const char *interface, const char *member) {
952 if (m->header->type != SD_BUS_MESSAGE_TYPE_SIGNAL)
955 if (interface && (!m->interface || !streq(m->interface, interface)))
958 if (member && (!m->member || !streq(m->member, member)))
964 int sd_bus_message_is_method_call(sd_bus_message *m, const char *interface, const char *member) {
968 if (m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_CALL)
971 if (interface && (!m->interface || !streq(m->interface, interface)))
974 if (member && (!m->member || !streq(m->member, member)))
980 int sd_bus_message_is_method_error(sd_bus_message *m, const char *name) {
984 if (m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_ERROR)
987 if (name && (!m->error.name || !streq(m->error.name, name)))
993 int sd_bus_message_set_no_reply(sd_bus_message *m, int b) {
998 if (m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_CALL)
1002 m->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
1004 m->header->flags &= ~SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
1009 static struct bus_container *message_get_container(sd_bus_message *m) {
1012 if (m->n_containers == 0)
1013 return &m->root_container;
1015 assert(m->containers);
1016 return m->containers + m->n_containers - 1;
1019 static void *message_extend_body(sd_bus_message *m, size_t align, size_t sz) {
1022 struct bus_container *c;
1028 added = m->header->body_size;
1030 p = buffer_extend(&m->body, &m->header->body_size, align, sz);
1034 added = m->header->body_size - added;
1036 for (c = m->containers; c < m->containers + m->n_containers; c++)
1037 if (c->array_size) {
1038 c->array_size = (uint32_t*) ((uint8_t*) m->body + ((uint8_t*) c->array_size - (uint8_t*) o));
1039 *c->array_size += added;
1043 if (m->error.message)
1044 m->error.message = (const char*) m->body + (m->error.message - (const char*) o);
1047 m->free_body = true;
1052 int message_append_basic(sd_bus_message *m, char type, const void *p, const void **stored) {
1053 struct bus_container *c;
1068 if (!bus_type_is_basic(type))
1071 c = message_get_container(m);
1073 if (c->signature && c->signature[c->index]) {
1074 /* Container signature is already set */
1076 if (c->signature[c->index] != type)
1079 /* Maybe we can append to the signature? But only if this is the top-level container*/
1080 if (c->enclosing != 0)
1083 e = strextend(&c->signature, CHAR_TO_STR(type), NULL);
1090 case SD_BUS_TYPE_STRING:
1091 case SD_BUS_TYPE_OBJECT_PATH:
1094 sz = 4 + strlen(p) + 1;
1097 case SD_BUS_TYPE_SIGNATURE:
1100 sz = 1 + strlen(p) + 1;
1103 case SD_BUS_TYPE_BOOLEAN:
1106 assert_cc(sizeof(int) == sizeof(uint32_t));
1112 case SD_BUS_TYPE_UNIX_FD: {
1115 if (!m->allow_fds) {
1128 fd = fcntl(z, F_DUPFD_CLOEXEC, 3);
1134 f = realloc(m->fds, sizeof(int) * (m->n_fds + 1));
1148 align = bus_type_get_alignment(type);
1149 sz = bus_type_get_size(type);
1156 a = message_extend_body(m, align, sz);
1162 if (type == SD_BUS_TYPE_STRING || type == SD_BUS_TYPE_OBJECT_PATH) {
1163 *(uint32_t*) a = sz - 5;
1164 memcpy((uint8_t*) a + 4, p, sz - 4);
1167 *stored = (const uint8_t*) a + 4;
1169 } else if (type == SD_BUS_TYPE_SIGNATURE) {
1170 *(uint8_t*) a = sz - 1;
1171 memcpy((uint8_t*) a + 1, p, sz - 1);
1174 *stored = (const uint8_t*) a + 1;
1175 } else if (type == SD_BUS_TYPE_UNIX_FD) {
1176 *(uint32_t*) a = fdi;
1190 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1196 /* Truncate extended signature again */
1198 c->signature[c->index] = 0;
1201 close_nointr_nofail(fd);
1206 int sd_bus_message_append_basic(sd_bus_message *m, char type, const void *p) {
1207 return message_append_basic(m, type, p, NULL);
1210 static int bus_message_open_array(
1212 struct bus_container *c,
1213 const char *contents,
1214 uint32_t **array_size) {
1227 if (!signature_is_single(contents))
1230 alignment = bus_type_get_alignment(contents[0]);
1234 if (c->signature && c->signature[c->index]) {
1236 /* Verify the existing signature */
1238 if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
1241 if (!startswith(c->signature + c->index + 1, contents))
1244 nindex = c->index + 1 + strlen(contents);
1246 if (c->enclosing != 0)
1249 /* Extend the existing signature */
1251 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_ARRAY), contents, NULL);
1255 nindex = e - c->signature;
1258 saved = m->header->body_size;
1259 a = message_extend_body(m, 4, 4);
1261 /* Truncate extended signature again */
1263 c->signature[c->index] = 0;
1269 if (!message_extend_body(m, alignment, 0)) {
1270 /* Add alignment between size and first element */
1272 c->signature[c->index] = 0;
1274 m->header->body_size = saved;
1278 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1281 /* m->body might have changed so let's readjust a */
1282 a = (uint8_t*) m->body + ((uint8_t*) a - (uint8_t*) b);
1289 static int bus_message_open_variant(
1291 struct bus_container *c,
1292 const char *contents) {
1302 if (!signature_is_single(contents))
1305 if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
1308 if (c->signature && c->signature[c->index]) {
1310 if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
1314 if (c->enclosing != 0)
1317 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_VARIANT), NULL);
1322 l = strlen(contents);
1323 a = message_extend_body(m, 1, 1 + l + 1);
1325 /* Truncate extended signature again */
1327 c->signature[c->index] = 0;
1333 memcpy((uint8_t*) a + 1, contents, l + 1);
1335 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1341 static int bus_message_open_struct(
1343 struct bus_container *c,
1344 const char *contents) {
1353 if (!signature_is_valid(contents, false))
1356 if (c->signature && c->signature[c->index]) {
1359 l = strlen(contents);
1361 if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
1362 !startswith(c->signature + c->index + 1, contents) ||
1363 c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
1366 nindex = c->index + 1 + l + 1;
1368 if (c->enclosing != 0)
1371 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_BEGIN), contents, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_END), NULL);
1375 nindex = e - c->signature;
1378 /* Align contents to 8 byte boundary */
1379 if (!message_extend_body(m, 8, 0)) {
1381 c->signature[c->index] = 0;
1386 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1392 static int bus_message_open_dict_entry(
1394 struct bus_container *c,
1395 const char *contents) {
1403 if (!signature_is_pair(contents))
1406 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1409 if (c->signature && c->signature[c->index]) {
1412 l = strlen(contents);
1414 if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
1415 !startswith(c->signature + c->index + 1, contents) ||
1416 c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
1419 nindex = c->index + 1 + l + 1;
1423 /* Align contents to 8 byte boundary */
1424 if (!message_extend_body(m, 8, 0))
1427 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1433 int sd_bus_message_open_container(
1436 const char *contents) {
1438 struct bus_container *c, *w;
1439 uint32_t *array_size = NULL;
1451 /* Make sure we have space for one more container */
1452 w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
1457 c = message_get_container(m);
1459 signature = strdup(contents);
1463 /* Save old index in the parent container, in case we have to
1464 * abort this container */
1465 c->saved_index = c->index;
1466 before = m->header->body_size;
1468 if (type == SD_BUS_TYPE_ARRAY)
1469 r = bus_message_open_array(m, c, contents, &array_size);
1470 else if (type == SD_BUS_TYPE_VARIANT)
1471 r = bus_message_open_variant(m, c, contents);
1472 else if (type == SD_BUS_TYPE_STRUCT)
1473 r = bus_message_open_struct(m, c, contents);
1474 else if (type == SD_BUS_TYPE_DICT_ENTRY)
1475 r = bus_message_open_dict_entry(m, c, contents);
1484 /* OK, let's fill it in */
1485 w += m->n_containers++;
1486 w->enclosing = type;
1487 w->signature = signature;
1489 w->array_size = array_size;
1491 w->begin = m->rindex;
1496 int sd_bus_message_close_container(sd_bus_message *m) {
1497 struct bus_container *c;
1503 if (m->n_containers <= 0)
1506 c = message_get_container(m);
1507 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1508 if (c->signature && c->signature[c->index] != 0)
1517 static void message_abort_container(sd_bus_message *m) {
1518 struct bus_container *c;
1523 assert(m->n_containers > 0);
1525 c = message_get_container(m);
1528 assert(m->header->body_size >= c->before);
1529 delta = m->header->body_size - c->before;
1530 m->header->body_size = c->before;
1532 /* Free container */
1536 /* Correct index of new top-level container */
1537 c = message_get_container(m);
1538 c->index = c->saved_index;
1540 /* Correct array sizes all the way up */
1541 for (c = m->containers; c < m->containers + m->n_containers; c++)
1542 if (c->array_size) {
1543 assert(*c->array_size >= delta);
1544 *c->array_size -= delta;
1554 static int type_stack_push(TypeStack *stack, unsigned max, unsigned *i, const char *types, unsigned n_struct, unsigned n_array) {
1561 stack[*i].types = types;
1562 stack[*i].n_struct = n_struct;
1563 stack[*i].n_array = n_array;
1569 static int type_stack_pop(TypeStack *stack, unsigned max, unsigned *i, const char **types, unsigned *n_struct, unsigned *n_array) {
1580 *types = stack[*i].types;
1581 *n_struct = stack[*i].n_struct;
1582 *n_array = stack[*i].n_array;
1587 int bus_message_append_ap(
1592 unsigned n_array, n_struct;
1593 TypeStack stack[BUS_CONTAINER_DEPTH];
1594 unsigned stack_ptr = 0;
1602 n_array = (unsigned) -1;
1603 n_struct = strlen(types);
1608 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
1609 r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
1615 r = sd_bus_message_close_container(m);
1623 if (n_array != (unsigned) -1)
1632 case SD_BUS_TYPE_BYTE: {
1635 x = (uint8_t) va_arg(ap, int);
1636 r = sd_bus_message_append_basic(m, *t, &x);
1640 case SD_BUS_TYPE_BOOLEAN:
1641 case SD_BUS_TYPE_INT32:
1642 case SD_BUS_TYPE_UINT32:
1643 case SD_BUS_TYPE_UNIX_FD: {
1646 /* We assume a boolean is the same as int32_t */
1647 assert_cc(sizeof(int32_t) == sizeof(int));
1649 x = va_arg(ap, uint32_t);
1650 r = sd_bus_message_append_basic(m, *t, &x);
1654 case SD_BUS_TYPE_INT16:
1655 case SD_BUS_TYPE_UINT16: {
1658 x = (uint16_t) va_arg(ap, int);
1659 r = sd_bus_message_append_basic(m, *t, &x);
1663 case SD_BUS_TYPE_INT64:
1664 case SD_BUS_TYPE_UINT64:
1665 case SD_BUS_TYPE_DOUBLE: {
1668 x = va_arg(ap, uint64_t);
1669 r = sd_bus_message_append_basic(m, *t, &x);
1673 case SD_BUS_TYPE_STRING:
1674 case SD_BUS_TYPE_OBJECT_PATH:
1675 case SD_BUS_TYPE_SIGNATURE: {
1678 x = va_arg(ap, const char*);
1679 r = sd_bus_message_append_basic(m, *t, x);
1683 case SD_BUS_TYPE_ARRAY: {
1686 r = signature_element_length(t + 1, &k);
1692 memcpy(s, t + 1, k);
1695 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, s);
1700 if (n_array == (unsigned) -1) {
1705 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
1711 n_array = va_arg(ap, unsigned);
1716 case SD_BUS_TYPE_VARIANT: {
1719 s = va_arg(ap, const char*);
1723 r = sd_bus_message_open_container(m, SD_BUS_TYPE_VARIANT, s);
1727 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
1732 n_struct = strlen(s);
1733 n_array = (unsigned) -1;
1738 case SD_BUS_TYPE_STRUCT_BEGIN:
1739 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
1742 r = signature_element_length(t, &k);
1749 memcpy(s, t + 1, k - 2);
1752 r = sd_bus_message_open_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
1757 if (n_array == (unsigned) -1) {
1762 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
1768 n_array = (unsigned) -1;
1784 int sd_bus_message_append(sd_bus_message *m, const char *types, ...) {
1795 va_start(ap, types);
1796 r = bus_message_append_ap(m, types, ap);
1802 int sd_bus_message_append_array_ptr(sd_bus_message *m, char type, size_t size, void **ptr) {
1811 if (!bus_type_is_trivial(type))
1813 if (!ptr && size > 0)
1816 align = bus_type_get_alignment(type);
1817 sz = bus_type_get_size(type);
1819 assert_se(align > 0);
1825 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
1829 a = message_extend_body(m, align, size);
1835 r = sd_bus_message_close_container(m);
1843 message_abort_container(m);
1847 int sd_bus_message_append_array(sd_bus_message *m, char type, const void *ptr, size_t size) {
1851 if (!ptr && size > 0)
1854 r = sd_bus_message_append_array_ptr(m, type, size, &p);
1859 memcpy(p, ptr, size);
1864 static int buffer_peek(const void *p, uint32_t sz, size_t *rindex, size_t align, size_t nbytes, void **r) {
1870 start = ALIGN_TO((size_t) *rindex, align);
1876 /* Verify that padding is 0 */
1877 for (k = *rindex; k < start; k++)
1878 if (((const uint8_t*) p)[k] != 0)
1882 *r = (uint8_t*) p + start;
1889 static bool message_end_of_array(sd_bus_message *m, size_t index) {
1890 struct bus_container *c;
1894 c = message_get_container(m);
1898 return index >= c->begin + BUS_MESSAGE_BSWAP32(m, *c->array_size);
1901 static int message_peek_body(sd_bus_message *m, size_t *rindex, size_t align, size_t nbytes, void **ret) {
1906 if (message_end_of_array(m, *rindex))
1909 return buffer_peek(m->body, BUS_MESSAGE_BODY_SIZE(m), rindex, align, nbytes, ret);
1912 static bool validate_nul(const char *s, size_t l) {
1914 /* Check for NUL chars in the string */
1915 if (memchr(s, 0, l))
1918 /* Check for NUL termination */
1925 static bool validate_string(const char *s, size_t l) {
1927 if (!validate_nul(s, l))
1930 /* Check if valid UTF8 */
1931 if (!utf8_is_valid(s))
1937 static bool validate_signature(const char *s, size_t l) {
1939 if (!validate_nul(s, l))
1942 /* Check if valid signature */
1943 if (!signature_is_valid(s, true))
1949 static bool validate_object_path(const char *s, size_t l) {
1951 if (!validate_nul(s, l))
1954 if (!object_path_is_valid(s))
1960 int sd_bus_message_read_basic(sd_bus_message *m, char type, void *p) {
1961 struct bus_container *c;
1969 if (!bus_type_is_basic(type))
1974 c = message_get_container(m);
1976 if (!c->signature || c->signature[c->index] == 0)
1979 if (c->signature[c->index] != type)
1984 case SD_BUS_TYPE_STRING:
1985 case SD_BUS_TYPE_OBJECT_PATH: {
1990 r = message_peek_body(m, &rindex, 4, 4, &q);
1994 l = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
1995 r = message_peek_body(m, &rindex, 1, l+1, &q);
2001 if (type == SD_BUS_TYPE_OBJECT_PATH) {
2002 if (!validate_object_path(q, l))
2005 if (!validate_string(q, l))
2010 *(const char**) p = q;
2014 case SD_BUS_TYPE_SIGNATURE: {
2019 r = message_peek_body(m, &rindex, 1, 1, &q);
2024 r = message_peek_body(m, &rindex, 1, l+1, &q);
2030 if (!validate_signature(q, l))
2034 *(const char**) p = q;
2042 align = bus_type_get_alignment(type);
2043 sz = bus_type_get_size(type);
2044 assert(align > 0 && sz > 0);
2047 r = message_peek_body(m, &rindex, align, sz, &q);
2053 case SD_BUS_TYPE_BYTE:
2054 *(uint8_t*) p = *(uint8_t*) q;
2057 case SD_BUS_TYPE_BOOLEAN:
2058 *(int*) p = !!*(uint32_t*) q;
2061 case SD_BUS_TYPE_INT16:
2062 case SD_BUS_TYPE_UINT16:
2063 *(uint16_t*) p = BUS_MESSAGE_BSWAP16(m, *(uint16_t*) q);
2066 case SD_BUS_TYPE_INT32:
2067 case SD_BUS_TYPE_UINT32:
2068 *(uint32_t*) p = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2071 case SD_BUS_TYPE_INT64:
2072 case SD_BUS_TYPE_UINT64:
2073 case SD_BUS_TYPE_DOUBLE:
2074 *(uint64_t*) p = BUS_MESSAGE_BSWAP64(m, *(uint64_t*) q);
2077 case SD_BUS_TYPE_UNIX_FD: {
2080 j = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2084 *(int*) p = m->fds[j];
2089 assert_not_reached("Unknown basic type...");
2098 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2104 static int bus_message_enter_array(
2106 struct bus_container *c,
2107 const char *contents,
2108 uint32_t **array_size) {
2119 if (!signature_is_single(contents))
2122 alignment = bus_type_get_alignment(contents[0]);
2126 if (!c->signature || c->signature[c->index] == 0)
2129 if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
2132 if (!startswith(c->signature + c->index + 1, contents))
2136 r = message_peek_body(m, &rindex, 4, 4, &q);
2140 if (BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q) > BUS_ARRAY_MAX_SIZE)
2143 r = message_peek_body(m, &rindex, alignment, 0, NULL);
2149 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2150 c->index += 1 + strlen(contents);
2154 *array_size = (uint32_t*) q;
2159 static int bus_message_enter_variant(
2161 struct bus_container *c,
2162 const char *contents) {
2173 if (!signature_is_single(contents))
2176 if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
2179 if (!c->signature || c->signature[c->index] == 0)
2182 if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
2186 r = message_peek_body(m, &rindex, 1, 1, &q);
2191 r = message_peek_body(m, &rindex, 1, l+1, &q);
2197 if (!validate_signature(q, l))
2200 if (!streq(q, contents))
2203 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2211 static int bus_message_enter_struct(
2213 struct bus_container *c,
2214 const char *contents) {
2223 if (!signature_is_valid(contents, false))
2226 if (!c->signature || c->signature[c->index] == 0)
2229 l = strlen(contents);
2231 if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
2232 !startswith(c->signature + c->index + 1, contents) ||
2233 c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
2236 r = message_peek_body(m, &m->rindex, 8, 0, NULL);
2240 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2241 c->index += 1 + l + 1;
2246 static int bus_message_enter_dict_entry(
2248 struct bus_container *c,
2249 const char *contents) {
2258 if (!signature_is_pair(contents))
2261 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2264 if (!c->signature || c->signature[c->index] == 0)
2267 l = strlen(contents);
2269 if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
2270 !startswith(c->signature + c->index + 1, contents) ||
2271 c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
2274 r = message_peek_body(m, &m->rindex, 8, 0, NULL);
2278 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2279 c->index += 1 + l + 1;
2284 int sd_bus_message_enter_container(sd_bus_message *m, char type, const char *contents) {
2285 struct bus_container *c, *w;
2286 uint32_t *array_size = NULL;
2299 * We enforce a global limit on container depth, that is much
2300 * higher than the 32 structs and 32 arrays the specification
2301 * mandates. This is simpler to implement for us, and we need
2302 * this only to ensure our container array doesn't grow
2303 * without bounds. We are happy to return any data from a
2304 * message as long as the data itself is valid, even if the
2305 * overall message might be not.
2307 * Note that the message signature is validated when
2308 * parsing the headers, and that validation does check the
2311 * Note that the specification defines no limits on the depth
2312 * of stacked variants, but we do.
2314 if (m->n_containers >= BUS_CONTAINER_DEPTH)
2317 w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
2322 c = message_get_container(m);
2324 if (!c->signature || c->signature[c->index] == 0)
2327 signature = strdup(contents);
2331 c->saved_index = c->index;
2334 if (type == SD_BUS_TYPE_ARRAY)
2335 r = bus_message_enter_array(m, c, contents, &array_size);
2336 else if (type == SD_BUS_TYPE_VARIANT)
2337 r = bus_message_enter_variant(m, c, contents);
2338 else if (type == SD_BUS_TYPE_STRUCT)
2339 r = bus_message_enter_struct(m, c, contents);
2340 else if (type == SD_BUS_TYPE_DICT_ENTRY)
2341 r = bus_message_enter_dict_entry(m, c, contents);
2350 /* OK, let's fill it in */
2351 w += m->n_containers++;
2352 w->enclosing = type;
2353 w->signature = signature;
2355 w->array_size = array_size;
2357 w->begin = m->rindex;
2362 int sd_bus_message_exit_container(sd_bus_message *m) {
2363 struct bus_container *c;
2369 if (m->n_containers <= 0)
2372 c = message_get_container(m);
2373 if (c->enclosing == SD_BUS_TYPE_ARRAY) {
2376 l = BUS_MESSAGE_BSWAP32(m, *c->array_size);
2377 if (c->begin + l != m->rindex)
2381 if (c->signature && c->signature[c->index] != 0)
2391 static void message_quit_container(sd_bus_message *m) {
2392 struct bus_container *c;
2396 assert(m->n_containers > 0);
2398 c = message_get_container(m);
2401 assert(m->rindex >= c->before);
2402 m->rindex = c->before;
2404 /* Free container */
2408 /* Correct index of new top-level container */
2409 c = message_get_container(m);
2410 c->index = c->saved_index;
2413 int sd_bus_message_peek_type(sd_bus_message *m, char *type, const char **contents) {
2414 struct bus_container *c;
2422 c = message_get_container(m);
2424 if (!c->signature || c->signature[c->index] == 0)
2427 if (message_end_of_array(m, m->rindex))
2430 if (bus_type_is_basic(c->signature[c->index])) {
2434 *type = c->signature[c->index];
2438 if (c->signature[c->index] == SD_BUS_TYPE_ARRAY) {
2444 r = signature_element_length(c->signature+c->index+1, &l);
2450 sig = strndup(c->signature + c->index + 1, l);
2454 free(m->peeked_signature);
2455 m->peeked_signature = sig;
2461 *type = SD_BUS_TYPE_ARRAY;
2466 if (c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ||
2467 c->signature[c->index] == SD_BUS_TYPE_DICT_ENTRY_BEGIN) {
2473 r = signature_element_length(c->signature+c->index, &l);
2478 sig = strndup(c->signature + c->index + 1, l - 2);
2482 free(m->peeked_signature);
2483 m->peeked_signature = sig;
2489 *type = c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY;
2494 if (c->signature[c->index] == SD_BUS_TYPE_VARIANT) {
2500 r = message_peek_body(m, &rindex, 1, 1, &q);
2507 r = message_peek_body(m, &rindex, 1, l+1, &q);
2513 if (!validate_signature(q, l))
2520 *type = SD_BUS_TYPE_VARIANT;
2529 *type = c->enclosing;
2535 int sd_bus_message_rewind(sd_bus_message *m, int complete) {
2536 struct bus_container *c;
2544 reset_containers(m);
2546 m->root_container.index = 0;
2548 c = message_get_container(m);
2550 c = message_get_container(m);
2553 m->rindex = c->begin;
2556 return !isempty(c->signature);
2558 static int message_read_ap(
2563 unsigned n_array, n_struct;
2564 TypeStack stack[BUS_CONTAINER_DEPTH];
2565 unsigned stack_ptr = 0;
2573 /* Ideally, we'd just call ourselves recursively on every
2574 * complex type. However, the state of a va_list that is
2575 * passed to a function is undefined after that function
2576 * returns. This means we need to docode the va_list linearly
2577 * in a single stackframe. We hence implement our own
2578 * home-grown stack in an array. */
2580 n_array = (unsigned) -1;
2581 n_struct = strlen(types);
2586 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
2587 r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
2593 r = sd_bus_message_exit_container(m);
2601 if (n_array != (unsigned) -1)
2610 case SD_BUS_TYPE_BYTE:
2611 case SD_BUS_TYPE_BOOLEAN:
2612 case SD_BUS_TYPE_INT16:
2613 case SD_BUS_TYPE_UINT16:
2614 case SD_BUS_TYPE_INT32:
2615 case SD_BUS_TYPE_UINT32:
2616 case SD_BUS_TYPE_INT64:
2617 case SD_BUS_TYPE_UINT64:
2618 case SD_BUS_TYPE_DOUBLE:
2619 case SD_BUS_TYPE_STRING:
2620 case SD_BUS_TYPE_OBJECT_PATH:
2621 case SD_BUS_TYPE_SIGNATURE:
2622 case SD_BUS_TYPE_UNIX_FD: {
2625 p = va_arg(ap, void*);
2626 r = sd_bus_message_read_basic(m, *t, p);
2635 case SD_BUS_TYPE_ARRAY: {
2638 r = signature_element_length(t + 1, &k);
2644 memcpy(s, t + 1, k);
2647 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, s);
2654 if (n_array == (unsigned) -1) {
2659 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2665 n_array = va_arg(ap, unsigned);
2670 case SD_BUS_TYPE_VARIANT: {
2673 s = va_arg(ap, const char *);
2677 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, s);
2683 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2688 n_struct = strlen(s);
2689 n_array = (unsigned) -1;
2694 case SD_BUS_TYPE_STRUCT_BEGIN:
2695 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
2698 r = signature_element_length(t, &k);
2704 memcpy(s, t + 1, k - 2);
2707 r = sd_bus_message_enter_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
2714 if (n_array == (unsigned) -1) {
2719 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2725 n_array = (unsigned) -1;
2738 int sd_bus_message_read(sd_bus_message *m, const char *types, ...) {
2749 va_start(ap, types);
2750 r = message_read_ap(m, types, ap);
2756 int sd_bus_message_read_array(sd_bus_message *m, char type, const void **ptr, size_t *size) {
2757 struct bus_container *c;
2767 if (!bus_type_is_trivial(type))
2773 if (BUS_MESSAGE_NEED_BSWAP(m))
2776 align = bus_type_get_alignment(type);
2780 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
2784 c = message_get_container(m);
2785 sz = BUS_MESSAGE_BSWAP32(m, *c->array_size);
2787 r = message_peek_body(m, &m->rindex, align, sz, &p);
2795 r = sd_bus_message_exit_container(m);
2799 *ptr = (const void*) p;
2805 message_quit_container(m);
2809 static int message_peek_fields(
2820 return buffer_peek(m->fields, BUS_MESSAGE_FIELDS_SIZE(m), rindex, align, nbytes, ret);
2823 static int message_peek_field_uint32(
2834 r = message_peek_fields(m, ri, 4, 4, &q);
2839 *ret = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2844 static int message_peek_field_string(
2846 bool (*validate)(const char *p),
2857 r = message_peek_field_uint32(m, ri, &l);
2861 r = message_peek_fields(m, ri, 1, l+1, &q);
2866 if (!validate_nul(q, l))
2872 if (!validate_string(q, l))
2882 static int message_peek_field_signature(
2894 r = message_peek_fields(m, ri, 1, 1, &q);
2899 r = message_peek_fields(m, ri, 1, l+1, &q);
2903 if (!validate_signature(q, l))
2912 static int message_skip_fields(
2915 uint32_t array_size,
2916 const char **signature) {
2918 size_t original_index;
2925 original_index = *ri;
2931 if (array_size != (uint32_t) -1 &&
2932 array_size <= *ri - original_index)
2939 if (t == SD_BUS_TYPE_STRING) {
2941 r = message_peek_field_string(m, NULL, ri, NULL);
2947 } else if (t == SD_BUS_TYPE_OBJECT_PATH) {
2949 r = message_peek_field_string(m, object_path_is_valid, ri, NULL);
2955 } else if (t == SD_BUS_TYPE_SIGNATURE) {
2957 r = message_peek_field_signature(m, ri, NULL);
2963 } else if (bus_type_is_basic(t)) {
2966 align = bus_type_get_alignment(t);
2967 k = bus_type_get_size(t);
2968 assert(align > 0 && k > 0);
2970 r = message_peek_fields(m, ri, align, k, NULL);
2976 } else if (t == SD_BUS_TYPE_ARRAY) {
2978 r = signature_element_length(*signature+1, &l);
2988 strncpy(sig, *signature + 1, l-1);
2991 alignment = bus_type_get_alignment(sig[0]);
2995 r = message_peek_field_uint32(m, ri, &nas);
2998 if (nas > BUS_ARRAY_MAX_SIZE)
3001 r = message_peek_fields(m, ri, alignment, 0, NULL);
3005 r = message_skip_fields(m, ri, nas, (const char**) &s);
3010 (*signature) += 1 + l;
3012 } else if (t == SD_BUS_TYPE_VARIANT) {
3015 r = message_peek_field_signature(m, ri, &s);
3019 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
3025 } else if (t == SD_BUS_TYPE_STRUCT ||
3026 t == SD_BUS_TYPE_DICT_ENTRY) {
3028 r = signature_element_length(*signature, &l);
3035 strncpy(sig, *signature + 1, l-1);
3038 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
3049 int bus_message_parse_fields(sd_bus_message *m) {
3052 uint32_t unix_fds = 0;
3056 for (ri = 0; ri < BUS_MESSAGE_FIELDS_SIZE(m); ) {
3057 const char *signature;
3060 r = message_peek_fields(m, &ri, 8, 1, (void**) &header);
3064 r = message_peek_field_signature(m, &ri, &signature);
3069 case _SD_BUS_MESSAGE_HEADER_INVALID:
3072 case SD_BUS_MESSAGE_HEADER_PATH:
3077 if (!streq(signature, "o"))
3080 r = message_peek_field_string(m, object_path_is_valid, &ri, &m->path);
3083 case SD_BUS_MESSAGE_HEADER_INTERFACE:
3088 if (!streq(signature, "s"))
3091 r = message_peek_field_string(m, interface_name_is_valid, &ri, &m->interface);
3094 case SD_BUS_MESSAGE_HEADER_MEMBER:
3099 if (!streq(signature, "s"))
3102 r = message_peek_field_string(m, member_name_is_valid, &ri, &m->member);
3105 case SD_BUS_MESSAGE_HEADER_ERROR_NAME:
3110 if (!streq(signature, "s"))
3113 r = message_peek_field_string(m, error_name_is_valid, &ri, &m->error.name);
3116 case SD_BUS_MESSAGE_HEADER_DESTINATION:
3121 if (!streq(signature, "s"))
3124 r = message_peek_field_string(m, service_name_is_valid, &ri, &m->destination);
3127 case SD_BUS_MESSAGE_HEADER_SENDER:
3132 if (!streq(signature, "s"))
3135 r = message_peek_field_string(m, service_name_is_valid, &ri, &m->sender);
3139 case SD_BUS_MESSAGE_HEADER_SIGNATURE: {
3143 if (m->root_container.signature)
3146 if (!streq(signature, "g"))
3149 r = message_peek_field_signature(m, &ri, &s);
3157 free(m->root_container.signature);
3158 m->root_container.signature = c;
3162 case SD_BUS_MESSAGE_HEADER_REPLY_SERIAL:
3163 if (m->reply_serial != 0)
3166 if (!streq(signature, "u"))
3169 r = message_peek_field_uint32(m, &ri, &m->reply_serial);
3173 if (m->reply_serial == 0)
3178 case SD_BUS_MESSAGE_HEADER_UNIX_FDS:
3182 if (!streq(signature, "u"))
3185 r = message_peek_field_uint32(m, &ri, &unix_fds);
3195 r = message_skip_fields(m, &ri, (uint32_t) -1, (const char **) &signature);
3202 if (m->n_fds != unix_fds)
3205 if (isempty(m->root_container.signature) != (BUS_MESSAGE_BODY_SIZE(m) == 0))
3208 switch (m->header->type) {
3210 case SD_BUS_MESSAGE_TYPE_SIGNAL:
3211 if (!m->path || !m->interface || !m->member)
3215 case SD_BUS_MESSAGE_TYPE_METHOD_CALL:
3217 if (!m->path || !m->member)
3222 case SD_BUS_MESSAGE_TYPE_METHOD_RETURN:
3224 if (m->reply_serial == 0)
3228 case SD_BUS_MESSAGE_TYPE_METHOD_ERROR:
3230 if (m->reply_serial == 0 || !m->error.name)
3235 /* Try to read the error message, but if we can't it's a non-issue */
3236 if (m->header->type == SD_BUS_MESSAGE_TYPE_METHOD_ERROR)
3237 sd_bus_message_read(m, "s", &m->error.message);
3242 int bus_message_seal(sd_bus_message *m, uint64_t serial) {
3251 if (m->n_containers > 0)
3254 /* If there's a non-trivial signature set, then add it in here */
3255 if (!isempty(m->root_container.signature)) {
3256 r = message_append_field_signature(m, SD_BUS_MESSAGE_HEADER_SIGNATURE, m->root_container.signature, NULL);
3262 r = message_append_field_uint32(m, SD_BUS_MESSAGE_HEADER_UNIX_FDS, m->n_fds);
3267 l = BUS_MESSAGE_FIELDS_SIZE(m);
3271 /* Add padding at the end, since we know the body
3272 * needs to start at an 8 byte alignment. */
3275 p = message_extend_fields(m, 1, a);
3280 m->header->fields_size -= a;
3283 m->header->serial = serial;
3289 int sd_bus_message_set_destination(sd_bus_message *m, const char *destination) {
3299 return message_append_field_string(m, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &m->destination);
3302 int bus_message_dump(sd_bus_message *m) {
3303 const char *u = NULL, *uu = NULL, *s = NULL;
3304 char **cmdline = NULL;
3307 uid_t owner, audit_loginuid;
3308 uint32_t audit_sessionid;
3312 printf("Message %p\n"
3319 "\tfields_size=%u\n"
3324 "\tdestination=%s\n"
3327 "\treply_serial=%u\n"
3329 "\terror.message=%s\n"
3337 BUS_MESSAGE_SERIAL(m),
3338 BUS_MESSAGE_FIELDS_SIZE(m),
3339 BUS_MESSAGE_BODY_SIZE(m),
3341 strna(m->interface),
3343 strna(m->destination),
3345 strna(m->root_container.signature),
3347 strna(m->error.name),
3348 strna(m->error.message),
3352 printf("\tpid=%lu\n", (unsigned long) m->pid);
3354 printf("\ttid=%lu\n", (unsigned long) m->tid);
3356 printf("\tuid=%lu\n", (unsigned long) m->uid);
3358 printf("\tgid=%lu\n", (unsigned long) m->gid);
3359 if (m->pid_starttime != 0)
3360 printf("\tpid_starttime=%llu\n", (unsigned long long) m->pid_starttime);
3361 if (m->monotonic != 0)
3362 printf("\tmonotonic=%llu\n", (unsigned long long) m->monotonic);
3363 if (m->realtime != 0)
3364 printf("\trealtime=%llu\n", (unsigned long long) m->realtime);
3366 printf("\texe=[%s]\n", m->exe);
3368 printf("\tcomm=[%s]\n", m->comm);
3370 printf("\ttid_comm=[%s]\n", m->tid_comm);
3372 printf("\tlabel=[%s]\n", m->label);
3374 printf("\tcgroup=[%s]\n", m->cgroup);
3376 sd_bus_message_get_unit(m, &u);
3378 printf("\tunit=[%s]\n", u);
3379 sd_bus_message_get_user_unit(m, &uu);
3381 printf("\tuser_unit=[%s]\n", uu);
3382 sd_bus_message_get_session(m, &s);
3384 printf("\tsession=[%s]\n", s);
3385 if (sd_bus_message_get_owner_uid(m, &owner) >= 0)
3386 printf("\towner_uid=%lu\n", (unsigned long) owner);
3387 if (sd_bus_message_get_audit_loginuid(m, &audit_loginuid) >= 0)
3388 printf("\taudit_loginuid=%lu\n", (unsigned long) audit_loginuid);
3389 if (sd_bus_message_get_audit_sessionid(m, &audit_sessionid) >= 0)
3390 printf("\taudit_sessionid=%lu\n", (unsigned long) audit_sessionid);
3392 printf("\tCAP_KILL=%i\n", sd_bus_message_has_effective_cap(m, 5));
3394 if (sd_bus_message_get_cmdline(m, &cmdline) >= 0) {
3397 fputs("\tcmdline=[", stdout);
3398 STRV_FOREACH(c, cmdline) {
3405 fputs("]\n", stdout);
3408 r = sd_bus_message_rewind(m, true);
3410 log_error("Failed to rewind: %s", strerror(-r));
3414 printf("BEGIN_MESSAGE \"%s\" {\n", strempty(m->root_container.signature));
3417 _cleanup_free_ char *prefix = NULL;
3418 const char *contents = NULL;
3433 r = sd_bus_message_peek_type(m, &type, &contents);
3435 log_error("Failed to peek type: %s", strerror(-r));
3442 r = sd_bus_message_exit_container(m);
3444 log_error("Failed to exit container: %s", strerror(-r));
3450 prefix = strrep("\t", level);
3454 if (type == SD_BUS_TYPE_ARRAY)
3455 printf("%s} END_ARRAY \n", prefix);
3456 else if (type == SD_BUS_TYPE_VARIANT)
3457 printf("%s} END_VARIANT\n", prefix);
3458 else if (type == SD_BUS_TYPE_STRUCT)
3459 printf("%s} END_STRUCT\n", prefix);
3460 else if (type == SD_BUS_TYPE_DICT_ENTRY)
3461 printf("%s} END_DICT_ENTRY\n", prefix);
3466 prefix = strrep("\t", level);
3470 if (bus_type_is_container(type) > 0) {
3471 r = sd_bus_message_enter_container(m, type, contents);
3473 log_error("Failed to enter container: %s", strerror(-r));
3477 if (type == SD_BUS_TYPE_ARRAY)
3478 printf("%sBEGIN_ARRAY \"%s\" {\n", prefix, contents);
3479 else if (type == SD_BUS_TYPE_VARIANT)
3480 printf("%sBEGIN_VARIANT \"%s\" {\n", prefix, contents);
3481 else if (type == SD_BUS_TYPE_STRUCT)
3482 printf("%sBEGIN_STRUCT \"%s\" {\n", prefix, contents);
3483 else if (type == SD_BUS_TYPE_DICT_ENTRY)
3484 printf("%sBEGIN_DICT_ENTRY \"%s\" {\n", prefix, contents);
3491 r = sd_bus_message_read_basic(m, type, &basic);
3493 log_error("Failed to get basic: %s", strerror(-r));
3499 case SD_BUS_TYPE_BYTE:
3500 printf("%sBYTE: %u\n", prefix, basic.u8);
3503 case SD_BUS_TYPE_BOOLEAN:
3504 printf("%sBOOLEAN: %s\n", prefix, yes_no(basic.i));
3507 case SD_BUS_TYPE_INT16:
3508 printf("%sINT16: %i\n", prefix, basic.s16);
3511 case SD_BUS_TYPE_UINT16:
3512 printf("%sUINT16: %u\n", prefix, basic.u16);
3515 case SD_BUS_TYPE_INT32:
3516 printf("%sINT32: %i\n", prefix, basic.s32);
3519 case SD_BUS_TYPE_UINT32:
3520 printf("%sUINT32: %u\n", prefix, basic.u32);
3523 case SD_BUS_TYPE_INT64:
3524 printf("%sINT64: %lli\n", prefix, (long long) basic.s64);
3527 case SD_BUS_TYPE_UINT64:
3528 printf("%sUINT64: %llu\n", prefix, (unsigned long long) basic.u64);
3531 case SD_BUS_TYPE_DOUBLE:
3532 printf("%sDOUBLE: %g\n", prefix, basic.d64);
3535 case SD_BUS_TYPE_STRING:
3536 printf("%sSTRING: \"%s\"\n", prefix, basic.string);
3539 case SD_BUS_TYPE_OBJECT_PATH:
3540 printf("%sOBJECT_PATH: \"%s\"\n", prefix, basic.string);
3543 case SD_BUS_TYPE_SIGNATURE:
3544 printf("%sSIGNATURE: \"%s\"\n", prefix, basic.string);
3547 case SD_BUS_TYPE_UNIX_FD:
3548 printf("%sUNIX_FD: %i\n", prefix, basic.i);
3552 assert_not_reached("Unknown basic type.");
3556 printf("} END_MESSAGE\n");
3560 int bus_message_get_blob(sd_bus_message *m, void **buffer, size_t *sz) {
3568 total = BUS_MESSAGE_SIZE(m);
3574 e = mempcpy(p, m->header, sizeof(*m->header));
3577 e = mempcpy(e, m->fields, m->header->fields_size);
3579 if (m->header->fields_size % 8 != 0)
3580 e = mempset(e, 0, 8 - (m->header->fields_size % 8));
3584 e = mempcpy(e, m->body, m->header->body_size);
3586 assert(total == (size_t) ((uint8_t*) e - (uint8_t*) p));
3594 int bus_message_read_strv_extend(sd_bus_message *m, char ***l) {
3600 r = sd_bus_message_enter_container(m, 'a', "s");
3607 r = sd_bus_message_read_basic(m, 's', &s);
3613 r = strv_extend(l, s);
3618 r = sd_bus_message_exit_container(m);
3625 const char* bus_message_get_arg(sd_bus_message *m, unsigned i) {
3627 const char *t = NULL;
3632 r = sd_bus_message_rewind(m, true);
3636 for (j = 0; j <= i; j++) {
3639 r = sd_bus_message_peek_type(m, &type, NULL);
3643 if (type != SD_BUS_TYPE_STRING &&
3644 type != SD_BUS_TYPE_OBJECT_PATH &&
3645 type != SD_BUS_TYPE_SIGNATURE)
3648 r = sd_bus_message_read_basic(m, type, &t);
3656 int bus_header_size(struct bus_header *h, size_t *sum) {
3662 if (h->endian == SD_BUS_NATIVE_ENDIAN) {
3663 fs = h->fields_size;
3665 } else if (h->endian == SD_BUS_REVERSE_ENDIAN) {
3666 fs = bswap_32(h->fields_size);
3667 bs = bswap_32(h->body_size);
3671 *sum = sizeof(struct bus_header) + ALIGN8(fs) + bs;