[evolution-data-server] Bug #649141 - Return only system timezones known to libical
- From: Milan Crha <mcrha src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-data-server] Bug #649141 - Return only system timezones known to libical
- Date: Mon, 30 Jan 2012 13:08:02 +0000 (UTC)
commit d116cf80a9d4ed522c5acd17454ab26e8b3bd725
Author: Milan Crha <mcrha redhat com>
Date: Mon Jan 30 14:06:55 2012 +0100
Bug #649141 - Return only system timezones known to libical
calendar/libecal/e-cal-system-timezone.c | 102 ++++++++++++++++++++++-------
1 files changed, 77 insertions(+), 25 deletions(-)
---
diff --git a/calendar/libecal/e-cal-system-timezone.c b/calendar/libecal/e-cal-system-timezone.c
index 66edf13..3f13e8d 100644
--- a/calendar/libecal/e-cal-system-timezone.c
+++ b/calendar/libecal/e-cal-system-timezone.c
@@ -44,26 +44,26 @@ system_timezone_strip_path_if_valid (const gchar *filename)
{
gint skip;
- if (!filename || !g_str_has_prefix (filename, SYSTEM_ZONEINFODIR"/"))
+ if (!filename || !g_str_has_prefix (filename, SYSTEM_ZONEINFODIR "/"))
return NULL;
/* Timezone data files also live under posix/ and right/ for some
* reason.
* FIXME: make sure accepting those files is valid. I think "posix" is
* okay, not sure about "right" */
- if (g_str_has_prefix (filename, SYSTEM_ZONEINFODIR"/posix/"))
- skip = strlen (SYSTEM_ZONEINFODIR"/posix/");
- else if (g_str_has_prefix (filename, SYSTEM_ZONEINFODIR"/right/"))
- skip = strlen (SYSTEM_ZONEINFODIR"/right/");
+ if (g_str_has_prefix (filename, SYSTEM_ZONEINFODIR "/posix/"))
+ skip = strlen (SYSTEM_ZONEINFODIR "/posix/");
+ else if (g_str_has_prefix (filename, SYSTEM_ZONEINFODIR "/right/"))
+ skip = strlen (SYSTEM_ZONEINFODIR "/right/");
else
- skip = strlen (SYSTEM_ZONEINFODIR"/");
+ skip = strlen (SYSTEM_ZONEINFODIR "/");
return g_strdup (filename + skip);
}
/* Read the soft symlink from /etc/localtime */
static gchar *
-system_timezone_read_etc_localtime_softlink (void)
+system_timezone_read_etc_localtime_softlink (GHashTable *ical_zones)
{
gchar *file;
gchar *tz;
@@ -79,7 +79,7 @@ system_timezone_read_etc_localtime_softlink (void)
}
static gchar *
-system_timezone_read_etc_timezone (void)
+system_timezone_read_etc_timezone (GHashTable *ical_zones)
{
FILE *etc_timezone;
GString *reading;
@@ -169,7 +169,7 @@ system_timezone_read_key_file (const gchar *filename,
/* This works for Fedora and Mandriva */
static gchar *
-system_timezone_read_etc_sysconfig_clock (void)
+system_timezone_read_etc_sysconfig_clock (GHashTable *ical_zones)
{
return system_timezone_read_key_file (ETC_SYSCONFIG_CLOCK,
"ZONE");
@@ -177,7 +177,7 @@ system_timezone_read_etc_sysconfig_clock (void)
/* This works for openSUSE */
static gchar *
-system_timezone_read_etc_sysconfig_clock_alt (void)
+system_timezone_read_etc_sysconfig_clock_alt (GHashTable *ical_zones)
{
return system_timezone_read_key_file (ETC_SYSCONFIG_CLOCK,
"TIMEZONE");
@@ -185,7 +185,7 @@ system_timezone_read_etc_sysconfig_clock_alt (void)
/* This works for Solaris/OpenSolaris */
static gchar *
-system_timezone_read_etc_TIMEZONE (void)
+system_timezone_read_etc_TIMEZONE (GHashTable *ical_zones)
{
return system_timezone_read_key_file (ETC_TIMEZONE_MAJ,
"TZ");
@@ -193,7 +193,7 @@ system_timezone_read_etc_TIMEZONE (void)
/* This works for Arch Linux */
static gchar *
-system_timezone_read_etc_rc_conf (void)
+system_timezone_read_etc_rc_conf (GHashTable *ical_zones)
{
return system_timezone_read_key_file (ETC_RC_CONF,
"TIMEZONE");
@@ -201,7 +201,7 @@ system_timezone_read_etc_rc_conf (void)
/* This works for old Gentoo */
static gchar *
-system_timezone_read_etc_conf_d_clock (void)
+system_timezone_read_etc_conf_d_clock (GHashTable *ical_zones)
{
return system_timezone_read_key_file (ETC_CONF_D_CLOCK,
"TIMEZONE");
@@ -209,10 +209,20 @@ system_timezone_read_etc_conf_d_clock (void)
static void
update_fallback (gchar **fallback,
- gchar *adept)
+ gchar *adept,
+ GHashTable *ical_zones)
{
g_return_if_fail (fallback != NULL);
+ /* ignore those not available in libical */
+ if (adept && ical_zones) {
+ if (!g_hash_table_lookup (ical_zones, adept) ||
+ (*fallback && g_hash_table_lookup (ical_zones, *fallback))) {
+ g_free (adept);
+ return;
+ }
+ }
+
if (!*fallback) {
*fallback = adept;
return;
@@ -241,6 +251,7 @@ recursive_compare (struct stat *localtime_stat,
gsize localtime_content_len,
const gchar *file,
CompareFiles compare_func,
+ GHashTable *ical_zones,
gint deep_level,
gchar **fallback)
{
@@ -255,12 +266,19 @@ recursive_compare (struct stat *localtime_stat,
localtime_content,
localtime_content_len,
file)) {
- if (deep_level <= 1) {
- update_fallback (fallback, system_timezone_strip_path_if_valid (file));
+ gchar *tz = system_timezone_strip_path_if_valid (file);
+
+ if (deep_level <= 1 || (ical_zones && g_hash_table_lookup (ical_zones, tz))) {
+ update_fallback (fallback, tz, ical_zones);
return NULL;
}
- return system_timezone_strip_path_if_valid (file);
+ if (ical_zones && !g_hash_table_lookup (ical_zones, tz)) {
+ g_free (tz);
+ return NULL;
+ }
+
+ return tz;
} else
return NULL;
} else if (S_ISDIR (file_stat.st_mode)) {
@@ -281,6 +299,7 @@ recursive_compare (struct stat *localtime_stat,
localtime_content_len,
subpath,
compare_func,
+ ical_zones,
deep_level + 1,
fallback);
@@ -327,7 +346,7 @@ files_are_identical_inode (struct stat *a_stat,
/* Determine if /etc/localtime is a hard link to some file, by looking at
* the inodes */
static gchar *
-system_timezone_read_etc_localtime_hardlink (void)
+system_timezone_read_etc_localtime_hardlink (GHashTable *ical_zones)
{
struct stat stat_localtime;
gchar *retval, *fallback = NULL;
@@ -343,6 +362,7 @@ system_timezone_read_etc_localtime_hardlink (void)
0,
SYSTEM_ZONEINFODIR,
files_are_identical_inode,
+ ical_zones,
0,
&fallback);
@@ -385,7 +405,7 @@ files_are_identical_content (struct stat *a_stat,
/* Determine if /etc/localtime is a copy of a timezone file */
static gchar *
-system_timezone_read_etc_localtime_content (void)
+system_timezone_read_etc_localtime_content (GHashTable *ical_zones)
{
static gchar *last_localtime_content = NULL;
static gsize last_localtime_content_len = -1;
@@ -433,6 +453,7 @@ system_timezone_read_etc_localtime_content (void)
localtime_content_len,
SYSTEM_ZONEINFODIR,
files_are_identical_content,
+ ical_zones,
0,
&fallback);
@@ -454,7 +475,7 @@ system_timezone_read_etc_localtime_content (void)
return retval;
}
-typedef gchar * (*GetSystemTimezone) (void);
+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[] = {
@@ -476,7 +497,8 @@ static GetSystemTimezone get_system_timezone_methods[] = {
};
static gboolean
-system_timezone_is_valid (const gchar *tz)
+system_timezone_is_valid (const gchar *tz,
+ GHashTable *ical_zones)
{
const gchar *c;
@@ -489,24 +511,51 @@ system_timezone_is_valid (const gchar *tz)
return FALSE;
}
+ if (ical_zones && !g_hash_table_lookup (ical_zones, tz))
+ return FALSE;
+
return TRUE;
}
static gchar *
system_timezone_find (void)
{
+ GHashTable *ical_zones;
+ icalarray *builtin_timezones;
+ gint ii;
gchar *tz;
- gint i;
- for (i = 0; get_system_timezone_methods[i] != NULL; i++) {
- tz = get_system_timezone_methods[i] ();
+ /* return only timezones known to libical */
+ ical_zones = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
+ g_hash_table_insert (ical_zones, g_strdup ("UTC"), GINT_TO_POINTER (1));
+
+ builtin_timezones = icaltimezone_get_builtin_timezones ();
+ for (ii = 0; ii < builtin_timezones->num_elements; ii++) {
+ icaltimezone *zone;
+ const gchar *location;
+
+ zone = icalarray_element_at (builtin_timezones, ii);
+ if (!zone)
+ continue;
+
+ location = icaltimezone_get_location (zone);
+ if (location)
+ g_hash_table_insert (ical_zones, g_strdup (location), GINT_TO_POINTER (1));
+ }
- if (system_timezone_is_valid (tz))
+ for (ii = 0; get_system_timezone_methods[ii] != NULL; ii++) {
+ tz = get_system_timezone_methods[ii] (ical_zones);
+
+ if (system_timezone_is_valid (tz, ical_zones)) {
+ g_hash_table_destroy (ical_zones);
return tz;
+ }
g_free (tz);
}
+ g_hash_table_destroy (ical_zones);
+
return NULL;
}
@@ -791,6 +840,9 @@ system_timezone_win32_query_registry (void)
* Returns system timezone location string, NULL on an error.
* Returned pointer should be freed with g_free().
*
+ * Note: Since 3.4 the returned timezone location is either NULL or
+ * an equivalent within known libical timezones.
+ *
* Since: 2.28
**/
gchar *
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]