From 41e0eb7378a2019cc6dd1687652dc05846e2c1d9 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Wed, 20 Feb 2019 22:07:17 +0100 Subject: [PATCH] lib/dbus/udisks2: parse the MountPoints property --- src/lib/dbus/UDisks2.cxx | 58 ++++++++++++++++++++++++++++++++++++++++ src/lib/dbus/UDisks2.hxx | 7 +++++ 2 files changed, 65 insertions(+) diff --git a/src/lib/dbus/UDisks2.cxx b/src/lib/dbus/UDisks2.cxx index 2476668f4..f0a677040 100644 --- a/src/lib/dbus/UDisks2.cxx +++ b/src/lib/dbus/UDisks2.cxx @@ -22,6 +22,7 @@ #include "ReadIter.hxx" #include "ObjectManager.hxx" #include "util/StringAPI.hxx" +#include "util/StringView.hxx" #include "util/Compiler.h" #include @@ -39,6 +40,40 @@ CheckString(I &&i) noexcept return i.GetString(); } +template +gcc_pure +static StringView +CheckRecursedByteArrayToString(I &&i) noexcept +{ + if (i.GetArgType() != DBUS_TYPE_BYTE) + return nullptr; + + auto value = i.template GetFixedArray(); + return { value.data, value.size }; +} + +template +gcc_pure +static StringView +CheckByteArrayToString(I &&i) noexcept +{ + if (i.GetArgType() != DBUS_TYPE_ARRAY) + return nullptr; + + return CheckRecursedByteArrayToString(i.Recurse()); +} + +template +gcc_pure +static StringView +CheckByteArrayArrayFrontToString(I &&i) noexcept +{ + if (i.GetArgType() != DBUS_TYPE_ARRAY) + return nullptr; + + return CheckByteArrayToString(i.Recurse()); +} + static void ParseDriveDictEntry(Object &o, const char *name, ODBus::ReadMessageIter &&value_i) noexcept @@ -61,6 +96,25 @@ ParseBlockDictEntry(Object &o, const char *name, } } +static void +ParseFileesystemDictEntry(Object &o, const char *name, + ODBus::ReadMessageIter &&value_i) noexcept +{ + if (StringIsEqual(name, "MountPoints")) { + if (!o.mount_point.empty()) + /* we already know one mount point, and we're + not interested in more */ + return; + + /* get the first string in the array */ + auto value = CheckByteArrayArrayFrontToString(value_i); + if (value != nullptr) + o.mount_point = {value.data, value.size}; + + // TODO: check whether the string is a valid filesystem path + } +} + static void ParseInterface(Object &o, const char *interface, ODBus::ReadMessageIter &&i) noexcept @@ -74,6 +128,10 @@ ParseInterface(Object &o, const char *interface, std::ref(o), _1, _2)); } else if (StringIsEqual(interface, "org.freedesktop.UDisks2.Filesystem")) { o.is_filesystem = true; + + i.ForEachProperty(std::bind(ParseFileesystemDictEntry, + std::ref(o), _1, _2)); + } } diff --git a/src/lib/dbus/UDisks2.hxx b/src/lib/dbus/UDisks2.hxx index ed4126cdd..615aca5bf 100644 --- a/src/lib/dbus/UDisks2.hxx +++ b/src/lib/dbus/UDisks2.hxx @@ -39,6 +39,13 @@ struct Object { std::string drive_id, block_id; + /** + * The first element of the "MountPoints" array of the + * "Filesystem" interface. Empty if no "MountPoints" property + * exists. + */ + std::string mount_point; + bool is_filesystem = false; explicit Object(const char *_path) noexcept