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