diff options
author | Carlos Garcia Campos <carlosgc@gnome.org> | 2008-05-25 15:32:01 +0000 |
---|---|---|
committer | Carlos Garcia Campos <carlosgc@src.gnome.org> | 2008-05-25 15:32:01 +0000 |
commit | 2c7ea0b3b6555f45358d956649bb768ee23090ff (patch) | |
tree | e79540b85c7fe13747dd21148d405c76ff49f10b /cpufreq/src/cpufreq-utils.c | |
parent | 15bcb5501f7d39c69e3fc0d39db3a638c1e1cd1f (diff) |
Use PolicyKit when available in the cpufreq-selector instead of installing
2008-05-25 Carlos Garcia Campos <carlosgc@gnome.org>
* src/Makefile.am:
* src/cpufreq-applet.c:
* src/cpufreq-popup.[ch]:
* src/cpufreq-selector.[ch]:
* src/cpufreq-utils.c:
* src/cpufreq-selector/Makefile.am:
* src/cpufreq-selector/main.c:
* src/cpufreq-selector/cpufreq-selector-factory.[ch]:
* src/cpufreq-selector/cpufreq-selector-service.[ch]:
* src/cpufreq-selector/cpufreq-selector-service.xml:
* src/cpufreq-selector/org.gnome.CPUFreqSelector.conf:
* src/cpufreq-selector/org.gnome.CPUFreqSelector.service.in:
* src/cpufreq-selector/org.gnome.cpufreqselector.policy.in:
Use PolicyKit when available in the cpufreq-selector instead of
installing it with suid bit enabled. Fixes bug #528536.
svn path=/trunk/; revision=10849
Diffstat (limited to 'cpufreq/src/cpufreq-utils.c')
-rw-r--r-- | cpufreq/src/cpufreq-utils.c | 137 |
1 files changed, 137 insertions, 0 deletions
diff --git a/cpufreq/src/cpufreq-utils.c b/cpufreq/src/cpufreq-utils.c index c6b918ef9..05a0a8da2 100644 --- a/cpufreq/src/cpufreq-utils.c +++ b/cpufreq/src/cpufreq-utils.c @@ -19,6 +19,15 @@ * Authors : Carlos García Campos <carlosgc@gnome.org> */ +#include <config.h> + +#ifdef HAVE_POLKIT_GNOME +#include <dbus/dbus-glib.h> +#include <dbus/dbus-glib-lowlevel.h> +#include <polkit/polkit.h> +#include <polkit-dbus/polkit-dbus.h> +#endif + #include <glib.h> #include <gtk/gtkmessagedialog.h> #include <sys/types.h> @@ -99,6 +108,133 @@ cpufreq_utils_display_error (const gchar *message, gtk_widget_show (dialog); } +#ifdef HAVE_POLKIT_GNOME +#define CACHE_VALIDITY_SEC 2 + +static gboolean +pk_io_watch_have_data (GIOChannel *channel, + GIOCondition condition, + PolKitContext *pk_context) +{ + polkit_context_io_func (pk_context, + g_io_channel_unix_get_fd (channel)); + return TRUE; +} + +static int +pk_add_io_watch (PolKitContext *pk_context, + int watch_id) +{ + GIOChannel *channel; + guint id = 0; + + channel = g_io_channel_unix_new (watch_id); + if (!channel) + return 0; + + id = g_io_add_watch (channel, G_IO_IN, + (GIOFunc)pk_io_watch_have_data, + pk_context); + g_io_channel_unref (channel); + + return id; +} + +static void +pk_remove_io_watch (PolKitContext *pk_context, + int watch_id) +{ + g_source_remove (watch_id); +} + +static gboolean +selector_is_available (const gchar *action) +{ + static DBusGConnection *system_bus = NULL; + static PolKitContext *pk_context = NULL; + PolKitCaller *pk_caller; + PolKitAction *pk_action; + PolKitResult pk_result; + PolKitError *pk_error = NULL; + GError *error = NULL; + DBusError dbus_error; + + if (!system_bus) { + system_bus = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error); + if (!system_bus) { + g_warning (error->message); + g_error_free (error); + + return FALSE; + } + } + + if (!pk_context) { + PolKitError *pk_error = NULL; + + pk_context = polkit_context_new (); + polkit_context_set_io_watch_functions (pk_context, + pk_add_io_watch, + pk_remove_io_watch); + if (!polkit_context_init (pk_context, &pk_error)) { + polkit_context_unref (pk_context); + pk_context = NULL; + + if (polkit_error_is_set (pk_error)) { + g_warning (polkit_error_get_error_message (pk_error)); + polkit_error_free (pk_error); + } else { + g_warning ("Cannot initialize libpolkit"); + } + + return FALSE; + } + } + + dbus_error_init (&dbus_error); + pk_caller = polkit_caller_new_from_pid (dbus_g_connection_get_connection (system_bus), + getpid (), &dbus_error); + if (!pk_caller) { + g_warning ("Cannot get caller from dbus name"); + + return FALSE; + } + + pk_action = polkit_action_new (); + polkit_action_set_action_id (pk_action, action); + pk_result = polkit_context_is_caller_authorized (pk_context, + pk_action, pk_caller, + FALSE, &pk_error); + + polkit_caller_unref (pk_caller); + polkit_action_unref (pk_action); + + if (polkit_error_is_set (pk_error)) { + g_warning (polkit_error_get_error_message (pk_error)); + polkit_error_free (pk_error); + + return FALSE; + } + + return !(pk_result == POLKIT_RESULT_UNKNOWN || pk_result == POLKIT_RESULT_NO); +} + +gboolean +cpufreq_utils_selector_is_available (void) +{ + static gboolean cache = FALSE; + static time_t last_refreshed = 0; + time_t now; + + time (&now); + if (ABS (now - last_refreshed) > CACHE_VALIDITY_SEC) { + cache = selector_is_available ("org.gnome.cpufreqselector"); + last_refreshed = now; + } + + return cache; +} +#else /* !HAVE_POLKIT_GNOME */ gboolean cpufreq_utils_selector_is_available (void) { @@ -130,6 +266,7 @@ cpufreq_utils_selector_is_available (void) return FALSE; } +#endif /* HAVE_POLKIT_GNOME */ gchar * cpufreq_utils_get_frequency_label (guint freq) |