summaryrefslogtreecommitdiff
path: root/cpufreq/src/cpufreq-utils.c
diff options
context:
space:
mode:
authorCarlos Garcia Campos <carlosgc@gnome.org>2008-05-25 15:32:01 +0000
committerCarlos Garcia Campos <carlosgc@src.gnome.org>2008-05-25 15:32:01 +0000
commit2c7ea0b3b6555f45358d956649bb768ee23090ff (patch)
treee79540b85c7fe13747dd21148d405c76ff49f10b /cpufreq/src/cpufreq-utils.c
parent15bcb5501f7d39c69e3fc0d39db3a638c1e1cd1f (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.c137
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)