diff options
Diffstat (limited to 'src/slack-timedate.cpp')
| -rw-r--r-- | src/slack-timedate.cpp | 202 |
1 files changed, 96 insertions, 106 deletions
diff --git a/src/slack-timedate.cpp b/src/slack-timedate.cpp index f5a476e..f2c637a 100644 --- a/src/slack-timedate.cpp +++ b/src/slack-timedate.cpp @@ -27,152 +27,105 @@ #include "slack-timedate.h" -static void slack_method_call (GDBusConnection *connection, const gchar *sender, const gchar *object_path, const gchar *interface_name, const gchar *method_name, GVariant *parameters, GDBusMethodInvocation *invocation, gpointer user_data) { - gchar *timezone, *response; - gboolean user_interaction, relative, is_localtime, use_ntp; - gint64 usec_utc; - auto timedate1 = reinterpret_cast<dlackware::timedate::timedate1 *>(user_data); - - // Set time zone - if (g_strcmp0(method_name, "SetTimezone") == 0) +static void slack_method_call(const Glib::RefPtr<Gio::DBus::Connection>& connection, const Glib::ustring& sender, + const Glib::ustring& object_path, const Glib::ustring& interface_name, const Glib::ustring& method_name, + const Glib::VariantContainerBase& parameters, const Glib::RefPtr<Gio::DBus::MethodInvocation>& invocation) { + gchar *timezone; + gboolean user_interaction, relative, is_localtime, use_ntp; + gint64 usec_utc; + auto parameters_copy = parameters.gobj_copy(); + + // Set time zone + if (method_name == "SetTimezone") { - g_variant_get(parameters, "(&sb)", &timezone, &user_interaction); + g_variant_get(parameters_copy, "(&sb)", &timezone, &user_interaction); std::error_code error_code; - if (timedate1->set_timezone(timezone, error_code)) + if (dlackware::timedate::set_timezone(timezone, error_code)) { - g_dbus_method_invocation_return_value(invocation, NULL); + g_dbus_method_invocation_return_value(invocation->gobj(), NULL); } - else + else { - g_dbus_method_invocation_return_error(invocation, G_IO_ERROR, G_IO_ERROR_FAILED, - "Set time zone: %s", + g_dbus_method_invocation_return_error(invocation->gobj(), G_IO_ERROR, G_IO_ERROR_FAILED, + "Set time zone: %s", error_code ? error_code.message().c_str() : "Zone info is not a regular file"); } - g_free (timezone); + g_free (timezone); } - else if (g_strcmp0(method_name, "SetTime") == 0) + else if (method_name == "SetTime") { - g_variant_get (parameters, "(xbb)", &usec_utc, &relative, &user_interaction); + g_variant_get(parameters_copy, "(xbb)", &usec_utc, &relative, &user_interaction); - // Set time - //if (!slack_set_time (usec_utc, slack_get_is_localtime ())) { - if (slack_set_time(usec_utc, relative)) + // Set time + //if (!slack_set_time (usec_utc, slack_get_is_localtime ())) { + if (slack_set_time(usec_utc, relative)) { - g_dbus_method_invocation_return_value(invocation, NULL); + g_dbus_method_invocation_return_value(invocation->gobj(), NULL); } - else + else { - g_dbus_method_invocation_return_error(invocation, G_IO_ERROR, G_IO_ERROR_FAILED, + g_dbus_method_invocation_return_error(invocation->gobj(), G_IO_ERROR, G_IO_ERROR_FAILED, "Failed to set system clock"); } } - else if (g_strcmp0(method_name, "SetNTP") == 0) + else if (method_name == "SetNTP") { - g_variant_get (parameters, "(bb)", &use_ntp, &user_interaction); + g_variant_get(parameters_copy, "(bb)", &use_ntp, &user_interaction); - // Enable NTP + // Enable NTP if (slack_set_ntp (use_ntp)) { - g_dbus_method_invocation_return_value (invocation, NULL); + g_dbus_method_invocation_return_value(invocation->gobj(), NULL); } else { - g_dbus_method_invocation_return_error (invocation, - G_IO_ERROR, - G_IO_ERROR_FAILED, - "Error enabling NTP"); + g_dbus_method_invocation_return_error(invocation->gobj(), + G_IO_ERROR, + G_IO_ERROR_FAILED, + "Error enabling NTP"); } - } - else if (g_strcmp0(method_name, "ListTimezones") == 0) + } + else if (method_name == "ListTimezones") { try { auto return_tuple = Glib::Variant<std::vector<Glib::ustring>>::create_tuple({ - timedate1->list_timezones() + dlackware::timedate::list_timezones() }); - g_dbus_method_invocation_return_value(invocation, return_tuple.gobj()); + g_dbus_method_invocation_return_value(invocation->gobj(), return_tuple.gobj()); } catch (const std::exception& exception) { - g_dbus_method_invocation_return_error(invocation, G_IO_ERROR, G_IO_ERROR_FAILED, + g_dbus_method_invocation_return_error(invocation->gobj(), G_IO_ERROR, G_IO_ERROR_FAILED, "List time zones: %s", exception.what()); } } + g_free(parameters_copy); } -static GVariant *slack_get_property (GDBusConnection *connection, const gchar *sender, const gchar *object_path, const gchar *interface_name, const gchar *prop_name, GError **slack_err, gpointer user_data) { - auto timedate1 = reinterpret_cast<dlackware::timedate::timedate1 *>(user_data); - - if (g_strcmp0 ("Timezone", prop_name) == 0) { - return Glib::Variant<Glib::ustring>::create(timedate1->timezone()).gobj_copy(); - } if (g_strcmp0 ("LocalRTC", prop_name) == 0) { - return g_variant_new_boolean (slack_get_is_localtime ()); - } if (g_strcmp0 ("NTP", prop_name) == 0) { - return g_variant_new_boolean (slack_get_ntp ()); - } - return NULL; -} - -static void on_timedate_acquired(const Glib::RefPtr<Gio::DBus::Connection>& connection, - const Glib::ustring& name, gpointer user_data) +static void slack_get_property(Glib::VariantBase& result, const Glib::RefPtr<Gio::DBus::Connection>& connection, + const Glib::ustring& sender, const Glib::ustring& object_path, const Glib::ustring& interface_name, + const Glib::ustring& prop_name) { - Glib::RefPtr<Gio::DBus::NodeInfo> introspection_data; - static const auto interface_vtable = Gio::DBus::InterfaceVTable( - [user_data](const Glib::RefPtr<Gio::DBus::Connection>& connection, - const Glib::ustring& sender, - const Glib::ustring& obj_path, - const Glib::ustring& interface_name, - const Glib::ustring& method_name, - const Glib::VariantContainerBase& parameters, - const Glib::RefPtr<Gio::DBus::MethodInvocation>& invocation) { - - auto parameters_copy = parameters.gobj_copy(); - slack_method_call(connection->gobj(), sender.data(), obj_path.data(), interface_name.data(), - method_name.data(), parameters_copy, invocation->gobj(), user_data); - g_free(parameters_copy); - }, - [user_data](Glib::VariantBase& result, - const Glib::RefPtr<Gio::DBus::Connection>& connection, - const Glib::ustring& sender, - const Glib::ustring& obj_path, - const Glib::ustring& interface_name, - const Glib::ustring& prop_name) { - - auto property_result = slack_get_property(connection->gobj(), sender.data(), obj_path.data(), - interface_name.data(), prop_name.data(), nullptr, user_data); - result.init(property_result, true); - } - ); - - try - { - introspection_data = Gio::DBus::NodeInfo::create_for_xml(INTROSPECTION_XML); - } - catch (Glib::Error& slack_err) + if (prop_name == "Timezone") { - g_error("Failed to parse D-Bus introspection XML: %s\n", slack_err.what().data()); + result = Glib::Variant<Glib::ustring>::create(dlackware::timedate::timezone()); } - try + else if (prop_name == "LocalRTC") { - guint registration_id = connection->register_object(BUS_PATH, - introspection_data->lookup_interface(), interface_vtable); + result = Glib::Variant<bool>::create(slack_get_is_localtime()); } - catch (Glib::Error& slack_err) + else if (prop_name == "NTP") { - g_critical("Failed to register callbacks for the exported object with the D-Bus interface: %s\n", - slack_err.what().data()); + result = Glib::Variant<bool>::create(slack_get_ntp()); } } -static void on_timedate_lost(const Glib::RefPtr<Gio::DBus::Connection>& connection, const Glib::ustring& name) { - g_warning("Failed to acquire the service %s.\n", name.data()); - exit(1); -} - -gboolean timeout_callback (Glib::RefPtr<Glib::MainLoop> loop2quit) { - loop2quit->quit(); - return false; +gboolean timeout_callback(Glib::RefPtr<Glib::MainLoop> loop2quit) +{ + loop2quit->quit(); + return false; } int main(int argc, char **argv) @@ -181,9 +134,11 @@ int main(int argc, char **argv) auto timedate1 = std::make_unique<dlackware::timedate::timedate1>(); guint owner_id = Gio::DBus::own_name(Gio::DBus::BUS_TYPE_SYSTEM, BUS_NAME, - [&timedate1](const Glib::RefPtr<Gio::DBus::Connection>& connection, const Glib::ustring& name) { - on_timedate_acquired(connection, name, timedate1.get()); - }, Gio::DBus::SlotNameAcquired(), &on_timedate_lost, + std::bind(&dlackware::timedate::timedate1::on_bus_acquired, timedate1.get(), + std::placeholders::_1, std::placeholders::_2), + Gio::DBus::SlotNameAcquired(), + std::bind(&dlackware::timedate::timedate1::on_name_lost, timedate1.get(), + std::placeholders::_1, std::placeholders::_2), Gio::DBus::BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT | Gio::DBus::BUS_NAME_OWNER_FLAGS_REPLACE); Glib::RefPtr<Glib::MainLoop> loop = Glib::MainLoop::create(false); @@ -198,7 +153,42 @@ int main(int argc, char **argv) namespace dlackware::timedate { - void timedate1::list_timezones(const std::string& prefix, std::vector<Glib::ustring>& accumulator) + timedate1::timedate1() + : interface_vtable{ &slack_method_call, &slack_get_property } + { + } + + void timedate1::on_name_lost(const Glib::RefPtr<Gio::DBus::Connection>& connection, const Glib::ustring& name) + { + g_warning("Failed to acquire the service %s.\n", name.data()); + exit(1); + } + + void timedate1::on_bus_acquired(const Glib::RefPtr<Gio::DBus::Connection>& connection, const Glib::ustring& name) + { + Glib::RefPtr<Gio::DBus::NodeInfo> introspection_data; + + try + { + introspection_data = Gio::DBus::NodeInfo::create_for_xml(INTROSPECTION_XML); + } + catch (Glib::Error& slack_err) + { + g_error("Failed to parse D-Bus introspection XML: %s\n", slack_err.what().data()); + } + try + { + guint registration_id = connection->register_object(BUS_PATH, + introspection_data->lookup_interface(), this->interface_vtable); + } + catch (Glib::Error& slack_err) + { + g_critical("Failed to register callbacks for the exported object with the D-Bus interface: %s\n", + slack_err.what().data()); + } + } + + void list_timezones(const std::string& prefix, std::vector<Glib::ustring>& accumulator) { auto zoneinfo_path = std::filesystem::path(zoneinfo_database) / prefix; @@ -218,7 +208,7 @@ namespace dlackware::timedate } } - Glib::Variant<std::vector<Glib::ustring>> timedate1::list_timezones() + Glib::Variant<std::vector<Glib::ustring>> list_timezones() { std::vector<Glib::ustring> result; @@ -226,7 +216,7 @@ namespace dlackware::timedate return Glib::Variant<std::vector<Glib::ustring>>::create(result); } - Glib::ustring timedate1::timezone() + Glib::ustring timezone() { std::unique_ptr<gchar[], decltype(&g_free)> zone_copied_from( g_file_read_link("/etc/localtime", NULL), &g_free); @@ -238,7 +228,7 @@ namespace dlackware::timedate return Glib::ustring{ zone_copied_from.get() + strlen(zoneinfo_database) + 1 }; } - bool timedate1::set_timezone(gchar *zone, std::error_code& ec) + bool set_timezone(gchar *zone, std::error_code& ec) { ec.clear(); auto zone_file = std::filesystem::path("/usr/share/zoneinfo") / zone; |
