commit b296c9298b88294ccbb14b820c028f8a9a30d32b Author: Vincent Untz Date: Wed Jul 20 15:46:14 2011 +0200 datetime: Add NTP support for SUSE variants https://bugzilla.gnome.org/show_bug.cgi?id=654970 diff --git a/plugins/datetime/Makefile.am b/plugins/datetime/Makefile.am index 990eeb6..69032fb 100644 --- a/plugins/datetime/Makefile.am +++ b/plugins/datetime/Makefile.am @@ -26,6 +26,8 @@ gsd_datetime_mechanism_SOURCES = \ gsd-datetime-mechanism-fedora.h \ gsd-datetime-mechanism-debian.c \ gsd-datetime-mechanism-debian.h \ + gsd-datetime-mechanism-suse.c \ + gsd-datetime-mechanism-suse.h \ gsd-datetime-mechanism-main.c \ system-timezone.c \ system-timezone.h diff --git a/plugins/datetime/gsd-datetime-mechanism-suse.c b/plugins/datetime/gsd-datetime-mechanism-suse.c new file mode 100644 index 0000000..ae32045 --- /dev/null +++ b/plugins/datetime/gsd-datetime-mechanism-suse.c @@ -0,0 +1,187 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2007 David Zeuthen + * Copyright (C) 2011 Bastien Nocera + * Copyright (C) 2011 Vincent Untz + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include "gsd-datetime-mechanism-suse.h" +#include "gsd-datetime-mechanism.h" + +gboolean +_get_using_ntp_suse (DBusGMethodInvocation *context) +{ + int exit_status; + GError *error = NULL; + gboolean can_use_ntp; + gboolean is_using_ntp; + + if (g_file_test ("/etc/ntp.conf", G_FILE_TEST_EXISTS)) { + can_use_ntp = TRUE; + if (!g_spawn_command_line_sync ("/sbin/service ntp status", + NULL, NULL, &exit_status, &error)) { + GError *error2; + error2 = g_error_new (GSD_DATETIME_MECHANISM_ERROR, + GSD_DATETIME_MECHANISM_ERROR_GENERAL, + "Error spawning /sbin/service: %s", error->message); + g_error_free (error); + dbus_g_method_return_error (context, error2); + g_error_free (error2); + return FALSE; + } + if (exit_status == 0) + is_using_ntp = TRUE; + else + is_using_ntp = FALSE; + } + else { + can_use_ntp = FALSE; + is_using_ntp = FALSE; + } + + dbus_g_method_return (context, can_use_ntp, is_using_ntp); + return TRUE; +} + +gboolean +_set_using_ntp_suse (DBusGMethodInvocation *context, + gboolean using_ntp) +{ + GError *error; + int exit_status; + char *cmd; + + error = NULL; + + /* We omit --level 2345 so that systemd doesn't try to use the + * SysV init scripts */ + cmd = g_strconcat ("/sbin/chkconfig ntp ", using_ntp ? "on" : "off", NULL); + + if (!g_spawn_command_line_sync (cmd, + NULL, NULL, &exit_status, &error)) { + GError *error2; + error2 = g_error_new (GSD_DATETIME_MECHANISM_ERROR, + GSD_DATETIME_MECHANISM_ERROR_GENERAL, + "Error spawning '%s': %s", cmd, error->message); + g_error_free (error); + dbus_g_method_return_error (context, error2); + g_error_free (error2); + g_free (cmd); + return FALSE; + } + + g_free (cmd); + + cmd = g_strconcat ("/sbin/service ntp ", using_ntp ? "restart" : "stop", NULL);; + + if (!g_spawn_command_line_sync (cmd, + NULL, NULL, &exit_status, &error)) { + GError *error2; + error2 = g_error_new (GSD_DATETIME_MECHANISM_ERROR, + GSD_DATETIME_MECHANISM_ERROR_GENERAL, + "Error spawning '%s': %s", cmd, error->message); + g_error_free (error); + dbus_g_method_return_error (context, error2); + g_error_free (error2); + g_free (cmd); + return FALSE; + } + + g_free (cmd); + + dbus_g_method_return (context); + return TRUE; +} + +gboolean +_update_etc_sysconfig_clock_suse (DBusGMethodInvocation *context, const char *key, const char *value) +{ + char **lines; + int n; + gboolean replaced; + char *data; + gsize len; + GError *error; + + /* On SUSE variants, the /etc/sysconfig/clock file needs to be kept in sync */ + if (!g_file_test ("/etc/sysconfig/clock", G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR)) { + error = g_error_new (GSD_DATETIME_MECHANISM_ERROR, + GSD_DATETIME_MECHANISM_ERROR_GENERAL, + "Error reading /etc/sysconfig/clock file: %s", "No such file"); + dbus_g_method_return_error (context, error); + g_error_free (error); + return FALSE; + } + + error = NULL; + + if (!g_file_get_contents ("/etc/sysconfig/clock", &data, &len, &error)) { + GError *error2; + error2 = g_error_new (GSD_DATETIME_MECHANISM_ERROR, + GSD_DATETIME_MECHANISM_ERROR_GENERAL, + "Error reading /etc/sysconfig/clock file: %s", error->message); + g_error_free (error); + dbus_g_method_return_error (context, error2); + g_error_free (error2); + return FALSE; + } + replaced = FALSE; + lines = g_strsplit (data, "\n", 0); + g_free (data); + + for (n = 0; lines[n] != NULL; n++) { + if (g_str_has_prefix (lines[n], key)) { + g_free (lines[n]); + lines[n] = g_strdup_printf ("%s%s", key, value); + replaced = TRUE; + } + } + if (replaced) { + GString *str; + + str = g_string_new (NULL); + for (n = 0; lines[n] != NULL; n++) { + g_string_append (str, lines[n]); + if (lines[n + 1] != NULL) + g_string_append_c (str, '\n'); + } + data = g_string_free (str, FALSE); + len = strlen (data); + if (!g_file_set_contents ("/etc/sysconfig/clock", data, len, &error)) { + GError *error2; + error2 = g_error_new (GSD_DATETIME_MECHANISM_ERROR, + GSD_DATETIME_MECHANISM_ERROR_GENERAL, + "Error updating /etc/sysconfig/clock: %s", error->message); + g_error_free (error); + dbus_g_method_return_error (context, error2); + g_error_free (error2); + g_free (data); + return FALSE; + } + g_free (data); + } + g_strfreev (lines); + + return TRUE; +} diff --git a/plugins/datetime/gsd-datetime-mechanism-suse.h b/plugins/datetime/gsd-datetime-mechanism-suse.h new file mode 100644 index 0000000..a228597 --- /dev/null +++ b/plugins/datetime/gsd-datetime-mechanism-suse.h @@ -0,0 +1,32 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2007 David Zeuthen + * Copyright (C) 2011 Bastien Nocera + * Copyright (C) 2011 Vincent Untz + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + */ + +#include +#include + +gboolean _get_using_ntp_suse (DBusGMethodInvocation *context); +gboolean _set_using_ntp_suse (DBusGMethodInvocation *context, + gboolean using_ntp); +gboolean _update_etc_sysconfig_clock_suse + (DBusGMethodInvocation *context, + const char *key, + const char *value); diff --git a/plugins/datetime/gsd-datetime-mechanism.c b/plugins/datetime/gsd-datetime-mechanism.c index c46c7f2..61d195f 100644 --- a/plugins/datetime/gsd-datetime-mechanism.c +++ b/plugins/datetime/gsd-datetime-mechanism.c @@ -47,6 +47,7 @@ /* NTP helper functions for various distributions */ #include "gsd-datetime-mechanism-fedora.h" #include "gsd-datetime-mechanism-debian.h" +#include "gsd-datetime-mechanism-suse.h" static gboolean do_exit (gpointer user_data) @@ -625,9 +626,13 @@ gsd_datetime_mechanism_set_hardware_clock_using_utc (GsdDatetimeMechanism *mech return FALSE; } - if (g_file_test ("/etc/fedora-release", G_FILE_TEST_EXISTS)) /* Fedora */ + if (g_file_test ("/etc/fedora-release", G_FILE_TEST_EXISTS)) { /* Fedora */ if (!_update_etc_sysconfig_clock_fedora (context, "UTC=", using_utc ? "true" : "false")) return FALSE; + } else if (g_file_test ("/etc/SuSE-release", G_FILE_TEST_EXISTS)) { /* SUSE variant */ + if (!_update_etc_sysconfig_clock_suse (context, "HWCLOCK=", using_utc ? "-u" : "--localtime")) + return FALSE; + } } dbus_g_method_return (context); return TRUE; @@ -644,6 +649,8 @@ gsd_datetime_mechanism_get_using_ntp (GsdDatetimeMechanism *mechanism, ret = _get_using_ntp_fedora (context); else if (g_file_test ("/usr/sbin/update-rc.d", G_FILE_TEST_EXISTS)) /* Debian */ ret = _get_using_ntp_debian (context); + else if (g_file_test ("/etc/SuSE-release", G_FILE_TEST_EXISTS)) /* SUSE variant */ + ret = _get_using_ntp_suse (context); else { error = g_error_new (GSD_DATETIME_MECHANISM_ERROR, GSD_DATETIME_MECHANISM_ERROR_GENERAL, @@ -673,6 +680,8 @@ gsd_datetime_mechanism_set_using_ntp (GsdDatetimeMechanism *mechanism, ret = _set_using_ntp_fedora (context, using_ntp); else if (g_file_test ("/usr/sbin/update-rc.d", G_FILE_TEST_EXISTS)) /* Debian */ ret = _set_using_ntp_debian (context, using_ntp); + else if (g_file_test ("/etc/SuSE-release", G_FILE_TEST_EXISTS)) /* SUSE variant */ + ret = _set_using_ntp_suse (context, using_ntp); else { error = g_error_new (GSD_DATETIME_MECHANISM_ERROR, GSD_DATETIME_MECHANISM_ERROR_GENERAL,