From 5371ab0196b4559cbb982ab7f957864d5e366ebb Mon Sep 17 00:00:00 2001 From: Wu Xiaotian Date: Wed, 1 Jul 2020 09:53:13 +0800 Subject: datetime: migrate from dbus-glib to gdbus --- configure.ac | 1 + plugins/datetime/Makefile.am | 15 +- plugins/datetime/msd-datetime-mechanism-main.c | 106 +-- plugins/datetime/msd-datetime-mechanism.c | 966 +++++++++++++++---------- plugins/datetime/msd-datetime-mechanism.h | 39 +- plugins/datetime/msd-datetime-mechanism.xml | 8 - 6 files changed, 608 insertions(+), 527 deletions(-) diff --git a/configure.ac b/configure.ac index 1a82c90..3e6626a 100644 --- a/configure.ac +++ b/configure.ac @@ -88,6 +88,7 @@ AC_SUBST([MSD_PLUGIN_LDFLAGS]) PKG_CHECK_MODULES(DCONF, dconf >= 0.13.4) AC_PATH_PROG(GLIB_GENMARSHAL, glib-genmarshal) +AC_PATH_PROG(GDBUS_CODEGEN, gdbus-codegen) GLIB_GSETTINGS diff --git a/plugins/datetime/Makefile.am b/plugins/datetime/Makefile.am index a920100..88b1174 100644 --- a/plugins/datetime/Makefile.am +++ b/plugins/datetime/Makefile.am @@ -5,16 +5,17 @@ polkitdir = $(datadir)/polkit-1/actions dbus_services_in_files = org.mate.SettingsDaemon.DateTimeMechanism.service.in polkit_in_files = org.mate.settingsdaemon.datetimemechanism.policy.in -msd-datetime-mechanism-glue.h: $(srcdir)/msd-datetime-mechanism.xml - $(AM_V_GEN) dbus-binding-tool \ - --prefix=msd_datetime_mechanism --mode=glib-server \ - --output=msd-datetime-mechanism-glue.h \ - $(srcdir)/msd-datetime-mechanism.xml +$(BUILT_SOURCES) : $(srcdir)/msd-datetime-mechanism.xml + $(AM_V_GEN) $(GDBUS_CODEGEN) \ + --interface-prefix org.mate.SettingsDaemon. \ + --c-namespace MateSettings \ + --generate-c-code msd-datetime-generated $< if HAVE_POLKIT libexec_PROGRAMS = msd-datetime-mechanism endif +nodist_msd_datetime_mechanism_SOURCES = $(BUILT_SOURCES) msd_datetime_mechanism_SOURCES = \ msd-datetime-mechanism.c \ msd-datetime-mechanism.h \ @@ -24,7 +25,9 @@ msd_datetime_mechanism_SOURCES = \ if HAVE_POLKIT -BUILT_SOURCES = msd-datetime-mechanism-glue.h +BUILT_SOURCES = \ + msd-datetime-generated.h \ + msd-datetime-generated.c endif AM_CFLAGS = $(WARN_CFLAGS) $(SETTINGS_PLUGIN_CFLAGS) $(POLKIT_CFLAGS) diff --git a/plugins/datetime/msd-datetime-mechanism-main.c b/plugins/datetime/msd-datetime-mechanism-main.c index be02ce6..981d8ea 100644 --- a/plugins/datetime/msd-datetime-mechanism-main.c +++ b/plugins/datetime/msd-datetime-mechanism-main.c @@ -35,127 +35,25 @@ #include #include - -#include -#include - #include "msd-datetime-mechanism.h" -static DBusGProxy * -get_bus_proxy (DBusGConnection *connection) -{ - DBusGProxy *bus_proxy; - - bus_proxy = dbus_g_proxy_new_for_name (connection, - DBUS_SERVICE_DBUS, - DBUS_PATH_DBUS, - DBUS_INTERFACE_DBUS); - return bus_proxy; -} - -#define BUS_NAME "org.mate.SettingsDaemon.DateTimeMechanism" - -static gboolean -acquire_name_on_proxy (DBusGProxy *bus_proxy) -{ - GError *error; - guint result; - gboolean res; - gboolean ret; - - ret = FALSE; - - if (bus_proxy == NULL) { - goto out; - } - - error = NULL; - res = dbus_g_proxy_call (bus_proxy, - "RequestName", - &error, - G_TYPE_STRING, BUS_NAME, - G_TYPE_UINT, 0, - G_TYPE_INVALID, - G_TYPE_UINT, &result, - G_TYPE_INVALID); - if (! res) { - if (error != NULL) { - g_warning ("Failed to acquire %s: %s", BUS_NAME, error->message); - g_error_free (error); - } else { - g_warning ("Failed to acquire %s", BUS_NAME); - } - goto out; - } - - if (result != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) { - if (error != NULL) { - g_warning ("Failed to acquire %s: %s", BUS_NAME, error->message); - g_error_free (error); - } else { - g_warning ("Failed to acquire %s", BUS_NAME); - } - goto out; - } - - ret = TRUE; - - out: - return ret; -} - -static DBusGConnection * -get_system_bus (void) -{ - GError *error; - DBusGConnection *bus; - - error = NULL; - bus = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error); - if (bus == NULL) { - g_warning ("Couldn't connect to system bus: %s", error->message); - g_error_free (error); - } - return bus; -} - int main (int argc, char **argv) { GMainLoop *loop; MsdDatetimeMechanism *mechanism; - DBusGProxy *bus_proxy; - DBusGConnection *connection; int ret; ret = 1; - dbus_g_thread_init (); - - connection = get_system_bus (); - if (connection == NULL) { - goto out; - } - - bus_proxy = get_bus_proxy (connection); - if (bus_proxy == NULL) { - g_warning ("Could not construct bus_proxy object; bailing out"); - goto out; - } - - if (!acquire_name_on_proxy (bus_proxy) ) { - g_warning ("Could not acquire name; bailing out"); - goto out; - } + loop = g_main_loop_new (NULL, FALSE); - mechanism = msd_datetime_mechanism_new (); + mechanism = msd_datetime_mechanism_new (loop); if (mechanism == NULL) { goto out; } - loop = g_main_loop_new (NULL, FALSE); - g_main_loop_run (loop); g_object_unref (mechanism); diff --git a/plugins/datetime/msd-datetime-mechanism.c b/plugins/datetime/msd-datetime-mechanism.c index d048bb0..3d4bf6b 100644 --- a/plugins/datetime/msd-datetime-mechanism.c +++ b/plugins/datetime/msd-datetime-mechanism.c @@ -1,4 +1,5 @@ /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * vim: set ts=8 sts=8 sw=8 expandtab: * * Copyright (C) 2007 David Zeuthen * Copyright (C) 2012-2021 MATE Developers @@ -34,27 +35,87 @@ #include #include - -#include -#include - #include #include "system-timezone.h" - #include "msd-datetime-mechanism.h" -#include "msd-datetime-mechanism-glue.h" +#include "msd-datetime-generated.h" + +#define MSD_DATETIME_DBUS_NAME "org.mate.SettingsDaemon.DateTimeMechanism" +#define MSD_DATETIME_DBUS_PATH "/" + +enum { + PROP_0, + PROP_LOOP, + LAST_PROP +}; + +struct MsdDatetimeMechanismPrivate +{ + MateSettingsDateTimeMechanism *skeleton; + guint bus_name_id; + GMainLoop *loop; + PolkitAuthority *auth; +}; + +static GParamSpec *properties[LAST_PROP] = { NULL }; + +static void msd_datetime_mechanism_dispose (GObject *object); +static gboolean msd_datetime_mechanism_can_set_timezone_handler (MateSettingsDateTimeMechanism *object, + GDBusMethodInvocation *invocation, + gpointer user_data); +static gboolean msd_datetime_mechanism_get_timezone_handler (MateSettingsDateTimeMechanism *object, + GDBusMethodInvocation *invocation, + gpointer user_data); +static gboolean msd_datetime_mechanism_set_timezone_handler (MateSettingsDateTimeMechanism *object, + GDBusMethodInvocation *invocation, + const gchar *arg_zonefile, + gpointer user_data); + +static gboolean msd_datetime_mechanism_adjust_time_handler (MateSettingsDateTimeMechanism *object, + GDBusMethodInvocation *invocation, + gint64 arg_seconds_to_add, + gpointer user_data); +static gboolean msd_datetime_mechanism_can_set_time_handler (MateSettingsDateTimeMechanism *object, + GDBusMethodInvocation *invocation, + gpointer user_data); +static gboolean msd_datetime_mechanism_get_hardware_clock_using_utc_handler (MateSettingsDateTimeMechanism *object, + GDBusMethodInvocation *invocation, + gpointer user_data); +static gboolean msd_datetime_mechanism_set_hardware_clock_using_utc_handler (MateSettingsDateTimeMechanism *object, + GDBusMethodInvocation *invocation, + gboolean arg_is_using_utc, + gpointer user_data); +static gboolean msd_datetime_mechanism_set_time_handler (MateSettingsDateTimeMechanism *object, + GDBusMethodInvocation *invocation, + gint64 arg_seconds_since_epoch, + gpointer user_data); +static gboolean _set_time (MsdDatetimeMechanism *mechanism, + const struct timeval *tv, + GError **error); +static gboolean _check_polkit_for_action (MsdDatetimeMechanism *mechanism, + const char *action, + const char *sender, + GError **error); +static gboolean _rh_update_etc_sysconfig_clock (const char *key, + const char *value, + GError **error); + +G_DEFINE_TYPE_WITH_PRIVATE (MsdDatetimeMechanism, msd_datetime_mechanism, G_TYPE_OBJECT) static gboolean do_exit (gpointer user_data) { + GMainLoop *loop; + + loop = (GMainLoop*)user_data; g_debug ("Exiting due to inactivity"); - exit (1); + g_main_loop_quit (loop); return FALSE; } static void -reset_killtimer (void) +reset_killtimer (GMainLoop *loop) { static guint timer_id = 0; @@ -62,20 +123,9 @@ reset_killtimer (void) g_source_remove (timer_id); } g_debug ("Setting killtimer to 30 seconds..."); - timer_id = g_timeout_add_seconds (30, do_exit, NULL); + timer_id = g_timeout_add_seconds (30, do_exit, loop); } -struct MsdDatetimeMechanismPrivate -{ - DBusGConnection *system_bus_connection; - DBusGProxy *system_bus_proxy; - PolkitAuthority *auth; -}; - -static void msd_datetime_mechanism_finalize (GObject *object); - -G_DEFINE_TYPE_WITH_PRIVATE (MsdDatetimeMechanism, msd_datetime_mechanism, G_TYPE_OBJECT) - GQuark msd_datetime_mechanism_error_quark (void) { @@ -113,178 +163,235 @@ msd_datetime_mechanism_error_get_type (void) return etype; } -static GObject * -msd_datetime_mechanism_constructor (GType type, - guint n_construct_properties, - GObjectConstructParam *construct_properties) -{ - MsdDatetimeMechanism *mechanism; - - mechanism = MSD_DATETIME_MECHANISM (G_OBJECT_CLASS (msd_datetime_mechanism_parent_class)->constructor ( - type, - n_construct_properties, - construct_properties)); - - return G_OBJECT (mechanism); -} - -static void -msd_datetime_mechanism_class_init (MsdDatetimeMechanismClass *klass) +static gboolean +msd_datetime_mechanism_adjust_time_handler (MateSettingsDateTimeMechanism *object, + GDBusMethodInvocation *invocation, + gint64 seconds_to_add, + gpointer user_data) { - GObjectClass *object_class = G_OBJECT_CLASS (klass); + struct timeval tv; + gboolean ret = FALSE; + GError *error = NULL; + MsdDatetimeMechanism *mechanism; - object_class->constructor = msd_datetime_mechanism_constructor; - object_class->finalize = msd_datetime_mechanism_finalize; + mechanism = MSD_DATETIME_MECHANISM (user_data); - dbus_g_object_type_install_info (MSD_DATETIME_TYPE_MECHANISM, &dbus_glib_msd_datetime_mechanism_object_info); + reset_killtimer (mechanism->priv->loop); + g_debug ("AdjustTime(%ld) called", seconds_to_add); - dbus_g_error_domain_register (MSD_DATETIME_MECHANISM_ERROR, NULL, MSD_DATETIME_MECHANISM_TYPE_ERROR); + if (gettimeofday (&tv, NULL) != 0) { + error = g_error_new (MSD_DATETIME_MECHANISM_ERROR, + MSD_DATETIME_MECHANISM_ERROR_GENERAL, + "Error calling gettimeofday(): %s", strerror (errno)); + g_dbus_method_invocation_return_gerror (invocation, error); + g_error_free (error); + return FALSE; + } -} + if (!_check_polkit_for_action (mechanism, + "org.mate.settingsdaemon.datetimemechanism.settime", + g_dbus_method_invocation_get_sender (invocation), + &error)) { + g_dbus_method_invocation_return_gerror (invocation, error); + g_error_free (error); + return FALSE; + } -static void -msd_datetime_mechanism_init (MsdDatetimeMechanism *mechanism) -{ - mechanism->priv = msd_datetime_mechanism_get_instance_private (mechanism); + tv.tv_sec += (time_t) seconds_to_add; + ret = _set_time (mechanism, &tv, &error); + if (!ret) { + g_dbus_method_invocation_return_gerror (invocation, error); + g_error_free (error); + } else { + mate_settings_date_time_mechanism_complete_adjust_time (object, invocation); + } + return ret; } -static void -msd_datetime_mechanism_finalize (GObject *object) +static gint +check_can_do (MsdDatetimeMechanism *mechanism, + const char *action, + const char *sender, + GError **error) { - MsdDatetimeMechanism *mechanism; - - g_return_if_fail (object != NULL); - g_return_if_fail (MSD_DATETIME_IS_MECHANISM (object)); + gint value = -1; + PolkitSubject *subject; + PolkitAuthorizationResult *result; - mechanism = MSD_DATETIME_MECHANISM (object); + /* Check that caller is privileged */ + subject = polkit_system_bus_name_new (sender); + result = polkit_authority_check_authorization_sync (mechanism->priv->auth, + subject, + action, + NULL, + 0, + NULL, + error); + g_object_unref (subject); - g_return_if_fail (mechanism->priv != NULL); + if (*error != NULL) { + return value; + } - g_object_unref (mechanism->priv->system_bus_proxy); + if (polkit_authorization_result_get_is_authorized (result)) { + value = 2; + } + else if (polkit_authorization_result_get_is_challenge (result)) { + value = 1; + } + else { + value = 0; + } - G_OBJECT_CLASS (msd_datetime_mechanism_parent_class)->finalize (object); + g_object_unref (result); + return value; } + static gboolean -register_mechanism (MsdDatetimeMechanism *mechanism) +msd_datetime_mechanism_can_set_time_handler (MateSettingsDateTimeMechanism *object, + GDBusMethodInvocation *invocation, + gpointer user_data) { + gboolean ret = FALSE; + gint value; GError *error = NULL; + MsdDatetimeMechanism *mechanism; - mechanism->priv->auth = polkit_authority_get_sync (NULL, &error); - if (mechanism->priv->auth == NULL) { - if (error != NULL) { - g_critical ("error getting system bus: %s", error->message); - g_error_free (error); - } - goto error; - } + mechanism = MSD_DATETIME_MECHANISM (user_data); - mechanism->priv->system_bus_connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error); - if (mechanism->priv->system_bus_connection == NULL) { - if (error != NULL) { - g_critical ("error getting system bus: %s", error->message); - g_error_free (error); - } - goto error; + value = check_can_do (mechanism, + "org.mate.settingsdaemon.datetimemechanism.settime", + g_dbus_method_invocation_get_sender (invocation), + &error); + if (error != NULL) { + g_dbus_method_invocation_return_gerror (invocation, error); + g_error_free (error); + ret = FALSE; + } else { + mate_settings_date_time_mechanism_complete_can_set_time (object, invocation, value); + ret = TRUE; } - dbus_g_connection_register_g_object (mechanism->priv->system_bus_connection, "/", - G_OBJECT (mechanism)); - - mechanism->priv->system_bus_proxy = dbus_g_proxy_new_for_name (mechanism->priv->system_bus_connection, - DBUS_SERVICE_DBUS, - DBUS_PATH_DBUS, - DBUS_INTERFACE_DBUS); - - reset_killtimer (); - - return TRUE; - -error: - return FALSE; + return ret; } -MsdDatetimeMechanism * -msd_datetime_mechanism_new (void) +static gboolean +msd_datetime_mechanism_can_set_timezone_handler (MateSettingsDateTimeMechanism *object, + GDBusMethodInvocation *invocation, + gpointer user_data) { - GObject *object; - gboolean res; - - object = g_object_new (MSD_DATETIME_TYPE_MECHANISM, NULL); + gboolean ret = FALSE; + gint value; + GError *error = NULL; + MsdDatetimeMechanism *mechanism; - res = register_mechanism (MSD_DATETIME_MECHANISM (object)); - if (! res) { - g_object_unref (object); - return NULL; + mechanism = MSD_DATETIME_MECHANISM (user_data); + value = check_can_do (mechanism, + "org.mate.settingsdaemon.datetimemechanism.settimezone", + g_dbus_method_invocation_get_sender (invocation), + &error); + if (error != NULL) { + g_dbus_method_invocation_return_gerror (invocation, error); + g_error_free (error); + ret = FALSE; + } else { + mate_settings_date_time_mechanism_complete_can_set_timezone (object, invocation, value); + ret = TRUE; } - return MSD_DATETIME_MECHANISM (object); + return ret; } static gboolean -_check_polkit_for_action (MsdDatetimeMechanism *mechanism, DBusGMethodInvocation *context, const char *action) +msd_datetime_mechanism_get_hardware_clock_using_utc_handler (MateSettingsDateTimeMechanism *object, + GDBusMethodInvocation *invocation, + gpointer user_data G_GNUC_UNUSED) { - char *sender; - GError *error; - PolkitSubject *subject; - PolkitAuthorizationResult *result; - - error = NULL; + char **lines; + char *data; + gsize len; + gboolean is_utc; + GError *error = NULL; - /* Check that caller is privileged */ - sender = dbus_g_method_get_sender (context); - subject = polkit_system_bus_name_new (sender); - g_free (sender); + if (!g_file_get_contents ("/etc/adjtime", &data, &len, &error)) { + GError *error2; + error2 = g_error_new (MSD_DATETIME_MECHANISM_ERROR, + MSD_DATETIME_MECHANISM_ERROR_GENERAL, + "Error reading /etc/adjtime file: %s", error->message); + g_error_free (error); + g_dbus_method_invocation_return_gerror (invocation, error2); + g_error_free (error2); + return FALSE; + } - result = polkit_authority_check_authorization_sync (mechanism->priv->auth, - subject, - action, - NULL, - POLKIT_CHECK_AUTHORIZATION_FLAGS_ALLOW_USER_INTERACTION, - NULL, &error); - g_object_unref (subject); + lines = g_strsplit (data, "\n", 0); + g_free (data); - if (error) { - dbus_g_method_return_error (context, error); + if (g_strv_length (lines) < 3) { + error = g_error_new (MSD_DATETIME_MECHANISM_ERROR, + MSD_DATETIME_MECHANISM_ERROR_GENERAL, + "Cannot parse /etc/adjtime"); + g_dbus_method_invocation_return_gerror (invocation, error); g_error_free (error); - + g_strfreev (lines); return FALSE; } - if (!polkit_authorization_result_get_is_authorized (result)) { + if (strcmp (lines[2], "UTC") == 0) { + is_utc = TRUE; + } else if (strcmp (lines[2], "LOCAL") == 0) { + is_utc = FALSE; + } else { error = g_error_new (MSD_DATETIME_MECHANISM_ERROR, - MSD_DATETIME_MECHANISM_ERROR_NOT_PRIVILEGED, - "Not Authorized for action %s", action); - dbus_g_method_return_error (context, error); + MSD_DATETIME_MECHANISM_ERROR_GENERAL, + "Expected UTC or LOCAL at line 3 of /etc/adjtime; found '%s'", + lines[2]); + g_dbus_method_invocation_return_gerror (invocation, error); g_error_free (error); - g_object_unref (result); - + g_strfreev (lines); return FALSE; } + g_strfreev (lines); + mate_settings_date_time_mechanism_complete_get_hardware_clock_using_utc (object, invocation, is_utc); + return TRUE; +} - g_object_unref (result); +static gboolean +msd_datetime_mechanism_get_timezone_handler (MateSettingsDateTimeMechanism *object, + GDBusMethodInvocation *invocation, + gpointer user_data G_GNUC_UNUSED) +{ + gchar *tz; + MsdDatetimeMechanism *mechanism; + + mechanism = MSD_DATETIME_MECHANISM (user_data); + + reset_killtimer (mechanism->priv->loop); + + tz = system_timezone_find (); + + mate_settings_date_time_mechanism_complete_get_timezone (object, invocation, tz); return TRUE; } static gboolean -_set_time (MsdDatetimeMechanism *mechanism, - const struct timeval *tv, - DBusGMethodInvocation *context) +msd_datetime_mechanism_set_hardware_clock_using_utc_handler (MateSettingsDateTimeMechanism *object, + GDBusMethodInvocation *invocation, + gboolean using_utc, + gpointer user_data) { - GError *error; - - if (!_check_polkit_for_action (mechanism, context, "org.mate.settingsdaemon.datetimemechanism.settime")) - return FALSE; + GError *error = NULL; + MsdDatetimeMechanism *mechanism; - if (settimeofday (tv, NULL) != 0) { - error = g_error_new (MSD_DATETIME_MECHANISM_ERROR, - MSD_DATETIME_MECHANISM_ERROR_GENERAL, - "Error calling settimeofday({%ld,%ld}): %s", - (gint64) tv->tv_sec, (gint64) tv->tv_usec, - strerror (errno)); - dbus_g_method_return_error (context, error); + mechanism = MSD_DATETIME_MECHANISM (user_data); + if (!_check_polkit_for_action (mechanism, + "org.mate.settingsdaemon.datetimemechanism.configurehwclock", + g_dbus_method_invocation_get_sender (invocation), + &error)) { + g_dbus_method_invocation_return_gerror (invocation, error); g_error_free (error); return FALSE; } @@ -292,152 +399,101 @@ _set_time (MsdDatetimeMechanism *mechanism, if (g_file_test ("/sbin/hwclock", G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR | G_FILE_TEST_IS_EXECUTABLE)) { int exit_status; - if (!g_spawn_command_line_sync ("/sbin/hwclock --systohc", NULL, NULL, &exit_status, &error)) { + char *cmd; + cmd = g_strdup_printf ("/sbin/hwclock %s --systohc", using_utc ? "--utc" : "--localtime"); + if (!g_spawn_command_line_sync (cmd, NULL, NULL, &exit_status, &error)) { GError *error2; error2 = g_error_new (MSD_DATETIME_MECHANISM_ERROR, MSD_DATETIME_MECHANISM_ERROR_GENERAL, "Error spawning /sbin/hwclock: %s", error->message); g_error_free (error); - dbus_g_method_return_error (context, error2); + g_dbus_method_invocation_return_gerror (invocation, error2); g_error_free (error2); + g_free (cmd); return FALSE; } + g_free (cmd); if (WEXITSTATUS (exit_status) != 0) { error = g_error_new (MSD_DATETIME_MECHANISM_ERROR, MSD_DATETIME_MECHANISM_ERROR_GENERAL, "/sbin/hwclock returned %d", exit_status); - dbus_g_method_return_error (context, error); + g_dbus_method_invocation_return_gerror (invocation, error); g_error_free (error); return FALSE; } - } - - dbus_g_method_return (context); - return TRUE; -} -static gboolean -_rh_update_etc_sysconfig_clock (DBusGMethodInvocation *context, const char *key, const char *value) -{ - /* On Red Hat / Fedora, the /etc/sysconfig/clock file needs to be kept in sync */ - if (g_file_test ("/etc/sysconfig/clock", G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR)) { - char **lines; - int n; - gboolean replaced; - char *data; - gsize len; - GError *error; - - error = NULL; - - if (!g_file_get_contents ("/etc/sysconfig/clock", &data, &len, &error)) { - GError *error2; - error2 = g_error_new (MSD_DATETIME_MECHANISM_ERROR, - MSD_DATETIME_MECHANISM_ERROR_GENERAL, - "Error reading /etc/sysconfig/clock file: %s", error->message); + if (!_rh_update_etc_sysconfig_clock ("UTC=", using_utc ? "true" : "false", &error)) { + g_dbus_method_invocation_return_gerror (invocation, error); g_error_free (error); - dbus_g_method_return_error (context, error2); - g_error_free (error2); return FALSE; } - replaced = FALSE; - lines = g_strsplit (data, "\n", 0); - g_free (data); - for (n = 0; lines[n] != NULL; n++) { - if (g_str_has_prefix (lines[n], key)) { - g_free (lines[n]); - lines[n] = g_strdup_printf ("%s%s", key, value); - replaced = TRUE; - } - } - if (replaced) { - GString *str; - - str = g_string_new (NULL); - for (n = 0; lines[n] != NULL; n++) { - g_string_append (str, lines[n]); - if (lines[n + 1] != NULL) - g_string_append_c (str, '\n'); - } - data = g_string_free (str, FALSE); - len = strlen (data); - if (!g_file_set_contents ("/etc/sysconfig/clock", data, len, &error)) { - GError *error2; - error2 = g_error_new (MSD_DATETIME_MECHANISM_ERROR, - MSD_DATETIME_MECHANISM_ERROR_GENERAL, - "Error updating /etc/sysconfig/clock: %s", error->message); - g_error_free (error); - dbus_g_method_return_error (context, error2); - g_error_free (error2); - g_free (data); - return FALSE; - } - g_free (data); - } - g_strfreev (lines); } - + mate_settings_date_time_mechanism_complete_set_hardware_clock_using_utc (object, invocation); return TRUE; } -/* exported methods */ - -gboolean -msd_datetime_mechanism_set_time (MsdDatetimeMechanism *mechanism, - gint64 seconds_since_epoch, - DBusGMethodInvocation *context) +static gboolean +msd_datetime_mechanism_set_time_handler (MateSettingsDateTimeMechanism *object, + GDBusMethodInvocation *invocation, + gint64 arg_seconds_since_epoch, + gpointer user_data) { + gboolean ret = FALSE; struct timeval tv; + GError *error = NULL; + MsdDatetimeMechanism *mechanism; - reset_killtimer (); - g_debug ("SetTime(%ld) called", seconds_since_epoch); + mechanism = MSD_DATETIME_MECHANISM (user_data); - tv.tv_sec = (time_t) seconds_since_epoch; - tv.tv_usec = 0; - return _set_time (mechanism, &tv, context); -} + reset_killtimer (mechanism->priv->loop); + g_debug ("SetTime(%ld) called", arg_seconds_since_epoch); -gboolean -msd_datetime_mechanism_adjust_time (MsdDatetimeMechanism *mechanism, - gint64 seconds_to_add, - DBusGMethodInvocation *context) -{ - struct timeval tv; - - reset_killtimer (); - g_debug ("AdjustTime(%ld) called", seconds_to_add); - - if (gettimeofday (&tv, NULL) != 0) { - GError *error; - error = g_error_new (MSD_DATETIME_MECHANISM_ERROR, - MSD_DATETIME_MECHANISM_ERROR_GENERAL, - "Error calling gettimeofday(): %s", strerror (errno)); - dbus_g_method_return_error (context, error); + if (!_check_polkit_for_action (mechanism, + "org.mate.settingsdaemon.datetimemechanism.settime", + g_dbus_method_invocation_get_sender (invocation), + &error)) { + g_dbus_method_invocation_return_gerror (invocation, error); g_error_free (error); return FALSE; } - tv.tv_sec += (time_t) seconds_to_add; - return _set_time (mechanism, &tv, context); + tv.tv_sec = (time_t) arg_seconds_since_epoch; + tv.tv_usec = 0; + + ret = _set_time (mechanism, &tv, &error); + if (ret == FALSE) { + g_dbus_method_invocation_return_gerror (invocation, error); + g_error_free (error); + } else { + mate_settings_date_time_mechanism_complete_set_time (object, invocation); + } + return ret; } -gboolean -msd_datetime_mechanism_set_timezone (MsdDatetimeMechanism *mechanism, - const char *zone_file, - DBusGMethodInvocation *context) +static gboolean +msd_datetime_mechanism_set_timezone_handler (MateSettingsDateTimeMechanism *object, + GDBusMethodInvocation *invocation, + const gchar *zonefile, + gpointer user_data) { - GError *error; + GError *error = NULL; + MsdDatetimeMechanism *mechanism; - reset_killtimer (); - g_debug ("SetTimezone('%s') called", zone_file); + mechanism = MSD_DATETIME_MECHANISM (user_data); + reset_killtimer (mechanism->priv->loop); + g_debug ("SetTimezone('%s') called", zonefile); - if (!_check_polkit_for_action (mechanism, context, "org.mate.settingsdaemon.datetimemechanism.settimezone")) + if (!_check_polkit_for_action (mechanism, + "org.mate.settingsdaemon.datetimemechanism.settimezone", + g_dbus_method_invocation_get_sender (invocation), + &error)) { + g_dbus_method_invocation_return_gerror (invocation, error); + g_error_free (error); return FALSE; + } - error = NULL; - - if (!system_timezone_set_from_file (zone_file, &error)) { + if (!system_timezone_set_from_file (zonefile, &error)) { GError *error2; int code; @@ -449,192 +505,356 @@ msd_datetime_mechanism_set_timezone (MsdDatetimeMechanism *mechanism, error2 = g_error_new (MSD_DATETIME_MECHANISM_ERROR, code, "%s", error->message); + g_error_free (error); - dbus_g_method_return_error (context, error2); + g_dbus_method_invocation_return_gerror (invocation, error2); g_error_free (error2); - return FALSE; } - dbus_g_method_return (context); + mate_settings_date_time_mechanism_complete_set_timezone (object, invocation); return TRUE; } -gboolean -msd_datetime_mechanism_get_timezone (MsdDatetimeMechanism *mechism, - DBusGMethodInvocation *context) +static void +bus_acquired_handler_cb (GDBusConnection *connection, + const gchar *name G_GNUC_UNUSED, + gpointer user_data) +{ + MsdDatetimeMechanism *mechanism; + GError *error = NULL; + gboolean exported; + + mechanism = MSD_DATETIME_MECHANISM (user_data); + + g_signal_connect (mechanism->priv->skeleton, + "handle-can-set-timezone", + G_CALLBACK (msd_datetime_mechanism_can_set_timezone_handler), + mechanism); + g_signal_connect (mechanism->priv->skeleton, + "handle-set-timezone", + G_CALLBACK (msd_datetime_mechanism_set_timezone_handler), + mechanism); + g_signal_connect (mechanism->priv->skeleton, + "handle-get-timezone", + G_CALLBACK (msd_datetime_mechanism_get_timezone_handler), + mechanism); + + g_signal_connect (mechanism->priv->skeleton, + "handle-can-set-time", + G_CALLBACK (msd_datetime_mechanism_can_set_time_handler), + mechanism); + g_signal_connect (mechanism->priv->skeleton, + "handle-set-time", + G_CALLBACK (msd_datetime_mechanism_set_time_handler), + mechanism); + + g_signal_connect (mechanism->priv->skeleton, + "handle-adjust-time", + G_CALLBACK (msd_datetime_mechanism_adjust_time_handler), + mechanism); + + g_signal_connect (mechanism->priv->skeleton, + "handle-get-hardware-clock-using-utc", + G_CALLBACK (msd_datetime_mechanism_get_hardware_clock_using_utc_handler), + mechanism); + g_signal_connect (mechanism->priv->skeleton, + "handle-set-hardware-clock-using-utc", + G_CALLBACK (msd_datetime_mechanism_set_hardware_clock_using_utc_handler), + mechanism); + + exported = g_dbus_interface_skeleton_export ( + G_DBUS_INTERFACE_SKELETON (mechanism->priv->skeleton), + connection, + MSD_DATETIME_DBUS_PATH, + &error); + if (!exported) + { + g_warning ("Failed to export interface: %s", error->message); + g_error_free (error); + g_main_loop_quit (mechanism->priv->loop); + } +} + +static void +name_lost_handler_cb (GDBusConnection *connection G_GNUC_UNUSED, + const gchar *name G_GNUC_UNUSED, + gpointer user_data) { - reset_killtimer (); + MsdDatetimeMechanism *mechanism; - dbus_g_method_return (context, system_timezone_find ()); + mechanism = MSD_DATETIME_MECHANISM (user_data); + g_debug("bus name lost\n"); - return TRUE; + g_main_loop_quit (mechanism->priv->loop); } -gboolean -msd_datetime_mechanism_get_hardware_clock_using_utc (MsdDatetimeMechanism *mechanism, - DBusGMethodInvocation *context) +static void +msd_datetime_mechanism_constructed (GObject *object) { - char **lines; - char *data; - gsize len; - GError *error; - gboolean is_utc; + MsdDatetimeMechanism *mechanism; - error = NULL; + mechanism = MSD_DATETIME_MECHANISM (object); - if (!g_file_get_contents ("/etc/adjtime", &data, &len, &error)) { - GError *error2; - error2 = g_error_new (MSD_DATETIME_MECHANISM_ERROR, - MSD_DATETIME_MECHANISM_ERROR_GENERAL, - "Error reading /etc/adjtime file: %s", error->message); - g_error_free (error); - dbus_g_method_return_error (context, error2); - g_error_free (error2); - return FALSE; - } + G_OBJECT_CLASS (msd_datetime_mechanism_parent_class)->constructed (object); - lines = g_strsplit (data, "\n", 0); - g_free (data); + mechanism->priv->bus_name_id = g_bus_own_name (G_BUS_TYPE_SYSTEM, + MSD_DATETIME_DBUS_NAME, + G_BUS_NAME_OWNER_FLAGS_NONE, + bus_acquired_handler_cb, + NULL, + name_lost_handler_cb, mechanism, NULL); +} - if (g_strv_length (lines) < 3) { - error = g_error_new (MSD_DATETIME_MECHANISM_ERROR, - MSD_DATETIME_MECHANISM_ERROR_GENERAL, - "Cannot parse /etc/adjtime"); - dbus_g_method_return_error (context, error); - g_error_free (error); - g_strfreev (lines); - return FALSE; - } +static void +msd_datetime_mechanism_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + MsdDatetimeMechanism *mechanism; - if (strcmp (lines[2], "UTC") == 0) { - is_utc = TRUE; - } else if (strcmp (lines[2], "LOCAL") == 0) { - is_utc = FALSE; - } else { - error = g_error_new (MSD_DATETIME_MECHANISM_ERROR, - MSD_DATETIME_MECHANISM_ERROR_GENERAL, - "Expected UTC or LOCAL at line 3 of /etc/adjtime; found '%s'", lines[2]); - dbus_g_method_return_error (context, error); - g_error_free (error); - g_strfreev (lines); - return FALSE; + mechanism = MSD_DATETIME_MECHANISM (object); + + switch (prop_id) + { + case PROP_LOOP: + mechanism->priv->loop = g_value_get_pointer (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; } - g_strfreev (lines); - dbus_g_method_return (context, is_utc); - return TRUE; + } + +static void +msd_datetime_mechanism_class_init (MsdDatetimeMechanismClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->constructed = msd_datetime_mechanism_constructed; + object_class->set_property = msd_datetime_mechanism_set_property; + object_class->dispose = msd_datetime_mechanism_dispose; + + properties[PROP_LOOP] = + g_param_spec_pointer("loop", + "loop", + "loop", + G_PARAM_CONSTRUCT_ONLY | G_PARAM_WRITABLE | + G_PARAM_STATIC_STRINGS); + g_object_class_install_properties (object_class, LAST_PROP, properties); } -gboolean -msd_datetime_mechanism_set_hardware_clock_using_utc (MsdDatetimeMechanism *mechanism, - gboolean using_utc, - DBusGMethodInvocation *context) +static void +msd_datetime_mechanism_init (MsdDatetimeMechanism *mechanism) { - GError *error; + mechanism->priv = msd_datetime_mechanism_get_instance_private (mechanism); + mechanism->priv->skeleton = mate_settings_date_time_mechanism_skeleton_new (); +} - error = NULL; +static void +msd_datetime_mechanism_dispose (GObject *object) +{ + MsdDatetimeMechanism *mechanism; - if (!_check_polkit_for_action (mechanism, context, - "org.mate.settingsdaemon.datetimemechanism.configurehwclock")) - return FALSE; + g_return_if_fail (object != NULL); + g_return_if_fail (MSD_DATETIME_IS_MECHANISM (object)); - if (g_file_test ("/sbin/hwclock", - G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR | G_FILE_TEST_IS_EXECUTABLE)) { - int exit_status; - char *cmd; - cmd = g_strdup_printf ("/sbin/hwclock %s --systohc", using_utc ? "--utc" : "--localtime"); - if (!g_spawn_command_line_sync (cmd, NULL, NULL, &exit_status, &error)) { - GError *error2; - error2 = g_error_new (MSD_DATETIME_MECHANISM_ERROR, - MSD_DATETIME_MECHANISM_ERROR_GENERAL, - "Error spawning /sbin/hwclock: %s", error->message); - g_error_free (error); - dbus_g_method_return_error (context, error2); - g_error_free (error2); - g_free (cmd); - return FALSE; - } - g_free (cmd); - if (WEXITSTATUS (exit_status) != 0) { - error = g_error_new (MSD_DATETIME_MECHANISM_ERROR, - MSD_DATETIME_MECHANISM_ERROR_GENERAL, - "/sbin/hwclock returned %d", exit_status); - dbus_g_method_return_error (context, error); + mechanism = MSD_DATETIME_MECHANISM (object); + + g_return_if_fail (mechanism->priv != NULL); + + if (mechanism->priv->skeleton != NULL) + { + GDBusInterfaceSkeleton *skeleton; + + skeleton = G_DBUS_INTERFACE_SKELETON (mechanism->priv->skeleton); + g_dbus_interface_skeleton_unexport (skeleton); + g_clear_object (&mechanism->priv->skeleton); + } + + if (mechanism->priv->bus_name_id > 0) + { + g_bus_unown_name (mechanism->priv->bus_name_id); + mechanism->priv->bus_name_id = 0; + } + + + G_OBJECT_CLASS (msd_datetime_mechanism_parent_class)->dispose (object); +} + +static gboolean +register_mechanism (MsdDatetimeMechanism *mechanism) +{ + GError *error = NULL; + + mechanism->priv->auth = polkit_authority_get_sync (NULL, &error); + if (mechanism->priv->auth == NULL) { + if (error != NULL) { + g_critical ("error getting system bus: %s", error->message); g_error_free (error); - return FALSE; } + goto error; + } - if (!_rh_update_etc_sysconfig_clock (context, "UTC=", using_utc ? "true" : "false")) - return FALSE; + reset_killtimer (mechanism->priv->loop); - } - dbus_g_method_return (context); return TRUE; + +error: + return FALSE; } -static void -check_can_do (MsdDatetimeMechanism *mechanism, - const char *action, - DBusGMethodInvocation *context) +MsdDatetimeMechanism * +msd_datetime_mechanism_new (GMainLoop *loop) +{ + GObject *object; + gboolean res; + + object = g_object_new (MSD_DATETIME_TYPE_MECHANISM, "loop", loop, NULL); + + res = register_mechanism (MSD_DATETIME_MECHANISM (object)); + if (! res) { + g_object_unref (object); + return NULL; + } + + return MSD_DATETIME_MECHANISM (object); +} + +static gboolean +_check_polkit_for_action (MsdDatetimeMechanism *mechanism, + const char *action, + const char *sender, + GError **error) { - char *sender; PolkitSubject *subject; PolkitAuthorizationResult *result; - GError *error; /* Check that caller is privileged */ - sender = dbus_g_method_get_sender (context); subject = polkit_system_bus_name_new (sender); - g_free (sender); - - error = NULL; result = polkit_authority_check_authorization_sync (mechanism->priv->auth, subject, action, NULL, - 0, - NULL, - &error); + POLKIT_CHECK_AUTHORIZATION_FLAGS_ALLOW_USER_INTERACTION, + NULL, error); g_object_unref (subject); - if (error) { - dbus_g_method_return_error (context, error); - g_error_free (error); - return; + if (*error != NULL) { + return FALSE; } - if (polkit_authorization_result_get_is_authorized (result)) { - dbus_g_method_return (context, 2); - } - else if (polkit_authorization_result_get_is_challenge (result)) { - dbus_g_method_return (context, 1); - } - else { - dbus_g_method_return (context, 0); + if (!polkit_authorization_result_get_is_authorized (result)) { + *error = g_error_new (MSD_DATETIME_MECHANISM_ERROR, + MSD_DATETIME_MECHANISM_ERROR_NOT_PRIVILEGED, + "Not Authorized for action %s", action); + g_object_unref (result); + + return FALSE; } g_object_unref (result); + + return TRUE; } -gboolean -msd_datetime_mechanism_can_set_time (MsdDatetimeMechanism *mechanism, - DBusGMethodInvocation *context) +static gboolean +_set_time (MsdDatetimeMechanism *mechanism G_GNUC_UNUSED, + const struct timeval *tv, + GError **error) { - check_can_do (mechanism, - "org.mate.settingsdaemon.datetimemechanism.settime", - context); + if (settimeofday (tv, NULL) != 0) { + *error = g_error_new (MSD_DATETIME_MECHANISM_ERROR, + MSD_DATETIME_MECHANISM_ERROR_GENERAL, + "Error calling settimeofday({%ld,%ld}): %s", + (gint64) tv->tv_sec, (gint64) tv->tv_usec, + strerror (errno)); + return FALSE; + } + + if (g_file_test ("/sbin/hwclock", + G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR | G_FILE_TEST_IS_EXECUTABLE)) { + int exit_status; + if (!g_spawn_command_line_sync ("/sbin/hwclock --systohc", NULL, NULL, &exit_status, error)) { + GError *error2; + error2 = g_error_new (MSD_DATETIME_MECHANISM_ERROR, + MSD_DATETIME_MECHANISM_ERROR_GENERAL, + "Error spawning /sbin/hwclock: %s", (*error)->message); + g_error_free (*error); + g_propagate_error (error, error2); + return FALSE; + } + if (WEXITSTATUS (exit_status) != 0) { + *error = g_error_new (MSD_DATETIME_MECHANISM_ERROR, + MSD_DATETIME_MECHANISM_ERROR_GENERAL, + "/sbin/hwclock returned %d", exit_status); + return FALSE; + } + } return TRUE; } -gboolean -msd_datetime_mechanism_can_set_timezone (MsdDatetimeMechanism *mechanism, - DBusGMethodInvocation *context) +static gboolean +_rh_update_etc_sysconfig_clock (const char *key, + const char *value, + GError **error) { - check_can_do (mechanism, - "org.mate.settingsdaemon.datetimemechanism.settimezone", - context); + /* On Red Hat / Fedora, the /etc/sysconfig/clock file needs to be kept in sync */ + if (g_file_test ("/etc/sysconfig/clock", G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR)) { + char **lines; + int n; + gboolean replaced; + char *data; + gsize len; + + if (!g_file_get_contents ("/etc/sysconfig/clock", &data, &len, error)) { + GError *error2; + error2 = g_error_new (MSD_DATETIME_MECHANISM_ERROR, + MSD_DATETIME_MECHANISM_ERROR_GENERAL, + "Error reading /etc/sysconfig/clock file: %s", (*error)->message); + g_error_free (*error); + g_propagate_error (error, error2); + return FALSE; + } + replaced = FALSE; + lines = g_strsplit (data, "\n", 0); + g_free (data); + + for (n = 0; lines[n] != NULL; n++) { + if (g_str_has_prefix (lines[n], key)) { + g_free (lines[n]); + lines[n] = g_strdup_printf ("%s%s", key, value); + replaced = TRUE; + } + } + if (replaced) { + GString *str; + + str = g_string_new (NULL); + for (n = 0; lines[n] != NULL; n++) { + g_string_append (str, lines[n]); + if (lines[n + 1] != NULL) + g_string_append_c (str, '\n'); + } + data = g_string_free (str, FALSE); + len = strlen (data); + if (!g_file_set_contents ("/etc/sysconfig/clock", data, len, error)) { + GError *error2; + error2 = g_error_new (MSD_DATETIME_MECHANISM_ERROR, + MSD_DATETIME_MECHANISM_ERROR_GENERAL, + "Error updating /etc/sysconfig/clock: %s", (*error)->message); + g_error_free (*error); + g_propagate_error (error, error2); + g_free (data); + return FALSE; + } + g_free (data); + } + g_strfreev (lines); + } return TRUE; } diff --git a/plugins/datetime/msd-datetime-mechanism.h b/plugins/datetime/msd-datetime-mechanism.h index 3a0f502..e15ca95 100644 --- a/plugins/datetime/msd-datetime-mechanism.h +++ b/plugins/datetime/msd-datetime-mechanism.h @@ -23,11 +23,8 @@ #define MSD_DATETIME_MECHANISM_H #include -#include -#ifdef __cplusplus -extern "C" { -#endif +G_BEGIN_DECLS #define MSD_DATETIME_TYPE_MECHANISM (msd_datetime_mechanism_get_type ()) #define MSD_DATETIME_MECHANISM(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), MSD_DATETIME_TYPE_MECHANISM, MsdDatetimeMechanism)) @@ -64,38 +61,8 @@ GType msd_datetime_mechanism_error_get_type (void); GQuark msd_datetime_mechanism_error_quark (void); GType msd_datetime_mechanism_get_type (void); -MsdDatetimeMechanism *msd_datetime_mechanism_new (void); +MsdDatetimeMechanism *msd_datetime_mechanism_new (GMainLoop *loop); -/* exported methods */ -gboolean msd_datetime_mechanism_get_timezone (MsdDatetimeMechanism *mechanism, - DBusGMethodInvocation *context); -gboolean msd_datetime_mechanism_set_timezone (MsdDatetimeMechanism *mechanism, - const char *zone_file, - DBusGMethodInvocation *context); - -gboolean msd_datetime_mechanism_can_set_timezone (MsdDatetimeMechanism *mechanism, - DBusGMethodInvocation *context); - -gboolean msd_datetime_mechanism_set_time (MsdDatetimeMechanism *mechanism, - gint64 seconds_since_epoch, - DBusGMethodInvocation *context); - -gboolean msd_datetime_mechanism_can_set_time (MsdDatetimeMechanism *mechanism, - DBusGMethodInvocation *context); - -gboolean msd_datetime_mechanism_adjust_time (MsdDatetimeMechanism *mechanism, - gint64 seconds_to_add, - DBusGMethodInvocation *context); - -gboolean msd_datetime_mechanism_get_hardware_clock_using_utc (MsdDatetimeMechanism *mechanism, - DBusGMethodInvocation *context); - -gboolean msd_datetime_mechanism_set_hardware_clock_using_utc (MsdDatetimeMechanism *mechanism, - gboolean using_utc, - DBusGMethodInvocation *context); - -#ifdef __cplusplus -} -#endif +G_END_DECLS #endif /* MSD_DATETIME_MECHANISM_H */ diff --git a/plugins/datetime/msd-datetime-mechanism.xml b/plugins/datetime/msd-datetime-mechanism.xml index 1962235..a605459 100644 --- a/plugins/datetime/msd-datetime-mechanism.xml +++ b/plugins/datetime/msd-datetime-mechanism.xml @@ -2,17 +2,14 @@ - - - Whether the caller can set the timezone @@ -39,11 +36,9 @@ - - Whether the caller can set the time @@ -70,16 +65,13 @@ - - - -- cgit v1.2.1