X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fshared%2Fdbus-common.c;h=2769b2c882e2081a153934c56cdfba46b1d5514f;hb=9f26c90cb50c45d4549c4dd569917b4ac143b94d;hp=e9a78c299ef20f317229900fd92b62c6619cf52e;hpb=f274ece0f76b5709408821e317e87aef76123db6;p=elogind.git diff --git a/src/shared/dbus-common.c b/src/shared/dbus-common.c index e9a78c299..2769b2c88 100644 --- a/src/shared/dbus-common.c +++ b/src/shared/dbus-common.c @@ -927,6 +927,95 @@ int bus_parse_strv_iter(DBusMessageIter *iter, char ***_l) { return 0; } +int bus_parse_strv_pairs_iter(DBusMessageIter *iter, char ***_l) { + DBusMessageIter sub, sub2; + unsigned n = 0, i = 0; + char **l; + + assert(iter); + assert(_l); + + if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_ARRAY || + dbus_message_iter_get_element_type(iter) != DBUS_TYPE_STRUCT) + return -EINVAL; + + dbus_message_iter_recurse(iter, &sub); + + while (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) { + n++; + dbus_message_iter_next(&sub); + } + + l = new(char*, n*2+1); + if (!l) + return -ENOMEM; + + dbus_message_iter_recurse(iter, &sub); + + while (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) { + const char *a, *b; + + assert_se(dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_STRUCT); + + dbus_message_iter_recurse(&sub, &sub2); + + if (bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &a, true) < 0 || + bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &b, false) < 0) + return -EINVAL; + + l[i] = strdup(a); + if (!l[i]) { + strv_free(l); + return -ENOMEM; + } + + l[++i] = strdup(b); + if (!l[i]) { + strv_free(l); + return -ENOMEM; + } + + i++; + dbus_message_iter_next(&sub); + } + + assert(i == n*2); + l[i] = NULL; + + if (_l) + *_l = l; + + return 0; +} + +int bus_parse_unit_info(DBusMessageIter *iter, struct unit_info *u) { + DBusMessageIter sub; + + assert(iter); + assert(u); + + if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_STRUCT) + return -EINVAL; + + dbus_message_iter_recurse(iter, &sub); + + if (bus_iter_get_basic_and_next(&sub, DBUS_TYPE_STRING, &u->id, true) < 0 || + bus_iter_get_basic_and_next(&sub, DBUS_TYPE_STRING, &u->description, true) < 0 || + bus_iter_get_basic_and_next(&sub, DBUS_TYPE_STRING, &u->load_state, true) < 0 || + bus_iter_get_basic_and_next(&sub, DBUS_TYPE_STRING, &u->active_state, true) < 0 || + bus_iter_get_basic_and_next(&sub, DBUS_TYPE_STRING, &u->sub_state, true) < 0 || + bus_iter_get_basic_and_next(&sub, DBUS_TYPE_STRING, &u->following, true) < 0 || + bus_iter_get_basic_and_next(&sub, DBUS_TYPE_OBJECT_PATH, &u->unit_path, true) < 0 || + bus_iter_get_basic_and_next(&sub, DBUS_TYPE_UINT32, &u->job_id, true) < 0 || + bus_iter_get_basic_and_next(&sub, DBUS_TYPE_STRING, &u->job_type, true) < 0 || + bus_iter_get_basic_and_next(&sub, DBUS_TYPE_OBJECT_PATH, &u->job_path, false) < 0) { + log_error("Failed to parse reply."); + return -EIO; + } + + return 0; +} + int bus_append_strv_iter(DBusMessageIter *iter, char **l) { DBusMessageIter sub;