[evolution-data-server/gnome-3-4] GN-bug #680687 - System timezone name differs from set in Gnome
- From: Milan Crha <mcrha src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-data-server/gnome-3-4] GN-bug #680687 - System timezone name differs from set in Gnome
- Date: Fri, 27 Jul 2012 10:37:44 +0000 (UTC)
commit c9a8627fb9a9f1d1086527f5823c9e757f5e0147
Author: Milan Crha <mcrha redhat com>
Date: Fri Jul 27 12:37:20 2012 +0200
GN-bug #680687 - System timezone name differs from set in Gnome
calendar/libecal/e-cal-system-timezone.c | 95 +++++++++++++++++++++++++-----
1 files changed, 80 insertions(+), 15 deletions(-)
---
diff --git a/calendar/libecal/e-cal-system-timezone.c b/calendar/libecal/e-cal-system-timezone.c
index bf7d523..dd51836 100644
--- a/calendar/libecal/e-cal-system-timezone.c
+++ b/calendar/libecal/e-cal-system-timezone.c
@@ -412,10 +412,10 @@ system_timezone_read_etc_localtime_content (GHashTable *ical_zones)
static gchar *last_timezone = NULL;
static GStaticRecMutex mutex = G_STATIC_REC_MUTEX_INIT;
- struct stat stat_localtime;
- gchar *localtime_content = NULL;
- gsize localtime_content_len = -1;
- gchar *retval, *fallback = NULL;
+ struct stat stat_localtime;
+ gchar *localtime_content = NULL;
+ gsize localtime_content_len = -1;
+ gchar *retval, *fallback = NULL;
if (g_stat (ETC_LOCALTIME, &stat_localtime) != 0)
return NULL;
@@ -478,13 +478,7 @@ system_timezone_read_etc_localtime_content (GHashTable *ical_zones)
typedef gchar * (*GetSystemTimezone) (GHashTable *ical_zones);
/* The order of the functions here define the priority of the methods used
* to find the timezone. First method has higher priority. */
-static GetSystemTimezone get_system_timezone_methods[] = {
- /* cheap and "more correct" than data from a config file */
- system_timezone_read_etc_localtime_softlink,
- /* reading /etc/timezone directly. Expensive since we have to stat
- * many files, but it returns always correct values, even on KDE */
- system_timezone_read_etc_localtime_content,
- system_timezone_read_etc_localtime_hardlink,
+static GetSystemTimezone get_system_timezone_methods_config[] = {
/* reading various config files */
system_timezone_read_etc_timezone,
system_timezone_read_etc_sysconfig_clock,
@@ -496,6 +490,14 @@ static GetSystemTimezone get_system_timezone_methods[] = {
NULL
};
+static GetSystemTimezone get_system_timezone_methods_slow[] = {
+ /* reading /etc/timezone directly. Expensive since we have to stat
+ * many files, but it returns always correct values, even on KDE */
+ system_timezone_read_etc_localtime_content,
+ system_timezone_read_etc_localtime_hardlink,
+ NULL
+};
+
static gboolean
system_timezone_is_valid (const gchar *tz,
GHashTable *ical_zones)
@@ -523,7 +525,7 @@ system_timezone_find (void)
GHashTable *ical_zones;
icalarray *builtin_timezones;
gint ii;
- gchar *tz;
+ gchar *tz, *config_tz = NULL;
/* return only timezones known to libical */
ical_zones = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
@@ -543,11 +545,74 @@ system_timezone_find (void)
g_hash_table_insert (ical_zones, g_strdup (location), GINT_TO_POINTER (1));
}
- for (ii = 0; get_system_timezone_methods[ii] != NULL; ii++) {
- tz = get_system_timezone_methods[ii] (ical_zones);
+ /* softlink is the best option, it points to the correct file */
+ tz = system_timezone_read_etc_localtime_softlink (ical_zones);
+ if (system_timezone_is_valid (tz, ical_zones)) {
+ g_hash_table_destroy (ical_zones);
+ return tz;
+ }
+
+ g_free (tz);
+
+ config_tz = NULL;
+
+ /* read correct timezone name from config file; checking
+ on /etc/localtime content can pick wrong timezone name,
+ even the file is same
+ */
+ for (ii = 0; get_system_timezone_methods_config[ii] != NULL; ii++) {
+ config_tz = get_system_timezone_methods_config[ii] (ical_zones);
+
+ if (system_timezone_is_valid (config_tz, ical_zones)) {
+ break;
+ }
+
+ g_free (config_tz);
+ config_tz = NULL;
+ }
+
+ if (config_tz) {
+ struct stat stat_localtime;
+ gchar *localtime_content = NULL;
+ gsize localtime_content_len = -1;
+
+ if (g_stat (ETC_LOCALTIME, &stat_localtime) == 0 &&
+ S_ISREG (stat_localtime.st_mode) &&
+ g_file_get_contents (ETC_LOCALTIME,
+ &localtime_content,
+ &localtime_content_len,
+ NULL)) {
+ struct stat stat_config_tz;
+ gchar *filename = g_build_filename (SYSTEM_ZONEINFODIR, config_tz, NULL);
+
+ if (filename &&
+ g_stat (filename, &stat_config_tz) == 0 &&
+ files_are_identical_content (&stat_localtime,
+ &stat_config_tz,
+ localtime_content,
+ localtime_content_len,
+ filename)) {
+ g_free (filename);
+ g_free (localtime_content);
+
+ /* corresponding file name to config_tz matches /etc/localtime,
+ thus that's the correct one - return it as system timezone;
+ bonus is that it might match configured system timezone name too
+ */
+ return config_tz;
+ }
+ g_free (filename);
+ }
+
+ g_free (localtime_content);
+ }
+
+ for (ii = 0; get_system_timezone_methods_slow[ii] != NULL; ii++) {
+ tz = get_system_timezone_methods_slow[ii] (ical_zones);
if (system_timezone_is_valid (tz, ical_zones)) {
g_hash_table_destroy (ical_zones);
+ g_free (config_tz);
return tz;
}
@@ -556,7 +621,7 @@ system_timezone_find (void)
g_hash_table_destroy (ical_zones);
- return NULL;
+ return config_tz;
}
#else /* G_OS_WIN32 */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]