2
* Copyright (C) 2011 Codethink Limited
4
* This program is free software; you can redistribute it and/or modify
5
* it under the terms of the GNU General Public License as published by
6
* the Free Software Foundation; either version 2 of the License, or
7
* (at your option) any later version.
9
* This program is distributed in the hope that it will be useful,
10
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
* GNU General Public License for more details.
14
* You should have received a copy of the GNU General Public License
15
* along with this program; if not, write to the Free Software
16
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
* Author: Ryan Lortie <desrt@desrt.ca>
26
#include <polkit/polkit.h>
28
#include "set-timezone.h"
30
#define CACHE_VALIDITY_SEC 20
32
#define MECHANISM_BUS_NAME "org.freedesktop.timedate1"
33
#define MECHANISM_OBJECT_PATH "/org/freedesktop/timedate1"
34
#define MECHANISM_INTERFACE "org.freedesktop.timedate1"
41
static Cache can_set_timezone_cache;
43
static GDBusConnection *
44
get_system_bus (GError **error)
46
static GDBusConnection *system;
47
static gboolean initialised;
48
static GError *saved_error;
52
system = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &saved_error);
56
if (system == NULL && error)
57
*error = g_error_copy (saved_error);
63
can_set (Cache *cache, const gchar *method_name)
65
guint64 now = g_get_monotonic_time ();
67
if (now - cache->stamp > (CACHE_VALIDITY_SEC * 1000000))
69
PolkitAuthority *authority;
70
PolkitSubject *subject;
71
PolkitAuthorizationResult *res;
73
authority = polkit_authority_get_sync (NULL, NULL);
74
subject = polkit_unix_session_new_for_process_sync (getpid (), NULL, NULL);
76
res = polkit_authority_check_authorization_sync (authority,
78
"org.freedesktop.timedate1.set-timezone",
80
POLKIT_CHECK_AUTHORIZATION_FLAGS_NONE,
84
cache->stamp = g_get_monotonic_time ();
90
if (polkit_authorization_result_get_is_authorized (res))
92
else if (polkit_authorization_result_get_is_challenge (res))
100
g_object_unref (authority);
101
g_object_unref (subject);
108
can_set_system_timezone (void)
110
return can_set (&can_set_timezone_cache, "CanSetTimezone");
114
set_system_timezone_finish (GAsyncResult *result,
117
GDBusConnection *system_bus = get_system_bus (NULL);
120
/* detect if we set an error due to being unable to get the system bus */
121
if (g_simple_async_result_is_valid (result, NULL, set_system_timezone_async))
123
g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result),
128
g_assert (system_bus != NULL);
130
reply = g_dbus_connection_call_finish (system_bus, result, error);
133
g_variant_unref (reply);
135
return reply != NULL;
139
set_system_timezone_async (const gchar *tz,
140
GAsyncReadyCallback callback,
143
GDBusConnection *system_bus;
144
GError *error = NULL;
146
system_bus = get_system_bus (&error);
148
if (system_bus == NULL)
150
GSimpleAsyncResult *simple;
152
simple = g_simple_async_result_new (NULL, callback, user_data,
153
set_system_timezone_async);
154
g_simple_async_result_set_from_error (simple, error);
155
g_simple_async_result_complete_in_idle (simple);
156
g_object_unref (simple);
157
g_error_free (error);
160
g_dbus_connection_call (system_bus, MECHANISM_BUS_NAME,
161
MECHANISM_OBJECT_PATH, MECHANISM_INTERFACE,
162
"SetTimezone", g_variant_new ("(sb)", tz, TRUE),
163
NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL,
164
callback, user_data);