From 813790b734225c856b494a70da11147a4d890e0f Mon Sep 17 00:00:00 2001 From: Michael Webster Date: Thu, 26 May 2022 10:47:44 -0400 Subject: [PATCH] datetime: Use Gio's dbus implementation. This removes dbus as a dependency. Fedora and Suse need to be tested. --- debian/control | 1 - meson.build | 9 - .../datetime/csd-datetime-mechanism-debian.c | 20 +- .../datetime/csd-datetime-mechanism-debian.h | 10 +- .../datetime/csd-datetime-mechanism-fedora.c | 36 +- .../datetime/csd-datetime-mechanism-fedora.h | 15 +- .../datetime/csd-datetime-mechanism-main.c | 135 +-- .../datetime/csd-datetime-mechanism-suse.c | 36 +- .../datetime/csd-datetime-mechanism-suse.h | 15 +- plugins/datetime/csd-datetime-mechanism.c | 844 ++++++++++-------- plugins/datetime/csd-datetime-mechanism.h | 66 +- plugins/datetime/meson.build | 23 +- 12 files changed, 578 insertions(+), 632 deletions(-) diff --git a/debian/control b/debian/control index 17a04570..04c9c6c2 100644 --- a/debian/control +++ b/debian/control @@ -11,7 +11,6 @@ Build-Depends: libcolord-dev (>= 0.1.27), libcups2-dev, libcvc-dev (>= 3.4~), - libdbus-glib-1-dev (>= 0.88), libfontconfig1-dev, libglib2.0-dev (>= 2.37.3), libgnomekbd-dev (>= 3.6.0), diff --git a/meson.build b/meson.build index dc527dc4..0ca22b79 100644 --- a/meson.build +++ b/meson.build @@ -70,11 +70,6 @@ xi = dependency('xi') xklavier = dependency('libxklavier', version: '>= 5.0') xtst = dependency('xtst') -# currently we only use dbus if we're also using polkit if this changes in the future we can -# simply remove the required field here -dbus = dependency('dbus-1', version: '>= 1.1.2', required: polkit.found()) -dbus_glib = dependency('dbus-glib-1', required: polkit.found()) - # currently only used for the wacom plugin librsvg = dependency('librsvg-2.0', version: '>= 2.36.2', required: wacom.found()) xorg_wacom = dependency('xorg-wacom', required: wacom.found()) @@ -103,10 +98,6 @@ endif cc = meson.get_compiler('c') math = cc.find_library('m', required: false) -# currently used by the datetime plugin, but dbus-glib is deprecated so we -# should port it to gdbus asap, and this should be removed at that point -dbus_binding_tool = find_program('dbus-binding-tool') - csd_conf = configuration_data() csd_conf.set_quoted('GTKBUILDERDIR', gtkbuilderdir) csd_conf.set_quoted('CINNAMON_SETTINGS_LOCALEDIR', localedir) diff --git a/plugins/datetime/csd-datetime-mechanism-debian.c b/plugins/datetime/csd-datetime-mechanism-debian.c index aa3f60c5..e5548812 100644 --- a/plugins/datetime/csd-datetime-mechanism-debian.c +++ b/plugins/datetime/csd-datetime-mechanism-debian.c @@ -66,23 +66,22 @@ _get_using_ntpd (gboolean *can_use, gboolean *is_using, GError ** error) } gboolean -_get_using_ntp_debian (DBusGMethodInvocation *context) +_get_using_ntp_debian (GDBusMethodInvocation *invocation, + gboolean *can_use_ntp, + gboolean *is_using_ntp) { - gboolean can_use_ntp = FALSE; - gboolean is_using_ntp = FALSE; GError *error = NULL; /* In Debian, ntpdate is used whenever the network comes up. So if either ntpdate or ntpd is installed and available, can_use is true. If either is active, is_using is true. */ - _get_using_ntpdate (&can_use_ntp, &is_using_ntp, &error); - _get_using_ntpd (&can_use_ntp, &is_using_ntp, &error); + _get_using_ntpdate (can_use_ntp, is_using_ntp, &error); + _get_using_ntpd (can_use_ntp, is_using_ntp, &error); if (error == NULL) { - dbus_g_method_return (context, can_use_ntp, is_using_ntp); return TRUE; } else { - dbus_g_method_return_error (context, error); + g_dbus_method_invocation_return_gerror (invocation, error); g_error_free (error); return FALSE; } @@ -177,8 +176,8 @@ _set_using_ntpd (gboolean using_ntp, GError **error) } gboolean -_set_using_ntp_debian (DBusGMethodInvocation *context, - gboolean using_ntp) +_set_using_ntp_debian (GDBusMethodInvocation *invocation, + gboolean using_ntp) { GError *error = NULL; @@ -189,10 +188,9 @@ _set_using_ntp_debian (DBusGMethodInvocation *context, _set_using_ntpd (using_ntp, &error); if (error == NULL) { - dbus_g_method_return (context); return TRUE; } else { - dbus_g_method_return_error (context, error); + g_dbus_method_invocation_return_gerror (invocation, error); g_error_free (error); return FALSE; } diff --git a/plugins/datetime/csd-datetime-mechanism-debian.h b/plugins/datetime/csd-datetime-mechanism-debian.h index a96b1e78..51260517 100644 --- a/plugins/datetime/csd-datetime-mechanism-debian.h +++ b/plugins/datetime/csd-datetime-mechanism-debian.h @@ -20,8 +20,10 @@ */ #include -#include +#include -gboolean _get_using_ntp_debian (DBusGMethodInvocation *context); -gboolean _set_using_ntp_debian (DBusGMethodInvocation *context, - gboolean using_ntp); +gboolean _get_using_ntp_debian (GDBusMethodInvocation *invocation, + gboolean *can_use_ntp, + gboolean *is_using_ntp); +gboolean _set_using_ntp_debian (GDBusMethodInvocation *invocation, + gboolean using_ntp); diff --git a/plugins/datetime/csd-datetime-mechanism-fedora.c b/plugins/datetime/csd-datetime-mechanism-fedora.c index a9961bf8..2a46fa3c 100644 --- a/plugins/datetime/csd-datetime-mechanism-fedora.c +++ b/plugins/datetime/csd-datetime-mechanism-fedora.c @@ -41,18 +41,18 @@ get_ntp_client () } gboolean -_get_using_ntp_fedora (DBusGMethodInvocation *context) +_get_using_ntp_fedora (GDBusMethodInvocation *invocation, + gboolean *can_use_ntp, + gboolean *is_using_ntp) { int exit_status; GError *error = NULL; - gboolean can_use_ntp; - gboolean is_using_ntp; const char *ntp_client; char *cmd; ntp_client = get_ntp_client (); if (ntp_client) { - can_use_ntp = TRUE; + *can_use_ntp = TRUE; cmd = g_strconcat ("/sbin/service ", ntp_client, " status", NULL); if (!g_spawn_command_line_sync (cmd, NULL, NULL, &exit_status, &error)) { @@ -61,28 +61,27 @@ _get_using_ntp_fedora (DBusGMethodInvocation *context) CSD_DATETIME_MECHANISM_ERROR_GENERAL, "Error spawning /sbin/service: %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 (exit_status == 0) - is_using_ntp = TRUE; + *is_using_ntp = TRUE; else - is_using_ntp = FALSE; + *is_using_ntp = FALSE; } else { - can_use_ntp = FALSE; - is_using_ntp = FALSE; + *can_use_ntp = FALSE; + *is_using_ntp = FALSE; } - dbus_g_method_return (context, can_use_ntp, is_using_ntp); return TRUE; } gboolean -_set_using_ntp_fedora (DBusGMethodInvocation *context, +_set_using_ntp_fedora (GDBusMethodInvocation *invocation, gboolean using_ntp) { GError *error; @@ -105,7 +104,7 @@ _set_using_ntp_fedora (DBusGMethodInvocation *context, CSD_DATETIME_MECHANISM_ERROR_GENERAL, "Error spawning '%s': %s", cmd, 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; @@ -122,7 +121,7 @@ _set_using_ntp_fedora (DBusGMethodInvocation *context, CSD_DATETIME_MECHANISM_ERROR_GENERAL, "Error spawning '%s': %s", cmd, 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; @@ -130,12 +129,13 @@ _set_using_ntp_fedora (DBusGMethodInvocation *context, g_free (cmd); - dbus_g_method_return (context); return TRUE; } gboolean -_update_etc_sysconfig_clock_fedora (DBusGMethodInvocation *context, const char *key, const char *value) +_update_etc_sysconfig_clock_fedora (GDBusMethodInvocation *invocation, + const char *key, + const char *value) { char **lines; int n; @@ -149,7 +149,7 @@ _update_etc_sysconfig_clock_fedora (DBusGMethodInvocation *context, const char * error = g_error_new (CSD_DATETIME_MECHANISM_ERROR, CSD_DATETIME_MECHANISM_ERROR_GENERAL, "Error reading /etc/sysconfig/clock file: %s", "No such file"); - dbus_g_method_return_error (context, error); + g_dbus_method_invocation_return_gerror (invocation, error); g_error_free (error); return FALSE; } @@ -162,7 +162,7 @@ _update_etc_sysconfig_clock_fedora (DBusGMethodInvocation *context, const char * CSD_DATETIME_MECHANISM_ERROR_GENERAL, "Error reading /etc/sysconfig/clock file: %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; } @@ -194,7 +194,7 @@ _update_etc_sysconfig_clock_fedora (DBusGMethodInvocation *context, const char * CSD_DATETIME_MECHANISM_ERROR_GENERAL, "Error updating /etc/sysconfig/clock: %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 (data); return FALSE; diff --git a/plugins/datetime/csd-datetime-mechanism-fedora.h b/plugins/datetime/csd-datetime-mechanism-fedora.h index e080471d..a72143b6 100644 --- a/plugins/datetime/csd-datetime-mechanism-fedora.h +++ b/plugins/datetime/csd-datetime-mechanism-fedora.h @@ -20,12 +20,13 @@ */ #include -#include +#include -gboolean _get_using_ntp_fedora (DBusGMethodInvocation *context); -gboolean _set_using_ntp_fedora (DBusGMethodInvocation *context, +gboolean _get_using_ntp_fedora (GDBusMethodInvocation *invocation, + gboolean *can_use_ntp, + gboolean *is_using_ntp); +gboolean _set_using_ntp_fedora (GDBusMethodInvocation *invocation, gboolean using_ntp); -gboolean _update_etc_sysconfig_clock_fedora - (DBusGMethodInvocation *context, - const char *key, - const char *value); +gboolean _update_etc_sysconfig_clock_fedora (GDBusMethodInvocation *invocation, + const char *key, + const char *value); diff --git a/plugins/datetime/csd-datetime-mechanism-main.c b/plugins/datetime/csd-datetime-mechanism-main.c index 4e8560af..72a4798d 100644 --- a/plugins/datetime/csd-datetime-mechanism-main.c +++ b/plugins/datetime/csd-datetime-mechanism-main.c @@ -34,131 +34,76 @@ #include #include - -#include -#include - +#include #include "csd-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.cinnamon.SettingsDaemon.DateTimeMechanism" -static gboolean -acquire_name_on_proxy (DBusGProxy *bus_proxy) -{ - GError *error; - guint result; - gboolean res; - gboolean ret; - - ret = FALSE; +GMainLoop *loop; +GDBusConnection *connection; +static CsdDatetimeMechanism *mechanism; +static int ret; - 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 void +on_name_acquired (GDBusConnection *connection, + const gchar *name, + gpointer user_data) +{ } -static DBusGConnection * -get_system_bus (void) +static void +on_name_lost (GDBusConnection *connection, + const gchar *name, + gpointer user_data) { - 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); + if (mechanism == NULL) { + g_critical ("Couldn't acquire bus name"); + g_main_loop_quit (loop); + return; } - return bus; + + g_message ("Name lost or replaced - quitting"); + g_main_loop_quit (loop); } int main (int argc, char **argv) { - GMainLoop *loop; - CsdDatetimeMechanism *mechanism; - DBusGProxy *bus_proxy; - DBusGConnection *connection; - int ret; + GError *error; + guint owner_id; ret = 1; + error = NULL; + connection = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error); - 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; + g_critical ("Couldn't connect to system bus: %s", error->message); + g_error_free (error); + goto out; } mechanism = csd_datetime_mechanism_new (); if (mechanism == NULL) { - goto out; + goto out; } - loop = g_main_loop_new (NULL, FALSE); + owner_id = g_bus_own_name_on_connection (connection, + BUS_NAME, + G_BUS_NAME_OWNER_FLAGS_REPLACE | G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT, + on_name_acquired, + on_name_lost, + NULL, NULL); + loop = g_main_loop_new (NULL, FALSE); g_main_loop_run (loop); g_object_unref (mechanism); + + g_bus_unown_name (owner_id); + + g_object_unref (connection); g_main_loop_unref (loop); ret = 0; diff --git a/plugins/datetime/csd-datetime-mechanism-suse.c b/plugins/datetime/csd-datetime-mechanism-suse.c index 2b9847cc..d25bfecd 100644 --- a/plugins/datetime/csd-datetime-mechanism-suse.c +++ b/plugins/datetime/csd-datetime-mechanism-suse.c @@ -30,15 +30,15 @@ #include "csd-datetime-mechanism.h" gboolean -_get_using_ntp_suse (DBusGMethodInvocation *context) +_get_using_ntp_suse (GDBusMethodInvocation *invocation, + gboolean *can_use_ntp, + gboolean *is_using_ntp) { int exit_status; GError *error = NULL; - gboolean can_use_ntp; - gboolean is_using_ntp; if (g_file_test ("/etc/ntp.conf", G_FILE_TEST_EXISTS)) { - can_use_ntp = TRUE; + *can_use_ntp = TRUE; if (!g_spawn_command_line_sync ("/sbin/service ntp status", NULL, NULL, &exit_status, &error)) { GError *error2; @@ -46,26 +46,25 @@ _get_using_ntp_suse (DBusGMethodInvocation *context) CSD_DATETIME_MECHANISM_ERROR_GENERAL, "Error spawning /sbin/service: %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; } if (exit_status == 0) - is_using_ntp = TRUE; + *is_using_ntp = TRUE; else - is_using_ntp = FALSE; + *is_using_ntp = FALSE; } else { - can_use_ntp = FALSE; - is_using_ntp = FALSE; + *can_use_ntp = FALSE; + *is_using_ntp = FALSE; } - dbus_g_method_return (context, can_use_ntp, is_using_ntp); return TRUE; } gboolean -_set_using_ntp_suse (DBusGMethodInvocation *context, +_set_using_ntp_suse (GDBusMethodInvocation *invocation, gboolean using_ntp) { GError *error; @@ -85,7 +84,7 @@ _set_using_ntp_suse (DBusGMethodInvocation *context, CSD_DATETIME_MECHANISM_ERROR_GENERAL, "Error spawning '%s': %s", cmd, 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; @@ -102,7 +101,7 @@ _set_using_ntp_suse (DBusGMethodInvocation *context, CSD_DATETIME_MECHANISM_ERROR_GENERAL, "Error spawning '%s': %s", cmd, 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; @@ -110,12 +109,13 @@ _set_using_ntp_suse (DBusGMethodInvocation *context, g_free (cmd); - dbus_g_method_return (context); return TRUE; } gboolean -_update_etc_sysconfig_clock_suse (DBusGMethodInvocation *context, const char *key, const char *value) +_update_etc_sysconfig_clock_suse (GDBusMethodInvocation *invocation, + const char *key, + const char *value) { char **lines; int n; @@ -129,7 +129,7 @@ _update_etc_sysconfig_clock_suse (DBusGMethodInvocation *context, const char *ke error = g_error_new (CSD_DATETIME_MECHANISM_ERROR, CSD_DATETIME_MECHANISM_ERROR_GENERAL, "Error reading /etc/sysconfig/clock file: %s", "No such file"); - dbus_g_method_return_error (context, error); + g_dbus_method_invocation_return_gerror (invocation, error); g_error_free (error); return FALSE; } @@ -142,7 +142,7 @@ _update_etc_sysconfig_clock_suse (DBusGMethodInvocation *context, const char *ke CSD_DATETIME_MECHANISM_ERROR_GENERAL, "Error reading /etc/sysconfig/clock file: %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; } @@ -174,7 +174,7 @@ _update_etc_sysconfig_clock_suse (DBusGMethodInvocation *context, const char *ke CSD_DATETIME_MECHANISM_ERROR_GENERAL, "Error updating /etc/sysconfig/clock: %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 (data); return FALSE; diff --git a/plugins/datetime/csd-datetime-mechanism-suse.h b/plugins/datetime/csd-datetime-mechanism-suse.h index af53c561..dbad260c 100644 --- a/plugins/datetime/csd-datetime-mechanism-suse.h +++ b/plugins/datetime/csd-datetime-mechanism-suse.h @@ -21,12 +21,13 @@ */ #include -#include +#include -gboolean _get_using_ntp_suse (DBusGMethodInvocation *context); -gboolean _set_using_ntp_suse (DBusGMethodInvocation *context, +gboolean _get_using_ntp_suse (GDBusMethodInvocation *invocation, + gboolean *can_use_ntp, + gboolean *is_using_ntp); +gboolean _set_using_ntp_suse (GDBusMethodInvocation *invocation, gboolean using_ntp); -gboolean _update_etc_sysconfig_clock_suse - (DBusGMethodInvocation *context, - const char *key, - const char *value); +gboolean _update_etc_sysconfig_clock_suse (GDBusMethodInvocation *invocation, + const char *key, + const char *value); diff --git a/plugins/datetime/csd-datetime-mechanism.c b/plugins/datetime/csd-datetime-mechanism.c index a0ccb99d..228ac517 100644 --- a/plugins/datetime/csd-datetime-mechanism.c +++ b/plugins/datetime/csd-datetime-mechanism.c @@ -33,27 +33,56 @@ #include #include - -#include -#include +#include "csd-exported-datetime.h" #include #include "system-timezone.h" #include "csd-datetime-mechanism.h" -#include "csd-datetime-mechanism-glue.h" /* NTP helper functions for various distributions */ #include "csd-datetime-mechanism-fedora.h" #include "csd-datetime-mechanism-debian.h" #include "csd-datetime-mechanism-suse.h" +struct _CsdDatetimeMechanism +{ + GObject parent; + CsdExportedDateTime *skeleton; + PolkitAuthority *auth; +}; + +G_DEFINE_TYPE (CsdDatetimeMechanism, csd_datetime_mechanism, G_TYPE_OBJECT) + +static gboolean _check_polkit_for_action (CsdDatetimeMechanism *mechanism, GDBusMethodInvocation *invocation); + +#define IFACE "org.cinnamon.SettingsDaemon.DateTimeMechanism" + +static const GDBusErrorEntry csd_datetime_mechanism_error_entries[] = { + { CSD_DATETIME_MECHANISM_ERROR_GENERAL, IFACE ".GeneralError" }, + { CSD_DATETIME_MECHANISM_ERROR_NOT_PRIVILEGED, IFACE ".NotPrivileged" }, + { CSD_DATETIME_MECHANISM_ERROR_INVALID_TIMEZONE_FILE, IFACE ".InvalidTimezoneFile" } +}; + +GQuark +csd_datetime_mechanism_error_quark (void) +{ + static volatile gsize quark_volatile = 0; + + g_dbus_error_register_error_domain ("csd_datetime_mechanism_error", + &quark_volatile, + csd_datetime_mechanism_error_entries, + G_N_ELEMENTS (csd_datetime_mechanism_error_entries)); + + return quark_volatile; +} + static gboolean do_exit (gpointer user_data) { g_debug ("Exiting due to inactivity"); - exit (1); + g_main_loop_quit (loop); return FALSE; } @@ -66,222 +95,176 @@ reset_killtimer (void) g_source_remove (timer_id); timer_id = 0; } + g_debug ("Setting killtimer to 30 seconds..."); timer_id = g_timeout_add_seconds (30, do_exit, NULL); } -struct CsdDatetimeMechanismPrivate +static gboolean +check_can_do (CsdDatetimeMechanism *mechanism, + const char *action, + GDBusMethodInvocation *invocation, + gint *canval) { - DBusGConnection *system_bus_connection; - DBusGProxy *system_bus_proxy; - PolkitAuthority *auth; -}; - -static void csd_datetime_mechanism_finalize (GObject *object); + const char *sender; + PolkitSubject *subject; + PolkitAuthorizationResult *result; + GError *error; -G_DEFINE_TYPE (CsdDatetimeMechanism, csd_datetime_mechanism, G_TYPE_OBJECT) + reset_killtimer (); -#define CSD_DATETIME_MECHANISM_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), CSD_DATETIME_TYPE_MECHANISM, CsdDatetimeMechanismPrivate)) + /* Check that caller is privileged */ + sender = g_dbus_method_invocation_get_sender (invocation); + subject = polkit_system_bus_name_new (sender); -GQuark -csd_datetime_mechanism_error_quark (void) -{ - static GQuark ret = 0; + error = NULL; + result = polkit_authority_check_authorization_sync (mechanism->auth, + subject, + action, + NULL, + 0, + NULL, + &error); + g_object_unref (subject); - if (ret == 0) { - ret = g_quark_from_static_string ("csd_datetime_mechanism_error"); + if (error) { + g_dbus_method_invocation_return_gerror (invocation, error); + g_error_free (error); + return FALSE; } - return ret; -} + if (polkit_authorization_result_get_is_authorized (result)) { + *canval = 2; + } + else if (polkit_authorization_result_get_is_challenge (result)) { + *canval = 1; + } + else { + *canval = 0; + } + g_object_unref (result); -#define ENUM_ENTRY(NAME, DESC) { NAME, "" #NAME "", DESC } + return TRUE; +} -GType -csd_datetime_mechanism_error_get_type (void) +gboolean +handle_can_set_timezone (CsdExportedDateTime *object, + GDBusMethodInvocation *invocation, + CsdDatetimeMechanism *mechanism) { - static GType etype = 0; - - if (etype == 0) - { - static const GEnumValue values[] = - { - ENUM_ENTRY (CSD_DATETIME_MECHANISM_ERROR_GENERAL, "GeneralError"), - ENUM_ENTRY (CSD_DATETIME_MECHANISM_ERROR_NOT_PRIVILEGED, "NotPrivileged"), - ENUM_ENTRY (CSD_DATETIME_MECHANISM_ERROR_INVALID_TIMEZONE_FILE, "InvalidTimezoneFile"), - { 0, 0, 0 } - }; - - g_assert (CSD_DATETIME_MECHANISM_NUM_ERRORS == G_N_ELEMENTS (values) - 1); - - etype = g_enum_register_static ("CsdDatetimeMechanismError", values); - } - - return etype; -} + gint canval = 0; + reset_killtimer (); + g_debug ("CanSetTimezone called"); -static GObject * -csd_datetime_mechanism_constructor (GType type, - guint n_construct_properties, - GObjectConstructParam *construct_properties) -{ - CsdDatetimeMechanism *mechanism; + if (!check_can_do (mechanism, + "org.cinnamon.settingsdaemon.datetimemechanism.configure", + invocation, + &canval)) { + return FALSE; + } - mechanism = CSD_DATETIME_MECHANISM (G_OBJECT_CLASS (csd_datetime_mechanism_parent_class)->constructor ( - type, - n_construct_properties, - construct_properties)); + csd_exported_date_time_complete_can_set_timezone (object, invocation, canval); - return G_OBJECT (mechanism); + return TRUE; } -static void -csd_datetime_mechanism_class_init (CsdDatetimeMechanismClass *klass) +static gboolean +check_tz_name (const char *tz, + GError **error) { - GObjectClass *object_class = G_OBJECT_CLASS (klass); + GFile *file; + char *tz_path, *actual_path; + gboolean retval; - object_class->constructor = csd_datetime_mechanism_constructor; - object_class->finalize = csd_datetime_mechanism_finalize; + retval = TRUE; + tz_path = g_build_filename (SYSTEM_ZONEINFODIR, tz, NULL); - g_type_class_add_private (klass, sizeof (CsdDatetimeMechanismPrivate)); + /* Get the actual resolved path */ + file = g_file_new_for_path (tz_path); + actual_path = g_file_get_path (file); + g_object_unref (file); - dbus_g_object_type_install_info (CSD_DATETIME_TYPE_MECHANISM, &dbus_glib_csd_datetime_mechanism_object_info); + /* The tz name passed had relative paths in it */ + if (g_strcmp0 (tz_path, actual_path) != 0) { + g_set_error (error, CSD_DATETIME_MECHANISM_ERROR, + CSD_DATETIME_MECHANISM_ERROR_INVALID_TIMEZONE_FILE, + "Timezone file '%s' was invalid.", + tz); + retval = FALSE; + } - dbus_g_error_domain_register (CSD_DATETIME_MECHANISM_ERROR, NULL, CSD_DATETIME_MECHANISM_TYPE_ERROR); + g_free (tz_path); + g_free (actual_path); + return retval; } -static void -csd_datetime_mechanism_init (CsdDatetimeMechanism *mechanism) +gboolean +handle_set_timezone (CsdExportedDateTime *object, + GDBusMethodInvocation *invocation, + const char *tz, + CsdDatetimeMechanism *mechanism) { - mechanism->priv = CSD_DATETIME_MECHANISM_GET_PRIVATE (mechanism); + GError *error; -} + reset_killtimer (); + g_debug ("SetTimezone ('%s') called", tz); -static void -csd_datetime_mechanism_finalize (GObject *object) -{ - CsdDatetimeMechanism *mechanism; + if (!_check_polkit_for_action (mechanism, invocation)) + return FALSE; - g_return_if_fail (object != NULL); - g_return_if_fail (CSD_DATETIME_IS_MECHANISM (object)); + error = NULL; - mechanism = CSD_DATETIME_MECHANISM (object); + if (!check_tz_name (tz, &error)) + return FALSE; - g_return_if_fail (mechanism->priv != NULL); + if (!system_timezone_set (tz, &error)) { + GError *error2; + int code; - g_object_unref (mechanism->priv->system_bus_proxy); + if (error->code == SYSTEM_TIMEZONE_ERROR_INVALID_TIMEZONE_FILE) + code = CSD_DATETIME_MECHANISM_ERROR_INVALID_TIMEZONE_FILE; + else + code = CSD_DATETIME_MECHANISM_ERROR_GENERAL; - G_OBJECT_CLASS (csd_datetime_mechanism_parent_class)->finalize (object); -} + error2 = g_error_new (CSD_DATETIME_MECHANISM_ERROR, + code, "%s", error->message); -static gboolean -register_mechanism (CsdDatetimeMechanism *mechanism) -{ - GError *error = NULL; + g_error_free (error); - 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; - } + g_dbus_method_invocation_return_gerror (invocation, error2); + g_error_free (error2); - 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; + return FALSE; } - 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 (); - + csd_exported_date_time_complete_set_timezone (object, invocation); return TRUE; - -error: - return FALSE; } -CsdDatetimeMechanism * -csd_datetime_mechanism_new (void) -{ - GObject *object; - gboolean res; - - object = g_object_new (CSD_DATETIME_TYPE_MECHANISM, NULL); - - res = register_mechanism (CSD_DATETIME_MECHANISM (object)); - if (! res) { - g_object_unref (object); - return NULL; - } - - return CSD_DATETIME_MECHANISM (object); -} - -static gboolean -_check_polkit_for_action (CsdDatetimeMechanism *mechanism, DBusGMethodInvocation *context) +gboolean +handle_get_timezone (CsdExportedDateTime *object, + GDBusMethodInvocation *invocation, + CsdDatetimeMechanism *mechanism) { - const char *action = "org.cinnamon.settingsdaemon.datetimemechanism.configure"; - const char *sender; - GError *error; - PolkitSubject *subject; - PolkitAuthorizationResult *result; - - error = NULL; - - /* Check that caller is privileged */ - sender = dbus_g_method_get_sender (context); - subject = polkit_system_bus_name_new (sender); - - 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); - - if (error) { - dbus_g_method_return_error (context, error); - g_error_free (error); - - return FALSE; - } + gchar *timezone; - if (!polkit_authorization_result_get_is_authorized (result)) { - error = g_error_new (CSD_DATETIME_MECHANISM_ERROR, - CSD_DATETIME_MECHANISM_ERROR_NOT_PRIVILEGED, - "Not Authorized for action %s", action); - dbus_g_method_return_error (context, error); - g_error_free (error); - g_object_unref (result); + reset_killtimer (); + g_debug ("GetTimezone called"); - return FALSE; - } + timezone = system_timezone_find (); - g_object_unref (result); + csd_exported_date_time_complete_get_timezone (object, invocation, timezone); + g_free (timezone); - return TRUE; + return TRUE; } static gboolean -_sync_hwclock (DBusGMethodInvocation *context) +_sync_hwclock (GDBusMethodInvocation *invocation) { GError *error; @@ -296,7 +279,7 @@ _sync_hwclock (DBusGMethodInvocation *context) CSD_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); return FALSE; } @@ -304,7 +287,7 @@ _sync_hwclock (DBusGMethodInvocation *context) error = g_error_new (CSD_DATETIME_MECHANISM_ERROR, CSD_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; } @@ -313,40 +296,12 @@ _sync_hwclock (DBusGMethodInvocation *context) return TRUE; } -static gboolean -_set_time (CsdDatetimeMechanism *mechanism, - const struct timeval *tv, - DBusGMethodInvocation *context) -{ - GError *error; - - if (!_check_polkit_for_action (mechanism, context)) - return FALSE; - - if (settimeofday (tv, NULL) != 0) { - error = g_error_new (CSD_DATETIME_MECHANISM_ERROR, - CSD_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); - g_error_free (error); - return FALSE; - } - - if (!_sync_hwclock (context)) - return FALSE; - - dbus_g_method_return (context); - return TRUE; -} - static gboolean _set_date (CsdDatetimeMechanism *mechanism, guint day, guint month, guint year, - DBusGMethodInvocation *context) + GDBusMethodInvocation *invocation) { GDateTime *time; char *date_str, *time_str; @@ -354,7 +309,7 @@ _set_date (CsdDatetimeMechanism *mechanism, int exit_status; GError *error; - if (!_check_polkit_for_action (mechanism, context)) + if (!_check_polkit_for_action (mechanism, invocation)) return FALSE; date_str = g_strdup_printf ("%02d/%02d/%d", month, day, year); @@ -374,7 +329,7 @@ _set_date (CsdDatetimeMechanism *mechanism, CSD_DATETIME_MECHANISM_ERROR_GENERAL, "Error spawning /bin/date: %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 (date_cmd); return FALSE; @@ -384,163 +339,142 @@ _set_date (CsdDatetimeMechanism *mechanism, error = g_error_new (CSD_DATETIME_MECHANISM_ERROR, CSD_DATETIME_MECHANISM_ERROR_GENERAL, "/bin/date 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; } - if (!_sync_hwclock (context)) + if (!_sync_hwclock (invocation)) return FALSE; return TRUE; } -/* exported methods */ - gboolean -csd_datetime_mechanism_set_time (CsdDatetimeMechanism *mechanism, - gint64 seconds_since_epoch, - DBusGMethodInvocation *context) +handle_set_date (CsdExportedDateTime *object, + GDBusMethodInvocation *invocation, + guint day, + guint month, + guint year, + CsdDatetimeMechanism *mechanism) { - struct timeval tv; - reset_killtimer (); - g_debug ("SetTime(%" G_GINT64_FORMAT ") called", seconds_since_epoch); + g_debug ("SetDate (%d, %d, %d) called", day, month, year); - tv.tv_sec = (time_t) seconds_since_epoch; - tv.tv_usec = 0; - return _set_time (mechanism, &tv, context); -} - -gboolean -csd_datetime_mechanism_set_date (CsdDatetimeMechanism *mechanism, - guint day, - guint month, - guint year, - DBusGMethodInvocation *context) -{ - reset_killtimer (); - g_debug ("SetDate(%d, %d, %d) called", day, month, year); + if (!_set_date (mechanism, day, month, year, invocation)) { + return FALSE; + } - return _set_date (mechanism, day, month, year, context); + csd_exported_date_time_complete_set_date (object, invocation); + return TRUE; } -gboolean -csd_datetime_mechanism_adjust_time (CsdDatetimeMechanism *mechanism, - gint64 seconds_to_add, - DBusGMethodInvocation *context) +static gboolean +_set_time (CsdDatetimeMechanism *mechanism, + const struct timeval *tv, + GDBusMethodInvocation *invocation) { - struct timeval tv; + GError *error; - reset_killtimer (); - g_debug ("AdjustTime(%" G_GINT64_FORMAT " ) called", seconds_to_add); + if (!_check_polkit_for_action (mechanism, invocation)) + return FALSE; - if (gettimeofday (&tv, NULL) != 0) { - GError *error; + if (settimeofday (tv, NULL) != 0) { error = g_error_new (CSD_DATETIME_MECHANISM_ERROR, CSD_DATETIME_MECHANISM_ERROR_GENERAL, - "Error calling gettimeofday(): %s", strerror (errno)); - dbus_g_method_return_error (context, error); + "Error calling settimeofday({%ld,%ld}): %s", + (gint64) tv->tv_sec, (gint64) tv->tv_usec, + strerror (errno)); + 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); -} - -static gboolean -csd_datetime_check_tz_name (const char *tz, - GError **error) -{ - GFile *file; - char *tz_path, *actual_path; - gboolean retval; - - retval = TRUE; - tz_path = g_build_filename (SYSTEM_ZONEINFODIR, tz, NULL); - - /* Get the actual resolved path */ - file = g_file_new_for_path (tz_path); - actual_path = g_file_get_path (file); - g_object_unref (file); - - /* The tz name passed had relative paths in it */ - if (g_strcmp0 (tz_path, actual_path) != 0) { - g_set_error (error, CSD_DATETIME_MECHANISM_ERROR, - CSD_DATETIME_MECHANISM_ERROR_INVALID_TIMEZONE_FILE, - "Timezone file '%s' was invalid.", - tz); - retval = FALSE; - } - - g_free (tz_path); - g_free (actual_path); + if (!_sync_hwclock (invocation)) + return FALSE; - return retval; + return TRUE; } gboolean -csd_datetime_mechanism_set_timezone (CsdDatetimeMechanism *mechanism, - const char *tz, - DBusGMethodInvocation *context) +handle_set_time (CsdExportedDateTime *object, + GDBusMethodInvocation *invocation, + gint64 seconds_since_epoch, + CsdDatetimeMechanism *mechanism) { - GError *error; + struct timeval tv; reset_killtimer (); - g_debug ("SetTimezone('%s') called", tz); + g_debug ("SetTime (%" G_GINT64_FORMAT ") called", seconds_since_epoch); - if (!_check_polkit_for_action (mechanism, context)) - return FALSE; - - error = NULL; + tv.tv_sec = (time_t) seconds_since_epoch; + tv.tv_usec = 0; - if (!csd_datetime_check_tz_name (tz, &error)) + if (!_set_time (mechanism, &tv, invocation)) { return FALSE; + } - if (!system_timezone_set (tz, &error)) { - GError *error2; - int code; - - if (error->code == SYSTEM_TIMEZONE_ERROR_INVALID_TIMEZONE_FILE) - code = CSD_DATETIME_MECHANISM_ERROR_INVALID_TIMEZONE_FILE; - else - code = CSD_DATETIME_MECHANISM_ERROR_GENERAL; + csd_exported_date_time_complete_set_time (object, invocation); - error2 = g_error_new (CSD_DATETIME_MECHANISM_ERROR, - code, "%s", error->message); + return TRUE; +} - g_error_free (error); +gboolean +handle_can_set_time (CsdExportedDateTime *object, + GDBusMethodInvocation *invocation, + CsdDatetimeMechanism *mechanism) +{ + gint canval = 0; - dbus_g_method_return_error (context, error2); - g_error_free (error2); + g_debug ("CanSetTime called"); + if (!check_can_do (mechanism, + "org.cinnamon.settingsdaemon.datetimemechanism.configure", + invocation, + &canval)) { return FALSE; } - dbus_g_method_return (context); + csd_exported_date_time_complete_can_set_time (object, invocation, canval); return TRUE; } - gboolean -csd_datetime_mechanism_get_timezone (CsdDatetimeMechanism *mechism, - DBusGMethodInvocation *context) +handle_adjust_time (CsdExportedDateTime *object, + GDBusMethodInvocation *invocation, + gint64 seconds_to_add, + CsdDatetimeMechanism *mechanism) { - gchar *timezone; + struct timeval tv; - reset_killtimer (); + reset_killtimer (); + g_debug ("AdjustTime (%" G_GINT64_FORMAT " ) called", seconds_to_add); - timezone = system_timezone_find (); + if (gettimeofday (&tv, NULL) != 0) { + GError *error; + error = g_error_new (CSD_DATETIME_MECHANISM_ERROR, + CSD_DATETIME_MECHANISM_ERROR_GENERAL, + "Error calling gettimeofday(): %s", strerror (errno)); + g_dbus_method_invocation_return_gerror (invocation, error); + g_error_free (error); + return FALSE; + } - dbus_g_method_return (context, timezone); + tv.tv_sec += (time_t) seconds_to_add; - return TRUE; + if (!_set_time (mechanism, &tv, invocation)) { + return FALSE; + } + + csd_exported_date_time_complete_adjust_time (object, invocation); + + return TRUE; } gboolean -csd_datetime_mechanism_get_hardware_clock_using_utc (CsdDatetimeMechanism *mechanism, - DBusGMethodInvocation *context) +handle_get_hardware_clock_using_utc (CsdExportedDateTime *object, + GDBusMethodInvocation *invocation, + CsdDatetimeMechanism *mechanism) { char **lines; char *data; @@ -548,6 +482,9 @@ csd_datetime_mechanism_get_hardware_clock_using_utc (CsdDatetimeMechanism *mech GError *error; gboolean is_utc; + reset_killtimer (); + g_debug ("GetHardwareClockUsingUtc called"); + error = NULL; if (!g_file_get_contents ("/etc/adjtime", &data, &len, &error)) { @@ -556,7 +493,7 @@ csd_datetime_mechanism_get_hardware_clock_using_utc (CsdDatetimeMechanism *mech CSD_DATETIME_MECHANISM_ERROR_GENERAL, "Error reading /etc/adjtime file: %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; } @@ -568,7 +505,7 @@ csd_datetime_mechanism_get_hardware_clock_using_utc (CsdDatetimeMechanism *mech error = g_error_new (CSD_DATETIME_MECHANISM_ERROR, CSD_DATETIME_MECHANISM_ERROR_GENERAL, "Cannot parse /etc/adjtime"); - dbus_g_method_return_error (context, error); + g_dbus_method_invocation_return_gerror (invocation, error); g_error_free (error); g_strfreev (lines); return FALSE; @@ -582,26 +519,33 @@ csd_datetime_mechanism_get_hardware_clock_using_utc (CsdDatetimeMechanism *mech error = g_error_new (CSD_DATETIME_MECHANISM_ERROR, CSD_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_dbus_method_invocation_return_gerror (invocation, error); g_error_free (error); g_strfreev (lines); return FALSE; } g_strfreev (lines); - dbus_g_method_return (context, is_utc); + + csd_exported_date_time_complete_get_hardware_clock_using_utc (object, invocation, is_utc); + return TRUE; } gboolean -csd_datetime_mechanism_set_hardware_clock_using_utc (CsdDatetimeMechanism *mechanism, - gboolean using_utc, - DBusGMethodInvocation *context) +handle_set_hardware_clock_using_utc (CsdExportedDateTime *object, + GDBusMethodInvocation *invocation, + gboolean using_utc, + CsdDatetimeMechanism *mechanism) { GError *error; error = NULL; - if (!_check_polkit_for_action (mechanism, context)) + reset_killtimer (); + + g_debug ("SetHardwareClockUsingUtc (%d) called", using_utc); + + if (!_check_polkit_for_action (mechanism, invocation)) return FALSE; if (g_file_test ("/sbin/hwclock", @@ -615,7 +559,7 @@ csd_datetime_mechanism_set_hardware_clock_using_utc (CsdDatetimeMechanism *mech CSD_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; @@ -625,152 +569,282 @@ csd_datetime_mechanism_set_hardware_clock_using_utc (CsdDatetimeMechanism *mech error = g_error_new (CSD_DATETIME_MECHANISM_ERROR, CSD_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; } if (g_file_test ("/etc/redhat-release", G_FILE_TEST_EXISTS)) { /* Fedora */ - if (!_update_etc_sysconfig_clock_fedora (context, "UTC=", using_utc ? "true" : "false")) + if (!_update_etc_sysconfig_clock_fedora (invocation, "UTC=", using_utc ? "true" : "false")) return FALSE; - } else if (g_file_test ("/etc/SuSE-release", G_FILE_TEST_EXISTS)) { /* SUSE variant */ - if (!_update_etc_sysconfig_clock_suse (context, "HWCLOCK=", using_utc ? "-u" : "--localtime")) + } else if (g_file_test ("/etc/SuSE-release", G_FILE_TEST_EXISTS)) { /* SUSE variant */ + if (!_update_etc_sysconfig_clock_suse (invocation, "HWCLOCK=", using_utc ? "-u" : "--localtime")) return FALSE; - } + } } - dbus_g_method_return (context); + + csd_exported_date_time_complete_set_hardware_clock_using_utc (object, invocation); + return TRUE; } gboolean -csd_datetime_mechanism_get_using_ntp (CsdDatetimeMechanism *mechanism, - DBusGMethodInvocation *context) +handle_get_using_ntp (CsdExportedDateTime *object, + GDBusMethodInvocation *invocation, + CsdDatetimeMechanism *mechanism) { GError *error = NULL; gboolean ret; + gboolean is_using_ntp = FALSE; + gboolean can_use_ntp = FALSE; + + reset_killtimer (); + + g_debug ("GetUsingNtp called"); if (g_file_test ("/etc/redhat-release", G_FILE_TEST_EXISTS)) /* Fedora */ - ret = _get_using_ntp_fedora (context); + ret = _get_using_ntp_fedora (invocation, &can_use_ntp, &is_using_ntp); else if (g_file_test ("/usr/sbin/update-rc.d", G_FILE_TEST_EXISTS)) /* Debian */ - ret = _get_using_ntp_debian (context); - else if (g_file_test ("/etc/SuSE-release", G_FILE_TEST_EXISTS)) /* SUSE variant */ - ret = _get_using_ntp_suse (context); + ret = _get_using_ntp_debian (invocation, &can_use_ntp, &is_using_ntp); + else if (g_file_test ("/etc/SuSE-release", G_FILE_TEST_EXISTS)) /* SUSE variant */ + ret = _get_using_ntp_suse (invocation, &can_use_ntp, &is_using_ntp); else { error = g_error_new (CSD_DATETIME_MECHANISM_ERROR, CSD_DATETIME_MECHANISM_ERROR_GENERAL, "Error enabling NTP: OS variant not supported"); - dbus_g_method_return_error (context, error); + g_dbus_method_invocation_return_gerror (invocation, error); g_error_free (error); return FALSE; } + if (ret) { + csd_exported_date_time_complete_get_using_ntp (object, invocation, can_use_ntp, is_using_ntp); + } + return ret; } gboolean -csd_datetime_mechanism_set_using_ntp (CsdDatetimeMechanism *mechanism, - gboolean using_ntp, - DBusGMethodInvocation *context) +handle_set_using_ntp (CsdExportedDateTime *object, + GDBusMethodInvocation *invocation, + gboolean using_ntp, + CsdDatetimeMechanism *mechanism) { GError *error; gboolean ret; + reset_killtimer (); + g_debug ("SetUsingNtp (%d) called", using_ntp); + error = NULL; - if (!_check_polkit_for_action (mechanism, context)) + if (!_check_polkit_for_action (mechanism, invocation)) return FALSE; if (g_file_test ("/etc/redhat-release", G_FILE_TEST_EXISTS)) /* Fedora */ - ret = _set_using_ntp_fedora (context, using_ntp); + ret = _set_using_ntp_fedora (invocation, using_ntp); else if (g_file_test ("/usr/sbin/update-rc.d", G_FILE_TEST_EXISTS)) /* Debian */ - ret = _set_using_ntp_debian (context, using_ntp); - else if (g_file_test ("/etc/SuSE-release", G_FILE_TEST_EXISTS)) /* SUSE variant */ - ret = _set_using_ntp_suse (context, using_ntp); + ret = _set_using_ntp_debian (invocation, using_ntp); + else if (g_file_test ("/etc/SuSE-release", G_FILE_TEST_EXISTS)) /* SUSE variant */ + ret = _set_using_ntp_suse (invocation, using_ntp); else { error = g_error_new (CSD_DATETIME_MECHANISM_ERROR, CSD_DATETIME_MECHANISM_ERROR_GENERAL, "Error enabling NTP: OS variant not supported"); - dbus_g_method_return_error (context, error); + g_dbus_method_invocation_return_gerror (invocation, error); g_error_free (error); return FALSE; } + if (ret) { + csd_exported_date_time_complete_set_using_ntp (object, invocation); + } + return ret; } + + +gboolean +handle_can_set_using_ntp (CsdExportedDateTime *object, + GDBusMethodInvocation *invocation, + CsdDatetimeMechanism *mechanism) +{ + gint canval = 0; + + g_debug ("CanSetUsingNtp called"); + + if (!check_can_do (mechanism, + "org.cinnamon.settingsdaemon.datetimemechanism.configure", + invocation, + &canval)) { + return FALSE; + } + + csd_exported_date_time_complete_can_set_using_ntp (object, invocation, canval); + + return TRUE; +} + static void -check_can_do (CsdDatetimeMechanism *mechanism, - const char *action, - DBusGMethodInvocation *context) +csd_datetime_mechanism_dispose (GObject *object) { - const char *sender; - PolkitSubject *subject; - PolkitAuthorizationResult *result; - GError *error; + CsdDatetimeMechanism *mechanism; - /* Check that caller is privileged */ - sender = dbus_g_method_get_sender (context); - subject = polkit_system_bus_name_new (sender); + g_return_if_fail (object != NULL); + g_return_if_fail (CSD_DATETIME_IS_MECHANISM (object)); - error = NULL; - result = polkit_authority_check_authorization_sync (mechanism->priv->auth, - subject, - action, - NULL, - 0, - NULL, - &error); - g_object_unref (subject); + mechanism = CSD_DATETIME_MECHANISM (object); - if (error) { - dbus_g_method_return_error (context, error); - g_error_free (error); - return; + if (mechanism->skeleton != NULL) { + g_dbus_interface_skeleton_unexport (G_DBUS_INTERFACE_SKELETON (mechanism->skeleton)); + g_clear_object (&mechanism->skeleton); } - 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); - } + g_clear_object (&mechanism->auth); - g_object_unref (result); + G_OBJECT_CLASS (csd_datetime_mechanism_parent_class)->dispose (object); } +static void +csd_datetime_mechanism_class_init (CsdDatetimeMechanismClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); -gboolean -csd_datetime_mechanism_can_set_time (CsdDatetimeMechanism *mechanism, - DBusGMethodInvocation *context) + object_class->dispose = csd_datetime_mechanism_dispose; +} + +static void +csd_datetime_mechanism_init (CsdDatetimeMechanism *mechanism) { - check_can_do (mechanism, - "org.cinnamon.settingsdaemon.datetimemechanism.configure", - context); +} + +typedef struct +{ + const gchar *signal_name; + gpointer callback; +} SkeletonSignal; + +static SkeletonSignal skeleton_signals[] = { + // signal name callback + { "handle-set-timezone", handle_set_timezone }, + { "handle-get-timezone", handle_get_timezone }, + { "handle-can-set-timezone", handle_can_set_timezone }, + { "handle-set-date", handle_set_date }, + { "handle-set-time", handle_set_time }, + { "handle-can-set-time", handle_can_set_time }, + { "handle-adjust-time", handle_adjust_time }, + { "handle-get-hardware-clock-using-utc", handle_get_hardware_clock_using_utc }, + { "handle-set-hardware-clock-using-utc", handle_set_hardware_clock_using_utc }, + { "handle-get-using-ntp", handle_get_using_ntp }, + { "handle-set-using-ntp", handle_set_using_ntp }, + { "handle-can-set-using-ntp", handle_can_set_using_ntp } +}; + +static gboolean +register_mechanism (CsdDatetimeMechanism *mechanism) +{ + GError *error = NULL; + gint i; + + mechanism->auth = polkit_authority_get_sync (NULL, &error); + if (mechanism->auth == NULL) { + if (error != NULL) { + g_critical ("error getting system bus: %s", error->message); + g_error_free (error); + } + goto error; + } + + mechanism->skeleton = csd_exported_date_time_skeleton_new (); + + g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (mechanism->skeleton), + connection, + "/org/cinnamon/SettingsDaemon/DateTimeMechanism", + &error); + + if (error != NULL) { + g_critical ("error exporting datetime intereface: %s", error->message); + g_error_free (error); + goto error; + } + + for (i = 0; i < G_N_ELEMENTS (skeleton_signals); i++) { + SkeletonSignal sig = skeleton_signals[i]; + g_signal_connect (mechanism->skeleton, + sig.signal_name, + G_CALLBACK (sig.callback), + mechanism); + } + + reset_killtimer (); return TRUE; + +error: + return FALSE; } -gboolean -csd_datetime_mechanism_can_set_timezone (CsdDatetimeMechanism *mechanism, - DBusGMethodInvocation *context) + +CsdDatetimeMechanism * +csd_datetime_mechanism_new (void) { - check_can_do (mechanism, - "org.cinnamon.settingsdaemon.datetimemechanism.configure", - context); + GObject *object; + gboolean res; - return TRUE; + object = g_object_new (CSD_DATETIME_TYPE_MECHANISM, NULL); + + res = register_mechanism (CSD_DATETIME_MECHANISM (object)); + if (! res) { + g_object_unref (object); + return NULL; + } + + return CSD_DATETIME_MECHANISM (object); } -gboolean -csd_datetime_mechanism_can_set_using_ntp (CsdDatetimeMechanism *mechanism, - DBusGMethodInvocation *context) +static gboolean +_check_polkit_for_action (CsdDatetimeMechanism *mechanism, GDBusMethodInvocation *invocation) { - check_can_do (mechanism, - "org.cinnamon.settingsdaemon.datetimemechanism.configure", - context); + const char *action = "org.cinnamon.settingsdaemon.datetimemechanism.configure"; + const char *sender; + GError *error; + PolkitSubject *subject; + PolkitAuthorizationResult *result; + + error = NULL; + + /* Check that caller is privileged */ + sender = g_dbus_method_invocation_get_sender (invocation); + subject = polkit_system_bus_name_new (sender); + + result = polkit_authority_check_authorization_sync (mechanism->auth, + subject, + action, + NULL, + POLKIT_CHECK_AUTHORIZATION_FLAGS_ALLOW_USER_INTERACTION, + NULL, &error); + g_object_unref (subject); + + if (error) { + g_dbus_method_invocation_return_gerror (invocation, error); + g_error_free (error); + + return FALSE; + } + + if (!polkit_authorization_result_get_is_authorized (result)) { + error = g_error_new (CSD_DATETIME_MECHANISM_ERROR, + CSD_DATETIME_MECHANISM_ERROR_NOT_PRIVILEGED, + "Not Authorized for action %s", action); + g_dbus_method_invocation_return_gerror (invocation, error); + g_error_free (error); + g_object_unref (result); + + return FALSE; + } + + g_object_unref (result); return TRUE; } diff --git a/plugins/datetime/csd-datetime-mechanism.h b/plugins/datetime/csd-datetime-mechanism.h index efc69ac9..ccb6f824 100644 --- a/plugins/datetime/csd-datetime-mechanism.h +++ b/plugins/datetime/csd-datetime-mechanism.h @@ -22,29 +22,15 @@ #define CSD_DATETIME_MECHANISM_H #include -#include +#include G_BEGIN_DECLS #define CSD_DATETIME_TYPE_MECHANISM (csd_datetime_mechanism_get_type ()) -#define CSD_DATETIME_MECHANISM(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), CSD_DATETIME_TYPE_MECHANISM, CsdDatetimeMechanism)) -#define CSD_DATETIME_MECHANISM_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), CSD_DATETIME_TYPE_MECHANISM, CsdDatetimeMechanismClass)) -#define CSD_DATETIME_IS_MECHANISM(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), CSD_DATETIME_TYPE_MECHANISM)) -#define CSD_DATETIME_IS_MECHANISM_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), CSD_DATETIME_TYPE_MECHANISM)) -#define CSD_DATETIME_MECHANISM_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), CSD_DATETIME_TYPE_MECHANISM, CsdDatetimeMechanismClass)) +G_DECLARE_FINAL_TYPE (CsdDatetimeMechanism, csd_datetime_mechanism, CSD_DATETIME, MECHANISM, GObject) -typedef struct CsdDatetimeMechanismPrivate CsdDatetimeMechanismPrivate; - -typedef struct -{ - GObject parent; - CsdDatetimeMechanismPrivate *priv; -} CsdDatetimeMechanism; - -typedef struct -{ - GObjectClass parent_class; -} CsdDatetimeMechanismClass; +extern GMainLoop *loop; +extern GDBusConnection *connection; typedef enum { @@ -59,54 +45,10 @@ typedef enum GType csd_datetime_mechanism_error_get_type (void); #define CSD_DATETIME_MECHANISM_TYPE_ERROR (csd_datetime_mechanism_error_get_type ()) - GQuark csd_datetime_mechanism_error_quark (void); GType csd_datetime_mechanism_get_type (void); CsdDatetimeMechanism *csd_datetime_mechanism_new (void); -/* exported methods */ -gboolean csd_datetime_mechanism_get_timezone (CsdDatetimeMechanism *mechanism, - DBusGMethodInvocation *context); -gboolean csd_datetime_mechanism_set_timezone (CsdDatetimeMechanism *mechanism, - const char *zone_file, - DBusGMethodInvocation *context); - -gboolean csd_datetime_mechanism_can_set_timezone (CsdDatetimeMechanism *mechanism, - DBusGMethodInvocation *context); - -gboolean csd_datetime_mechanism_set_time (CsdDatetimeMechanism *mechanism, - gint64 seconds_since_epoch, - DBusGMethodInvocation *context); - -gboolean csd_datetime_mechanism_set_date (CsdDatetimeMechanism *mechanism, - guint day, - guint month, - guint year, - DBusGMethodInvocation *context); - -gboolean csd_datetime_mechanism_can_set_time (CsdDatetimeMechanism *mechanism, - DBusGMethodInvocation *context); - -gboolean csd_datetime_mechanism_adjust_time (CsdDatetimeMechanism *mechanism, - gint64 seconds_to_add, - DBusGMethodInvocation *context); - -gboolean csd_datetime_mechanism_get_hardware_clock_using_utc (CsdDatetimeMechanism *mechanism, - DBusGMethodInvocation *context); - -gboolean csd_datetime_mechanism_set_hardware_clock_using_utc (CsdDatetimeMechanism *mechanism, - gboolean using_utc, - DBusGMethodInvocation *context); - -gboolean csd_datetime_mechanism_get_using_ntp (CsdDatetimeMechanism *mechanism, - DBusGMethodInvocation *context); - -gboolean csd_datetime_mechanism_set_using_ntp (CsdDatetimeMechanism *mechanism, - gboolean using_ntp, - DBusGMethodInvocation *context); - -gboolean csd_datetime_mechanism_can_set_using_ntp (CsdDatetimeMechanism *mechanism, - DBusGMethodInvocation *context); G_END_DECLS #endif /* CSD_DATETIME_MECHANISM_H */ diff --git a/plugins/datetime/meson.build b/plugins/datetime/meson.build index 382e6664..71a07371 100644 --- a/plugins/datetime/meson.build +++ b/plugins/datetime/meson.build @@ -1,16 +1,10 @@ -plugin_name = 'datetime' -datetime_dbus = custom_target( - 'datetime-dbus', - input: 'csd-datetime-mechanism.xml', - output: 'csd-datetime-mechanism-glue.h', - command: [ - dbus_binding_tool, - '--prefix=csd_datetime_mechanism', - '--mode=glib-server', - '--output=@OUTPUT@', - '@INPUT@', - ], +datetime_exported_iface = gnome.gdbus_codegen( + 'csd-exported-datetime', + 'csd-datetime-mechanism.xml', + interface_prefix: 'org.cinnamon.SettingsDaemon.DateTimeMechanism.', + namespace: 'Csd', + annotations: ['org.cinnamon.SettingsDaemon.DateTimeMechanism', 'org.gtk.GDBus.C.Name', 'ExportedDateTime'] ) datetime_common_sources = [ @@ -28,8 +22,8 @@ datetime_sources = [ 'csd-datetime-mechanism-suse.c', 'csd-datetime-mechanism-suse.h', 'csd-datetime-mechanism-main.c', - datetime_dbus, datetime_common_sources, + datetime_exported_iface ] test_timezone_sources = [ @@ -40,11 +34,10 @@ test_timezone_sources = [ datetime_deps = [ common_dep, csd_dep, - dbus, - dbus_glib, libnotify, polkit, xfixes, + gio ] if polkit.found()