[evolution-mapi] Bug #669817 - Events using incorrect timezone



commit 5de567e2847583171d7e767e4b18683c1123579c
Author: Milan Crha <mcrha redhat com>
Date:   Thu Feb 23 19:11:20 2012 +0100

    Bug #669817 - Events using incorrect timezone

 src/libexchangemapi/e-mapi-cal-tz-utils.c |   94 +++++++++++++++++++++++++++++
 src/libexchangemapi/e-mapi-cal-tz-utils.h |    2 +
 src/libexchangemapi/e-mapi-cal-utils.c    |   14 ++++-
 3 files changed, 109 insertions(+), 1 deletions(-)
---
diff --git a/src/libexchangemapi/e-mapi-cal-tz-utils.c b/src/libexchangemapi/e-mapi-cal-tz-utils.c
index 23addbc..689311d 100644
--- a/src/libexchangemapi/e-mapi-cal-tz-utils.c
+++ b/src/libexchangemapi/e-mapi-cal-tz-utils.c
@@ -80,6 +80,100 @@ e_mapi_cal_tz_util_get_ical_equivalent (const gchar *mapi_tz_location)
 	return retval;
 }
 
+static struct icaltimetype
+tm_to_icaltimetype (struct tm *tm,
+		    gboolean dst)
+{
+	struct icaltimetype itt;
+
+	memset (&itt, 0, sizeof (struct icaltimetype));
+
+	itt.second = 0;
+	itt.minute = 0;
+	itt.hour = 0;
+
+	itt.day = 1;
+	itt.month = dst ? 6 : 1;
+	itt.year = tm->tm_year + 1900;
+
+	itt.is_utc = 0;
+	itt.is_date = 0;
+
+	return itt;
+}
+
+static gint
+get_offset (icaltimezone *zone,
+	    gboolean dst)
+{
+	struct tm local;
+	struct icaltimetype tt;
+	gint offset;
+	time_t now = time (NULL);
+
+	gmtime_r (&now, &local);
+	tt = tm_to_icaltimetype (&local, dst);
+	offset = icaltimezone_get_utc_offset (zone, &tt, NULL);
+
+	return offset / -60;
+}
+
+const gchar *
+e_mapi_cal_tz_util_ical_from_zone_struct (const guint8 *lpb,
+					  guint32 cb)
+{
+	GHashTableIter iter;
+	gpointer key, value;
+	guint32 utcBias, stdBias, dstBias;
+	const gchar *res = NULL;
+
+	g_return_val_if_fail (lpb != NULL, NULL);
+
+	/* get the timezone by biases, which are the first 3*4 bytes */
+	if (cb < 12)
+		return NULL;
+
+	memcpy (&utcBias, lpb, 4); lpb += 4;
+	memcpy (&stdBias, lpb, 4); lpb += 4;
+	memcpy (&dstBias, lpb, 4); lpb += 4;
+
+	g_static_rec_mutex_lock (&mutex);
+	if (!e_mapi_cal_tz_util_populate ()) {
+		g_static_rec_mutex_unlock (&mutex);
+		return NULL;
+	}
+
+	g_hash_table_iter_init (&iter, mapi_to_ical);
+	while (g_hash_table_iter_next (&iter, &key, &value)) {
+		const gchar *location = value;
+		icaltimezone *zone;
+		gint offset;
+
+		zone = icaltimezone_get_builtin_timezone (location);
+		if (!zone)
+			continue;
+
+		offset = get_offset (zone, FALSE);
+		if (offset != utcBias || offset != utcBias + stdBias)
+			continue;
+
+		offset = get_offset (zone, TRUE);
+		if (offset != utcBias + dstBias)
+			continue;
+
+		/* pick shortest and alphabetically first timezone */
+		if (!res ||
+		    strlen (res) > strlen (location) ||
+		    (strlen (res) == strlen (location) &&
+		    strcmp (location, res) < 0))
+			res = location;
+	}
+
+	g_static_rec_mutex_unlock (&mutex);
+
+	return res;
+}
+
 void
 e_mapi_cal_tz_util_destroy (void)
 {
diff --git a/src/libexchangemapi/e-mapi-cal-tz-utils.h b/src/libexchangemapi/e-mapi-cal-tz-utils.h
index 9db6596..ba06d51 100644
--- a/src/libexchangemapi/e-mapi-cal-tz-utils.h
+++ b/src/libexchangemapi/e-mapi-cal-tz-utils.h
@@ -32,6 +32,8 @@ G_BEGIN_DECLS
 
 const gchar *	e_mapi_cal_tz_util_get_mapi_equivalent	(const gchar *ical_tz_location);
 const gchar *	e_mapi_cal_tz_util_get_ical_equivalent	(const gchar *mapi_tz_location);
+const gchar *	e_mapi_cal_tz_util_ical_from_zone_struct(const guint8 *lpb,
+							 guint32 cb);
 gboolean	e_mapi_cal_tz_util_populate		(void);
 void		e_mapi_cal_tz_util_destroy		(void);
 void		e_mapi_cal_tz_util_dump			(void);
diff --git a/src/libexchangemapi/e-mapi-cal-utils.c b/src/libexchangemapi/e-mapi-cal-utils.c
index 6ebce46..66e86c1 100644
--- a/src/libexchangemapi/e-mapi-cal-utils.c
+++ b/src/libexchangemapi/e-mapi-cal-utils.c
@@ -1003,7 +1003,7 @@ e_mapi_cal_util_object_to_comp (EMapiConnection *conn,
 		if (location && *location)
 			icalcomponent_set_location (ical_comp, location);
 
-		b = e_mapi_util_find_array_propval (&object->properties, PidLidAppointmentSubType);;
+		b = e_mapi_util_find_array_propval (&object->properties, PidLidAppointmentSubType);
 		all_day = b && *b;
 
 		bin = e_mapi_util_find_array_propval (&object->properties, PidLidAppointmentTimeZoneDefinitionStartDisplay);
@@ -1013,6 +1013,12 @@ e_mapi_cal_util_object_to_comp (EMapiConnection *conn,
 			g_free (buf);
 		}
 
+		if (!dtstart_tz_location) {
+			bin = e_mapi_util_find_array_propval (&object->properties, PidLidTimeZoneStruct);
+			if (bin)
+				dtstart_tz_location = e_mapi_cal_tz_util_ical_from_zone_struct (bin->lpb, bin->cb);
+		}
+
 		if (e_mapi_util_find_array_datetime_propval (&t, &object->properties, PidLidAppointmentStartWhole) == MAPI_E_SUCCESS) {
 			icaltimezone *zone = dtstart_tz_location ? icaltimezone_get_builtin_timezone (dtstart_tz_location) : utc_zone;
 			prop = icalproperty_new_dtstart (icaltime_from_timet_with_zone (t.tv_sec, all_day, zone));
@@ -1030,6 +1036,12 @@ e_mapi_cal_util_object_to_comp (EMapiConnection *conn,
 			g_free (buf);
 		}
 
+		if (!dtend_tz_location) {
+			bin = e_mapi_util_find_array_propval (&object->properties, PidLidTimeZoneStruct);
+			if (bin)
+				dtend_tz_location = e_mapi_cal_tz_util_ical_from_zone_struct (bin->lpb, bin->cb);
+		}
+
 		if (e_mapi_util_find_array_datetime_propval (&t, &object->properties, PidLidAppointmentEndWhole) == MAPI_E_SUCCESS) {
 			icaltimezone *zone;
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]