File: | plugins/datetime/csd_datetime-mechanism.c |
Warning: | line 52, column 16 This statement is never executed |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- |
2 | * |
3 | * Copyright (C) 2007 David Zeuthen <david@fubar.dk> |
4 | * |
5 | * This program is free software; you can redistribute it and/or modify |
6 | * it under the terms of the GNU General Public License as published by |
7 | * the Free Software Foundation; either version 2 of the License, or |
8 | * (at your option) any later version. |
9 | * |
10 | * This program is distributed in the hope that it will be useful, |
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
13 | * GNU General Public License for more details. |
14 | * |
15 | * You should have received a copy of the GNU General Public License |
16 | * along with this program; if not, write to the Free Software |
17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. |
18 | * |
19 | */ |
20 | |
21 | #ifdef HAVE_CONFIG_H1 |
22 | # include "config.h" |
23 | #endif |
24 | |
25 | #include <stdlib.h> |
26 | #include <stdio.h> |
27 | #include <fcntl.h> |
28 | #include <unistd.h> |
29 | #include <string.h> |
30 | #include <sys/wait.h> |
31 | #include <errno(*__errno_location ()).h> |
32 | #include <sys/time.h> |
33 | |
34 | #include <glib.h> |
35 | #include <glib-object.h> |
36 | |
37 | #include <dbus/dbus-glib.h> |
38 | #include <dbus/dbus-glib-lowlevel.h> |
39 | |
40 | #include <polkit/polkit.h> |
41 | |
42 | #include "system-timezone.h" |
43 | |
44 | #include "csd_datetime-mechanism.h" |
45 | #include "csd_datetime-mechanism-glue.h" |
46 | |
47 | static gboolean |
48 | do_exit (gpointer user_data) |
49 | { |
50 | g_debug ("Exiting due to inactivity"); |
51 | exit (1); |
52 | return FALSE(0); |
This statement is never executed | |
53 | } |
54 | |
55 | static void |
56 | reset_killtimer (void) |
57 | { |
58 | static guint timer_id = 0; |
59 | |
60 | if (timer_id > 0) { |
61 | g_source_remove (timer_id); |
62 | } |
63 | g_debug ("Setting killtimer to 30 seconds..."); |
64 | timer_id = g_timeout_add_seconds (30, do_exit, NULL((void*)0)); |
65 | } |
66 | |
67 | struct CsdDatetimeMechanismPrivate |
68 | { |
69 | DBusGConnection *system_bus_connection; |
70 | DBusGProxy *system_bus_proxy; |
71 | PolkitAuthority *auth; |
72 | }; |
73 | |
74 | static void csd_datetime_mechanism_finalize (GObject *object); |
75 | |
76 | G_DEFINE_TYPE_WITH_PRIVATE (CsdDatetimeMechanism, csd_datetime_mechanism, G_TYPE_OBJECT)static void csd_datetime_mechanism_init (CsdDatetimeMechanism *self); static void csd_datetime_mechanism_class_init (CsdDatetimeMechanismClass *klass); static GType csd_datetime_mechanism_get_type_once ( void); static gpointer csd_datetime_mechanism_parent_class = ( (void*)0); static gint CsdDatetimeMechanism_private_offset; static void csd_datetime_mechanism_class_intern_init (gpointer klass ) { csd_datetime_mechanism_parent_class = g_type_class_peek_parent (klass); if (CsdDatetimeMechanism_private_offset != 0) g_type_class_adjust_private_offset (klass, &CsdDatetimeMechanism_private_offset); csd_datetime_mechanism_class_init ((CsdDatetimeMechanismClass*) klass); } __attribute__ ((__unused__ )) static inline gpointer csd_datetime_mechanism_get_instance_private (CsdDatetimeMechanism *self) { return (((gpointer) ((guint8* ) (self) + (glong) (CsdDatetimeMechanism_private_offset)))); } GType csd_datetime_mechanism_get_type (void) { static GType static_g_define_type_id = 0; if ((__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id ) == sizeof (gpointer), "Expression evaluates to false"); (void ) (0 ? (gpointer) * (&static_g_define_type_id) : ((void*) 0)); (!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id ) == sizeof (gpointer), "Expression evaluates to false"); __typeof__ (*(&static_g_define_type_id)) gapg_temp_newval; __typeof__ ((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id ); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5) ; gapg_temp_newval; })) && g_once_init_enter_pointer ( &static_g_define_type_id)); })) ) { GType g_define_type_id = csd_datetime_mechanism_get_type_once (); (__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id) == sizeof (gpointer), "Expression evaluates to false"); 0 ? (void) (*( &static_g_define_type_id) = (g_define_type_id)) : (void) 0 ; g_once_init_leave_pointer ((&static_g_define_type_id), ( gpointer) (guintptr) (g_define_type_id)); })) ; } return static_g_define_type_id ; } __attribute__ ((__noinline__)) static GType csd_datetime_mechanism_get_type_once (void) { GType g_define_type_id = g_type_register_static_simple (((GType) ((20) << (2))), g_intern_static_string ("CsdDatetimeMechanism" ), sizeof (CsdDatetimeMechanismClass), (GClassInitFunc)(void ( *)(void)) csd_datetime_mechanism_class_intern_init, sizeof (CsdDatetimeMechanism ), (GInstanceInitFunc)(void (*)(void)) csd_datetime_mechanism_init , (GTypeFlags) 0); { {{ CsdDatetimeMechanism_private_offset = g_type_add_instance_private (g_define_type_id, sizeof (CsdDatetimeMechanismPrivate )); };} } return g_define_type_id; } |
77 | |
78 | GQuark |
79 | csd_datetime_mechanism_error_quark (void) |
80 | { |
81 | static GQuark ret = 0; |
82 | |
83 | if (ret == 0) { |
84 | ret = g_quark_from_static_string ("csd_datetime_mechanism_error"); |
85 | } |
86 | |
87 | return ret; |
88 | } |
89 | |
90 | |
91 | #define ENUM_ENTRY(NAME, DESC){ NAME, "" "NAME" "", DESC } { NAME, "" #NAME "", DESC } |
92 | |
93 | GType |
94 | csd_datetime_mechanism_error_get_type (void) |
95 | { |
96 | static GType etype = 0; |
97 | |
98 | if (etype == 0) |
99 | { |
100 | static const GEnumValue values[] = |
101 | { |
102 | ENUM_ENTRY (CSD_DATETIME_MECHANISM_ERROR_GENERAL, "GeneralError"){ CSD_DATETIME_MECHANISM_ERROR_GENERAL, "" "CSD_DATETIME_MECHANISM_ERROR_GENERAL" "", "GeneralError" }, |
103 | ENUM_ENTRY (CSD_DATETIME_MECHANISM_ERROR_NOT_PRIVILEGED, "NotPrivileged"){ CSD_DATETIME_MECHANISM_ERROR_NOT_PRIVILEGED, "" "CSD_DATETIME_MECHANISM_ERROR_NOT_PRIVILEGED" "", "NotPrivileged" }, |
104 | ENUM_ENTRY (CSD_DATETIME_MECHANISM_ERROR_INVALID_TIMEZONE_FILE, "InvalidTimezoneFile"){ CSD_DATETIME_MECHANISM_ERROR_INVALID_TIMEZONE_FILE, "" "CSD_DATETIME_MECHANISM_ERROR_INVALID_TIMEZONE_FILE" "", "InvalidTimezoneFile" }, |
105 | { 0, 0, 0 } |
106 | }; |
107 | |
108 | g_assert (CSD_DATETIME_MECHANISM_NUM_ERRORS == G_N_ELEMENTS (values) - 1)do { if (CSD_DATETIME_MECHANISM_NUM_ERRORS == (sizeof (values ) / sizeof ((values)[0])) - 1) ; else g_assertion_message_expr (((gchar*) 0), "csd_datetime-mechanism.c", 108, ((const char *) (__func__)), "CSD_DATETIME_MECHANISM_NUM_ERRORS == G_N_ELEMENTS (values) - 1" ); } while (0); |
109 | |
110 | etype = g_enum_register_static ("CsdDatetimeMechanismError", values); |
111 | } |
112 | |
113 | return etype; |
114 | } |
115 | |
116 | |
117 | static GObject * |
118 | csd_datetime_mechanism_constructor (GType type, |
119 | guint n_construct_properties, |
120 | GObjectConstructParam *construct_properties) |
121 | { |
122 | CsdDatetimeMechanism *mechanism; |
123 | |
124 | mechanism = CSD_DATETIME_MECHANISM (G_OBJECT_CLASS (csd_datetime_mechanism_parent_class)->constructor (((((CsdDatetimeMechanism*) (void *) g_type_check_instance_cast ((GTypeInstance*) ((((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass*) ((csd_datetime_mechanism_parent_class)), (((GType ) ((20) << (2))))))))->constructor ( type, n_construct_properties , construct_properties))), ((csd_datetime_mechanism_get_type ( ))))))) |
125 | type,((((CsdDatetimeMechanism*) (void *) g_type_check_instance_cast ((GTypeInstance*) ((((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass*) ((csd_datetime_mechanism_parent_class)), (((GType ) ((20) << (2))))))))->constructor ( type, n_construct_properties , construct_properties))), ((csd_datetime_mechanism_get_type ( ))))))) |
126 | n_construct_properties,((((CsdDatetimeMechanism*) (void *) g_type_check_instance_cast ((GTypeInstance*) ((((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass*) ((csd_datetime_mechanism_parent_class)), (((GType ) ((20) << (2))))))))->constructor ( type, n_construct_properties , construct_properties))), ((csd_datetime_mechanism_get_type ( ))))))) |
127 | construct_properties))((((CsdDatetimeMechanism*) (void *) g_type_check_instance_cast ((GTypeInstance*) ((((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass*) ((csd_datetime_mechanism_parent_class)), (((GType ) ((20) << (2))))))))->constructor ( type, n_construct_properties , construct_properties))), ((csd_datetime_mechanism_get_type ( ))))))); |
128 | |
129 | return G_OBJECT (mechanism)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((mechanism)), (((GType) ((20) << (2)))))))); |
130 | } |
131 | |
132 | static void |
133 | csd_datetime_mechanism_class_init (CsdDatetimeMechanismClass *klass) |
134 | { |
135 | GObjectClass *object_class = G_OBJECT_CLASS (klass)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass *) ((klass)), (((GType) ((20) << (2)))))))); |
136 | |
137 | object_class->constructor = csd_datetime_mechanism_constructor; |
138 | object_class->finalize = csd_datetime_mechanism_finalize; |
139 | |
140 | dbus_g_object_type_install_info (CSD_DATETIME_TYPE_MECHANISM(csd_datetime_mechanism_get_type ()), &dbus_glib_csd_datetime_mechanism_object_info); |
141 | |
142 | dbus_g_error_domain_register (CSD_DATETIME_MECHANISM_ERRORcsd_datetime_mechanism_error_quark (), NULL((void*)0), CSD_DATETIME_MECHANISM_TYPE_ERROR(csd_datetime_mechanism_error_get_type ())); |
143 | |
144 | } |
145 | |
146 | static void |
147 | csd_datetime_mechanism_init (CsdDatetimeMechanism *mechanism) |
148 | { |
149 | mechanism->priv = csd_datetime_mechanism_get_instance_private (mechanism); |
150 | |
151 | } |
152 | |
153 | static void |
154 | csd_datetime_mechanism_finalize (GObject *object) |
155 | { |
156 | CsdDatetimeMechanism *mechanism; |
157 | |
158 | g_return_if_fail (object != NULL)do { if ((object != ((void*)0))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char*) (__func__)), "object != NULL") ; return; } } while (0); |
159 | g_return_if_fail (CSD_DATETIME_IS_MECHANISM (object))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((object)); GType __t = ((csd_datetime_mechanism_get_type ( ))); gboolean __r; if (!__inst) __r = (0); else if (__inst-> g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning (((gchar*) 0 ), ((const char*) (__func__)), "CSD_DATETIME_IS_MECHANISM (object)" ); return; } } while (0); |
160 | |
161 | mechanism = CSD_DATETIME_MECHANISM (object)((((CsdDatetimeMechanism*) (void *) g_type_check_instance_cast ((GTypeInstance*) ((object)), ((csd_datetime_mechanism_get_type ())))))); |
162 | |
163 | g_return_if_fail (mechanism->priv != NULL)do { if ((mechanism->priv != ((void*)0))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char*) (__func__)), "mechanism->priv != NULL" ); return; } } while (0); |
164 | |
165 | g_object_unref (mechanism->priv->system_bus_proxy); |
166 | |
167 | G_OBJECT_CLASS (csd_datetime_mechanism_parent_class)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass *) ((csd_datetime_mechanism_parent_class)), (((GType) ((20) << (2))))))))->finalize (object); |
168 | } |
169 | |
170 | static gboolean |
171 | register_mechanism (CsdDatetimeMechanism *mechanism) |
172 | { |
173 | GError *error = NULL((void*)0); |
174 | |
175 | mechanism->priv->auth = polkit_authority_get_sync (NULL((void*)0), &error); |
176 | if (mechanism->priv->auth == NULL((void*)0)) { |
177 | if (error != NULL((void*)0)) { |
178 | g_critical ("error getting system bus: %s", error->message); |
179 | g_error_free (error); |
180 | } |
181 | goto error; |
182 | } |
183 | |
184 | mechanism->priv->system_bus_connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error); |
185 | if (mechanism->priv->system_bus_connection == NULL((void*)0)) { |
186 | if (error != NULL((void*)0)) { |
187 | g_critical ("error getting system bus: %s", error->message); |
188 | g_error_free (error); |
189 | } |
190 | goto error; |
191 | } |
192 | |
193 | dbus_g_connection_register_g_object (mechanism->priv->system_bus_connection, "/", |
194 | G_OBJECT (mechanism)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((mechanism)), (((GType) ((20) << (2))))))))); |
195 | |
196 | mechanism->priv->system_bus_proxy = dbus_g_proxy_new_for_name (mechanism->priv->system_bus_connection, |
197 | DBUS_SERVICE_DBUS"org.freedesktop.DBus", |
198 | DBUS_PATH_DBUS"/org/freedesktop/DBus", |
199 | DBUS_INTERFACE_DBUS"org.freedesktop.DBus"); |
200 | |
201 | reset_killtimer (); |
202 | |
203 | return TRUE(!(0)); |
204 | |
205 | error: |
206 | return FALSE(0); |
207 | } |
208 | |
209 | |
210 | CsdDatetimeMechanism * |
211 | csd_datetime_mechanism_new (void) |
212 | { |
213 | GObject *object; |
214 | gboolean res; |
215 | |
216 | object = g_object_new (CSD_DATETIME_TYPE_MECHANISM(csd_datetime_mechanism_get_type ()), NULL((void*)0)); |
217 | |
218 | res = register_mechanism (CSD_DATETIME_MECHANISM (object)((((CsdDatetimeMechanism*) (void *) g_type_check_instance_cast ((GTypeInstance*) ((object)), ((csd_datetime_mechanism_get_type ()))))))); |
219 | if (! res) { |
220 | g_object_unref (object); |
221 | return NULL((void*)0); |
222 | } |
223 | |
224 | return CSD_DATETIME_MECHANISM (object)((((CsdDatetimeMechanism*) (void *) g_type_check_instance_cast ((GTypeInstance*) ((object)), ((csd_datetime_mechanism_get_type ())))))); |
225 | } |
226 | |
227 | static gboolean |
228 | _check_polkit_for_action (CsdDatetimeMechanism *mechanism, DBusGMethodInvocation *context, const char *action) |
229 | { |
230 | const char *sender; |
231 | GError *error; |
232 | PolkitSubject *subject; |
233 | PolkitAuthorizationResult *result; |
234 | |
235 | error = NULL((void*)0); |
236 | |
237 | /* Check that caller is privileged */ |
238 | sender = dbus_g_method_get_sender (context); |
239 | subject = polkit_system_bus_name_new (sender); |
240 | |
241 | result = polkit_authority_check_authorization_sync (mechanism->priv->auth, |
242 | subject, |
243 | action, |
244 | NULL((void*)0), |
245 | POLKIT_CHECK_AUTHORIZATION_FLAGS_ALLOW_USER_INTERACTION, |
246 | NULL((void*)0), &error); |
247 | g_object_unref (subject); |
248 | |
249 | if (error) { |
250 | dbus_g_method_return_error (context, error); |
251 | g_error_free (error); |
252 | |
253 | return FALSE(0); |
254 | } |
255 | |
256 | if (!polkit_authorization_result_get_is_authorized (result)) { |
257 | error = g_error_new (CSD_DATETIME_MECHANISM_ERRORcsd_datetime_mechanism_error_quark (), |
258 | CSD_DATETIME_MECHANISM_ERROR_NOT_PRIVILEGED, |
259 | "Not Authorized for action %s", action); |
260 | dbus_g_method_return_error (context, error); |
261 | g_error_free (error); |
262 | g_object_unref (result); |
263 | |
264 | return FALSE(0); |
265 | } |
266 | |
267 | g_object_unref (result); |
268 | |
269 | return TRUE(!(0)); |
270 | } |
271 | |
272 | |
273 | static gboolean |
274 | _set_time (CsdDatetimeMechanism *mechanism, |
275 | const struct timeval *tv, |
276 | DBusGMethodInvocation *context) |
277 | { |
278 | GError *error; |
279 | |
280 | if (!_check_polkit_for_action (mechanism, context, "org.cafe.settingsdaemon.datetimemechanism.settime")) |
281 | return FALSE(0); |
282 | |
283 | if (settimeofday (tv, NULL((void*)0)) != 0) { |
284 | error = g_error_new (CSD_DATETIME_MECHANISM_ERRORcsd_datetime_mechanism_error_quark (), |
285 | CSD_DATETIME_MECHANISM_ERROR_GENERAL, |
286 | "Error calling settimeofday({%ld,%ld}): %s", |
287 | (gint64) tv->tv_sec, (gint64) tv->tv_usec, |
288 | strerror (errno(*__errno_location ()))); |
289 | dbus_g_method_return_error (context, error); |
290 | g_error_free (error); |
291 | return FALSE(0); |
292 | } |
293 | |
294 | if (g_file_test ("/sbin/hwclock", |
295 | G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR | G_FILE_TEST_IS_EXECUTABLE)) { |
296 | int exit_status; |
297 | if (!g_spawn_command_line_sync ("/sbin/hwclock --systohc", NULL((void*)0), NULL((void*)0), &exit_status, &error)) { |
298 | GError *error2; |
299 | error2 = g_error_new (CSD_DATETIME_MECHANISM_ERRORcsd_datetime_mechanism_error_quark (), |
300 | CSD_DATETIME_MECHANISM_ERROR_GENERAL, |
301 | "Error spawning /sbin/hwclock: %s", error->message); |
302 | g_error_free (error); |
303 | dbus_g_method_return_error (context, error2); |
304 | g_error_free (error2); |
305 | return FALSE(0); |
306 | } |
307 | if (WEXITSTATUS (exit_status)(((exit_status) & 0xff00) >> 8) != 0) { |
308 | error = g_error_new (CSD_DATETIME_MECHANISM_ERRORcsd_datetime_mechanism_error_quark (), |
309 | CSD_DATETIME_MECHANISM_ERROR_GENERAL, |
310 | "/sbin/hwclock returned %d", exit_status); |
311 | dbus_g_method_return_error (context, error); |
312 | g_error_free (error); |
313 | return FALSE(0); |
314 | } |
315 | } |
316 | |
317 | dbus_g_method_return (context); |
318 | return TRUE(!(0)); |
319 | } |
320 | |
321 | static gboolean |
322 | _rh_update_etc_sysconfig_clock (DBusGMethodInvocation *context, const char *key, const char *value) |
323 | { |
324 | /* On Red Hat / Fedora, the /etc/sysconfig/clock file needs to be kept in sync */ |
325 | if (g_file_test ("/etc/sysconfig/clock", G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR)) { |
326 | char **lines; |
327 | int n; |
328 | gboolean replaced; |
329 | char *data; |
330 | gsize len; |
331 | GError *error; |
332 | |
333 | error = NULL((void*)0); |
334 | |
335 | if (!g_file_get_contents ("/etc/sysconfig/clock", &data, &len, &error)) { |
336 | GError *error2; |
337 | error2 = g_error_new (CSD_DATETIME_MECHANISM_ERRORcsd_datetime_mechanism_error_quark (), |
338 | CSD_DATETIME_MECHANISM_ERROR_GENERAL, |
339 | "Error reading /etc/sysconfig/clock file: %s", error->message); |
340 | g_error_free (error); |
341 | dbus_g_method_return_error (context, error2); |
342 | g_error_free (error2); |
343 | return FALSE(0); |
344 | } |
345 | replaced = FALSE(0); |
346 | lines = g_strsplit (data, "\n", 0); |
347 | g_free (data); |
348 | |
349 | for (n = 0; lines[n] != NULL((void*)0); n++) { |
350 | if (g_str_has_prefix (lines[n], key)(__builtin_constant_p (key)? __extension__ ({ const char * const __str = (lines[n]); const char * const __prefix = (key); gboolean __result = (0); if (__str == ((void*)0) || __prefix == ((void *)0)) __result = (g_str_has_prefix) (__str, __prefix); else { const size_t __str_len = strlen (((__str) + !(__str))); const size_t __prefix_len = strlen (((__prefix) + !(__prefix))); if (__str_len >= __prefix_len) __result = memcmp (((__str) + !(__str)), ((__prefix) + !(__prefix)), __prefix_len) == 0; } __result; }) : (g_str_has_prefix) (lines[n], key) )) { |
351 | g_free (lines[n]); |
352 | lines[n] = g_strdup_printf ("%s%s", key, value); |
353 | replaced = TRUE(!(0)); |
354 | } |
355 | } |
356 | if (replaced) { |
357 | GString *str; |
358 | |
359 | str = g_string_new (NULL((void*)0)); |
360 | for (n = 0; lines[n] != NULL((void*)0); n++) { |
361 | g_string_append (str, lines[n])(__builtin_constant_p (lines[n]) ? __extension__ ({ const char * const __val = (lines[n]); g_string_append_len_inline (str, __val, (__val != ((void*)0)) ? (gssize) strlen (((__val) + ! (__val))) : (gssize) -1); }) : g_string_append_len_inline (str , lines[n], (gssize) -1)); |
362 | if (lines[n + 1] != NULL((void*)0)) |
363 | g_string_append_c (str, '\n')g_string_append_c_inline (str, '\n'); |
364 | } |
365 | data = g_string_free (str, FALSE)(__builtin_constant_p ((0)) ? (((0)) ? (g_string_free) ((str) , ((0))) : g_string_free_and_steal (str)) : (g_string_free) ( (str), ((0)))); |
366 | len = strlen (data); |
367 | if (!g_file_set_contents ("/etc/sysconfig/clock", data, len, &error)) { |
368 | GError *error2; |
369 | error2 = g_error_new (CSD_DATETIME_MECHANISM_ERRORcsd_datetime_mechanism_error_quark (), |
370 | CSD_DATETIME_MECHANISM_ERROR_GENERAL, |
371 | "Error updating /etc/sysconfig/clock: %s", error->message); |
372 | g_error_free (error); |
373 | dbus_g_method_return_error (context, error2); |
374 | g_error_free (error2); |
375 | g_free (data); |
376 | return FALSE(0); |
377 | } |
378 | g_free (data); |
379 | } |
380 | g_strfreev (lines); |
381 | } |
382 | |
383 | return TRUE(!(0)); |
384 | } |
385 | |
386 | /* exported methods */ |
387 | |
388 | gboolean |
389 | csd_datetime_mechanism_set_time (CsdDatetimeMechanism *mechanism, |
390 | gint64 seconds_since_epoch, |
391 | DBusGMethodInvocation *context) |
392 | { |
393 | struct timeval tv; |
394 | |
395 | reset_killtimer (); |
396 | g_debug ("SetTime(%ld) called", seconds_since_epoch); |
397 | |
398 | tv.tv_sec = (time_t) seconds_since_epoch; |
399 | tv.tv_usec = 0; |
400 | return _set_time (mechanism, &tv, context); |
401 | } |
402 | |
403 | gboolean |
404 | csd_datetime_mechanism_adjust_time (CsdDatetimeMechanism *mechanism, |
405 | gint64 seconds_to_add, |
406 | DBusGMethodInvocation *context) |
407 | { |
408 | struct timeval tv; |
409 | |
410 | reset_killtimer (); |
411 | g_debug ("AdjustTime(%ld) called", seconds_to_add); |
412 | |
413 | if (gettimeofday (&tv, NULL((void*)0)) != 0) { |
414 | GError *error; |
415 | error = g_error_new (CSD_DATETIME_MECHANISM_ERRORcsd_datetime_mechanism_error_quark (), |
416 | CSD_DATETIME_MECHANISM_ERROR_GENERAL, |
417 | "Error calling gettimeofday(): %s", strerror (errno(*__errno_location ()))); |
418 | dbus_g_method_return_error (context, error); |
419 | g_error_free (error); |
420 | return FALSE(0); |
421 | } |
422 | |
423 | tv.tv_sec += (time_t) seconds_to_add; |
424 | return _set_time (mechanism, &tv, context); |
425 | } |
426 | |
427 | |
428 | gboolean |
429 | csd_datetime_mechanism_set_timezone (CsdDatetimeMechanism *mechanism, |
430 | const char *zone_file, |
431 | DBusGMethodInvocation *context) |
432 | { |
433 | GError *error; |
434 | |
435 | reset_killtimer (); |
436 | g_debug ("SetTimezone('%s') called", zone_file); |
437 | |
438 | if (!_check_polkit_for_action (mechanism, context, "org.cafe.settingsdaemon.datetimemechanism.settimezone")) |
439 | return FALSE(0); |
440 | |
441 | error = NULL((void*)0); |
442 | |
443 | if (!system_timezone_set_from_file (zone_file, &error)) { |
444 | GError *error2; |
445 | int code; |
446 | |
447 | if (error->code == SYSTEM_TIMEZONE_ERROR_INVALID_TIMEZONE_FILE) |
448 | code = CSD_DATETIME_MECHANISM_ERROR_INVALID_TIMEZONE_FILE; |
449 | else |
450 | code = CSD_DATETIME_MECHANISM_ERROR_GENERAL; |
451 | |
452 | error2 = g_error_new (CSD_DATETIME_MECHANISM_ERRORcsd_datetime_mechanism_error_quark (), |
453 | code, "%s", error->message); |
454 | |
455 | g_error_free (error); |
456 | |
457 | dbus_g_method_return_error (context, error2); |
458 | g_error_free (error2); |
459 | |
460 | return FALSE(0); |
461 | } |
462 | |
463 | dbus_g_method_return (context); |
464 | return TRUE(!(0)); |
465 | } |
466 | |
467 | |
468 | gboolean |
469 | csd_datetime_mechanism_get_timezone (CsdDatetimeMechanism *mechism, |
470 | DBusGMethodInvocation *context) |
471 | { |
472 | gchar *timezone; |
473 | |
474 | reset_killtimer (); |
475 | |
476 | timezone = system_timezone_find (); |
477 | |
478 | dbus_g_method_return (context, timezone); |
479 | |
480 | return TRUE(!(0)); |
481 | } |
482 | |
483 | gboolean |
484 | csd_datetime_mechanism_get_hardware_clock_using_utc (CsdDatetimeMechanism *mechanism, |
485 | DBusGMethodInvocation *context) |
486 | { |
487 | char **lines; |
488 | char *data; |
489 | gsize len; |
490 | GError *error; |
491 | gboolean is_utc; |
492 | |
493 | error = NULL((void*)0); |
494 | |
495 | if (!g_file_get_contents ("/etc/adjtime", &data, &len, &error)) { |
496 | GError *error2; |
497 | error2 = g_error_new (CSD_DATETIME_MECHANISM_ERRORcsd_datetime_mechanism_error_quark (), |
498 | CSD_DATETIME_MECHANISM_ERROR_GENERAL, |
499 | "Error reading /etc/adjtime file: %s", error->message); |
500 | g_error_free (error); |
501 | dbus_g_method_return_error (context, error2); |
502 | g_error_free (error2); |
503 | return FALSE(0); |
504 | } |
505 | |
506 | lines = g_strsplit (data, "\n", 0); |
507 | g_free (data); |
508 | |
509 | if (g_strv_length (lines) < 3) { |
510 | error = g_error_new (CSD_DATETIME_MECHANISM_ERRORcsd_datetime_mechanism_error_quark (), |
511 | CSD_DATETIME_MECHANISM_ERROR_GENERAL, |
512 | "Cannot parse /etc/adjtime"); |
513 | dbus_g_method_return_error (context, error); |
514 | g_error_free (error); |
515 | g_strfreev (lines); |
516 | return FALSE(0); |
517 | } |
518 | |
519 | if (strcmp (lines[2], "UTC") == 0) { |
520 | is_utc = TRUE(!(0)); |
521 | } else if (strcmp (lines[2], "LOCAL") == 0) { |
522 | is_utc = FALSE(0); |
523 | } else { |
524 | error = g_error_new (CSD_DATETIME_MECHANISM_ERRORcsd_datetime_mechanism_error_quark (), |
525 | CSD_DATETIME_MECHANISM_ERROR_GENERAL, |
526 | "Expected UTC or LOCAL at line 3 of /etc/adjtime; found '%s'", lines[2]); |
527 | dbus_g_method_return_error (context, error); |
528 | g_error_free (error); |
529 | g_strfreev (lines); |
530 | return FALSE(0); |
531 | } |
532 | g_strfreev (lines); |
533 | dbus_g_method_return (context, is_utc); |
534 | return TRUE(!(0)); |
535 | } |
536 | |
537 | gboolean |
538 | csd_datetime_mechanism_set_hardware_clock_using_utc (CsdDatetimeMechanism *mechanism, |
539 | gboolean using_utc, |
540 | DBusGMethodInvocation *context) |
541 | { |
542 | GError *error; |
543 | |
544 | error = NULL((void*)0); |
545 | |
546 | if (!_check_polkit_for_action (mechanism, context, |
547 | "org.cafe.settingsdaemon.datetimemechanism.configurehwclock")) |
548 | return FALSE(0); |
549 | |
550 | if (g_file_test ("/sbin/hwclock", |
551 | G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR | G_FILE_TEST_IS_EXECUTABLE)) { |
552 | int exit_status; |
553 | char *cmd; |
554 | cmd = g_strdup_printf ("/sbin/hwclock %s --systohc", using_utc ? "--utc" : "--localtime"); |
555 | if (!g_spawn_command_line_sync (cmd, NULL((void*)0), NULL((void*)0), &exit_status, &error)) { |
556 | GError *error2; |
557 | error2 = g_error_new (CSD_DATETIME_MECHANISM_ERRORcsd_datetime_mechanism_error_quark (), |
558 | CSD_DATETIME_MECHANISM_ERROR_GENERAL, |
559 | "Error spawning /sbin/hwclock: %s", error->message); |
560 | g_error_free (error); |
561 | dbus_g_method_return_error (context, error2); |
562 | g_error_free (error2); |
563 | g_free (cmd); |
564 | return FALSE(0); |
565 | } |
566 | g_free (cmd); |
567 | if (WEXITSTATUS (exit_status)(((exit_status) & 0xff00) >> 8) != 0) { |
568 | error = g_error_new (CSD_DATETIME_MECHANISM_ERRORcsd_datetime_mechanism_error_quark (), |
569 | CSD_DATETIME_MECHANISM_ERROR_GENERAL, |
570 | "/sbin/hwclock returned %d", exit_status); |
571 | dbus_g_method_return_error (context, error); |
572 | g_error_free (error); |
573 | return FALSE(0); |
574 | } |
575 | |
576 | if (!_rh_update_etc_sysconfig_clock (context, "UTC=", using_utc ? "true" : "false")) |
577 | return FALSE(0); |
578 | |
579 | } |
580 | dbus_g_method_return (context); |
581 | return TRUE(!(0)); |
582 | } |
583 | |
584 | static void |
585 | check_can_do (CsdDatetimeMechanism *mechanism, |
586 | const char *action, |
587 | DBusGMethodInvocation *context) |
588 | { |
589 | const char *sender; |
590 | PolkitSubject *subject; |
591 | PolkitAuthorizationResult *result; |
592 | GError *error; |
593 | |
594 | /* Check that caller is privileged */ |
595 | sender = dbus_g_method_get_sender (context); |
596 | subject = polkit_system_bus_name_new (sender); |
597 | |
598 | error = NULL((void*)0); |
599 | result = polkit_authority_check_authorization_sync (mechanism->priv->auth, |
600 | subject, |
601 | action, |
602 | NULL((void*)0), |
603 | 0, |
604 | NULL((void*)0), |
605 | &error); |
606 | g_object_unref (subject); |
607 | |
608 | if (error) { |
609 | dbus_g_method_return_error (context, error); |
610 | g_error_free (error); |
611 | return; |
612 | } |
613 | |
614 | if (polkit_authorization_result_get_is_authorized (result)) { |
615 | dbus_g_method_return (context, 2); |
616 | } |
617 | else if (polkit_authorization_result_get_is_challenge (result)) { |
618 | dbus_g_method_return (context, 1); |
619 | } |
620 | else { |
621 | dbus_g_method_return (context, 0); |
622 | } |
623 | |
624 | g_object_unref (result); |
625 | } |
626 | |
627 | |
628 | gboolean |
629 | csd_datetime_mechanism_can_set_time (CsdDatetimeMechanism *mechanism, |
630 | DBusGMethodInvocation *context) |
631 | { |
632 | check_can_do (mechanism, |
633 | "org.cafe.settingsdaemon.datetimemechanism.settime", |
634 | context); |
635 | |
636 | return TRUE(!(0)); |
637 | } |
638 | |
639 | gboolean |
640 | csd_datetime_mechanism_can_set_timezone (CsdDatetimeMechanism *mechanism, |
641 | DBusGMethodInvocation *context) |
642 | { |
643 | check_can_do (mechanism, |
644 | "org.cafe.settingsdaemon.datetimemechanism.settimezone", |
645 | context); |
646 | |
647 | return TRUE(!(0)); |
648 | } |