evolution-data-server r9086 - in branches/EXCHANGE_MAPI_BRANCH: calendar/backends/mapi servers/mapi
- From: msuman svn gnome org
- To: svn-commits-list gnome org
- Subject: evolution-data-server r9086 - in branches/EXCHANGE_MAPI_BRANCH: calendar/backends/mapi servers/mapi
- Date: Thu, 3 Jul 2008 08:02:54 +0000 (UTC)
Author: msuman
Date: Thu Jul 3 08:02:54 2008
New Revision: 9086
URL: http://svn.gnome.org/viewvc/evolution-data-server?rev=9086&view=rev
Log:
MAPI - Move the calendar utility files to servers.
Added:
branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-cal-recur-utils.c
branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-cal-recur-utils.h
branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-cal-tz-utils.c
branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-cal-tz-utils.h
branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-cal-utils.c
branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-cal-utils.h
branches/EXCHANGE_MAPI_BRANCH/servers/mapi/tz-ical-to-mapi
branches/EXCHANGE_MAPI_BRANCH/servers/mapi/tz-mapi-to-ical
Removed:
branches/EXCHANGE_MAPI_BRANCH/calendar/backends/mapi/e-cal-backend-mapi-recur-utils.c
branches/EXCHANGE_MAPI_BRANCH/calendar/backends/mapi/e-cal-backend-mapi-recur-utils.h
branches/EXCHANGE_MAPI_BRANCH/calendar/backends/mapi/e-cal-backend-mapi-tz-utils.c
branches/EXCHANGE_MAPI_BRANCH/calendar/backends/mapi/e-cal-backend-mapi-tz-utils.h
branches/EXCHANGE_MAPI_BRANCH/calendar/backends/mapi/e-cal-backend-mapi-utils.c
branches/EXCHANGE_MAPI_BRANCH/calendar/backends/mapi/e-cal-backend-mapi-utils.h
branches/EXCHANGE_MAPI_BRANCH/calendar/backends/mapi/tz-ical-to-mapi
branches/EXCHANGE_MAPI_BRANCH/calendar/backends/mapi/tz-mapi-to-ical
Modified:
branches/EXCHANGE_MAPI_BRANCH/calendar/backends/mapi/ChangeLog
branches/EXCHANGE_MAPI_BRANCH/calendar/backends/mapi/Makefile.am
branches/EXCHANGE_MAPI_BRANCH/calendar/backends/mapi/e-cal-backend-mapi-factory.c
branches/EXCHANGE_MAPI_BRANCH/calendar/backends/mapi/e-cal-backend-mapi.c
branches/EXCHANGE_MAPI_BRANCH/calendar/backends/mapi/e-cal-backend-mapi.h
branches/EXCHANGE_MAPI_BRANCH/servers/mapi/ChangeLog
branches/EXCHANGE_MAPI_BRANCH/servers/mapi/Makefile.am
Modified: branches/EXCHANGE_MAPI_BRANCH/calendar/backends/mapi/Makefile.am
==============================================================================
--- branches/EXCHANGE_MAPI_BRANCH/calendar/backends/mapi/Makefile.am (original)
+++ branches/EXCHANGE_MAPI_BRANCH/calendar/backends/mapi/Makefile.am Thu Jul 3 08:02:54 2008
@@ -10,25 +10,16 @@
-I$(top_builddir)/libical/src/libical \
-I$(top_srcdir)/servers/mapi \
-I$(top_builddir)/servers/mapi \
- -DMAPI_DATADIR=\""$(mapidatadir)"\" \
$(EVOLUTION_CALENDAR_CFLAGS) \
$(LIBMAPI_CFLAGS)
extension_LTLIBRARIES = libecalbackendmapi.la
-mapidata_DATA = \
- tz-mapi-to-ical \
- tz-ical-to-mapi
-
libecalbackendmapi_la_SOURCES = \
e-cal-backend-mapi-factory.c \
e-cal-backend-mapi-factory.h \
e-cal-backend-mapi.c \
- e-cal-backend-mapi.h \
- e-cal-backend-mapi-utils.c \
- e-cal-backend-mapi-utils.h \
- e-cal-backend-mapi-tz-utils.c \
- e-cal-backend-mapi-tz-utils.h
+ e-cal-backend-mapi.h
libecalbackendmapi_la_LIBADD = \
$(top_builddir)/calendar/libecal/libecal-1.2.la \
@@ -42,5 +33,3 @@
libecalbackendmapi_la_LDFLAGS = \
-module -avoid-version $(NO_UNDEFINED)
-EXTRA_DIST = \
- $(mapidata_DATA)
Modified: branches/EXCHANGE_MAPI_BRANCH/calendar/backends/mapi/e-cal-backend-mapi-factory.c
==============================================================================
--- branches/EXCHANGE_MAPI_BRANCH/calendar/backends/mapi/e-cal-backend-mapi-factory.c (original)
+++ branches/EXCHANGE_MAPI_BRANCH/calendar/backends/mapi/e-cal-backend-mapi-factory.c Thu Jul 3 08:02:54 2008
@@ -29,7 +29,7 @@
#include "e-cal-backend-mapi-factory.h"
#include "e-cal-backend-mapi.h"
-#include "e-cal-backend-mapi-tz-utils.h"
+
#define d(x)
typedef struct {
@@ -205,14 +205,14 @@
mapi_types[1] = events_backend_factory_get_type (module);
mapi_types[2] = journal_backend_factory_get_type (module);
- e_cal_backend_mapi_tz_util_populate ();
- d(e_cal_backend_mapi_tz_util_dump ());
+ exchange_mapi_cal_tz_util_populate ();
+ d(exchange_mapi_cal_tz_util_dump ());
}
void
eds_module_shutdown (void)
{
- e_cal_backend_mapi_tz_util_destroy ();
+ exchange_mapi_cal_tz_util_destroy ();
}
void
Modified: branches/EXCHANGE_MAPI_BRANCH/calendar/backends/mapi/e-cal-backend-mapi.c
==============================================================================
--- branches/EXCHANGE_MAPI_BRANCH/calendar/backends/mapi/e-cal-backend-mapi.c (original)
+++ branches/EXCHANGE_MAPI_BRANCH/calendar/backends/mapi/e-cal-backend-mapi.c Thu Jul 3 08:02:54 2008
@@ -27,7 +27,7 @@
#include <gio/gio.h>
#include "e-cal-backend-mapi.h"
-#include "e-cal-backend-mapi-utils.h"
+
#define d(x) x
#ifdef G_OS_WIN32
@@ -346,59 +346,13 @@
return GNOME_Evolution_Calendar_Success;
}
-/* we don't have to specify the PR_BODY_* tags since it is fetched by default */
-static const uint32_t GetPropsList[] = {
- PR_FID,
- PR_MID,
- PR_SUBJECT,
- PR_SUBJECT_UNICODE,
- PR_SUBJECT_ERROR,
- PR_NORMALIZED_SUBJECT,
- PR_NORMALIZED_SUBJECT_UNICODE,
- PR_NORMALIZED_SUBJECT_ERROR,
- PR_CREATION_TIME,
- PR_LAST_MODIFICATION_TIME,
- PR_PRIORITY,
- PR_SENSITIVITY,
- PR_START_DATE,
- PR_END_DATE,
- PR_RESPONSE_REQUESTED,
-
- PR_SENT_REPRESENTING_NAME,
- PR_SENT_REPRESENTING_NAME_UNICODE,
- PR_SENT_REPRESENTING_ADDRTYPE,
- PR_SENT_REPRESENTING_ADDRTYPE_UNICODE,
- PR_SENT_REPRESENTING_EMAIL_ADDRESS,
- PR_SENT_REPRESENTING_EMAIL_ADDRESS_UNICODE,
-
- PR_SENDER_NAME,
- PR_SENDER_NAME_UNICODE,
- PR_SENDER_ADDRTYPE,
- PR_SENDER_ADDRTYPE_UNICODE,
- PR_SENDER_EMAIL_ADDRESS,
- PR_SENDER_EMAIL_ADDRESS_UNICODE,
-
- PR_RCVD_REPRESENTING_NAME,
- PR_RCVD_REPRESENTING_NAME_UNICODE,
- PR_RCVD_REPRESENTING_ADDRTYPE,
- PR_RCVD_REPRESENTING_ADDRTYPE_UNICODE,
- PR_RCVD_REPRESENTING_EMAIL_ADDRESS,
- PR_RCVD_REPRESENTING_EMAIL_ADDRESS_UNICODE
-};
-static const uint16_t n_GetPropsList = G_N_ELEMENTS (GetPropsList);
-
-static const uint32_t IDList[] = {
- PR_FID,
- PR_MID
-};
-static const uint16_t n_IDList = G_N_ELEMENTS (IDList);
-
static gboolean
mapi_cal_get_changes_cb (struct mapi_SPropValue_array *array, const mapi_id_t fid, const mapi_id_t mid,
GSList *streams, GSList *recipients, GSList *attachments, gpointer data)
{
ECalBackendMAPI *cbmapi = data;
ECalBackendMAPIPrivate *priv = cbmapi->priv;
+ icalcomponent_kind kind = e_cal_backend_get_kind (E_CAL_BACKEND (cbmapi));
gchar *tmp = NULL;
ECalComponent *cache_comp = NULL;
const bool *recurring;
@@ -431,7 +385,9 @@
cache_comp = e_cal_backend_cache_get_component (priv->cache, tmp, NULL);
if (cache_comp == NULL) {
- ECalComponent *comp = e_cal_backend_mapi_props_to_comp (cbmapi, tmp, array, streams, recipients, attachments, priv->default_zone);
+ ECalComponent *comp = exchange_mapi_cal_util_mapi_props_to_comp (kind, tmp, array,
+ streams, recipients, attachments,
+ priv->local_attachments_store, priv->default_zone);
if (E_IS_CAL_COMPONENT (comp)) {
char *comp_str;
@@ -462,8 +418,9 @@
e_cal_component_commit_sequence (cache_comp);
cache_comp_str = e_cal_component_get_as_string (cache_comp);
- comp = e_cal_backend_mapi_props_to_comp (cbmapi, tmp, array,
- streams, recipients, attachments, priv->default_zone);
+ comp = exchange_mapi_cal_util_mapi_props_to_comp (kind, tmp, array,
+ streams, recipients, attachments,
+ priv->local_attachments_store, priv->default_zone);
e_cal_component_commit_sequence (comp);
modif_comp_str = e_cal_component_get_as_string (comp);
@@ -533,8 +490,8 @@
return FALSE;
cbmapi = (ECalBackendMAPI *) handle;
- kind = e_cal_backend_get_kind (E_CAL_BACKEND (cbmapi));
priv= cbmapi->priv;
+ kind = e_cal_backend_get_kind (E_CAL_BACKEND (cbmapi));
if (priv->mode == CAL_MODE_LOCAL)
return FALSE;
@@ -566,8 +523,8 @@
// e_file_cache_freeze_changes (E_FILE_CACHE (priv->cache));
if (!exchange_mapi_connection_fetch_items (priv->fid, use_restriction ? &res : NULL,
- GetPropsList, n_GetPropsList,
- mapi_cal_build_name_id, cbmapi,
+ cal_GetPropsList, n_cal_GetPropsList,
+ exchange_mapi_cal_util_build_name_id, GINT_TO_POINTER(kind),
mapi_cal_get_changes_cb, cbmapi,
MAPI_OPTIONS_FETCH_ALL)) {
/* FIXME: better string please... */
@@ -590,7 +547,7 @@
* so should not be freed, only the list should. */
priv->cache_keys = e_cal_backend_cache_get_keys (priv->cache);
if (!exchange_mapi_connection_fetch_items (priv->fid, NULL,
- IDList, n_IDList,
+ cal_IDList, n_cal_IDList,
NULL, NULL,
handle_deleted_items_cb, cbmapi,
0)) {
@@ -863,13 +820,14 @@
{
ECalBackendMAPI *cbmapi = E_CAL_BACKEND_MAPI (data);
ECalBackendMAPIPrivate *priv = cbmapi->priv;
+ icalcomponent_kind kind = e_cal_backend_get_kind (E_CAL_BACKEND (cbmapi));
ECalComponent *comp = NULL;
gchar *tmp = NULL;
const bool *recurring = NULL;
// exchange_mapi_debug_property_dump (properties);
- switch (e_cal_backend_get_kind (E_CAL_BACKEND (cbmapi))) {
+ switch (kind) {
case ICAL_VEVENT_COMPONENT:
/* FIXME: Provide backend support for recurrence */
recurring = (const bool *)find_mapi_SPropValue_data(properties, PROP_TAG(PT_BOOLEAN, 0x8223));
@@ -899,7 +857,9 @@
}
tmp = exchange_mapi_util_mapi_id_to_string (mid);
- comp = e_cal_backend_mapi_props_to_comp (cbmapi, tmp, properties, streams, recipients, attachments, priv->default_zone);
+ comp = exchange_mapi_cal_util_mapi_props_to_comp (kind, tmp, properties,
+ streams, recipients, attachments,
+ priv->local_attachments_store, priv->default_zone);
g_free (tmp);
if (E_IS_CAL_COMPONENT (comp)) {
@@ -948,8 +908,8 @@
// e_file_cache_freeze_changes (E_FILE_CACHE (priv->cache));
if (!exchange_mapi_connection_fetch_items (priv->fid, NULL,
- GetPropsList, n_GetPropsList,
- mapi_cal_build_name_id, cbmapi,
+ cal_GetPropsList, n_cal_GetPropsList,
+ exchange_mapi_cal_util_build_name_id, GINT_TO_POINTER(kind),
mapi_cal_cache_create_cb, cbmapi,
MAPI_OPTIONS_FETCH_ALL)) {
e_cal_backend_notify_error (E_CAL_BACKEND (cbmapi), _("Could not create cache file"));
@@ -1222,6 +1182,7 @@
{
ECalBackendMAPI *cbmapi;
ECalBackendMAPIPrivate *priv;
+ icalcomponent_kind kind;
icalcomponent *icalcomp;
ECalComponent *comp;
mapi_id_t mid = 0;
@@ -1232,6 +1193,7 @@
cbmapi = E_CAL_BACKEND_MAPI (backend);
priv = cbmapi->priv;
+ kind = e_cal_backend_get_kind (E_CAL_BACKEND (backend));
g_return_val_if_fail (E_IS_CAL_BACKEND_MAPI (cbmapi), GNOME_Evolution_Calendar_InvalidObject);
g_return_val_if_fail (calobj != NULL && *calobj != NULL, GNOME_Evolution_Calendar_InvalidObject);
@@ -1244,7 +1206,7 @@
if (!icalcomp)
return GNOME_Evolution_Calendar_InvalidObject;
- if (e_cal_backend_get_kind (E_CAL_BACKEND (backend)) != icalcomponent_isa (icalcomp)) {
+ if (kind != icalcomponent_isa (icalcomp)) {
icalcomponent_free (icalcomp);
return GNOME_Evolution_Calendar_InvalidObject;
}
@@ -1260,22 +1222,29 @@
/* FIXME: [WIP] Add support for meetings/assigned tasks */
if (e_cal_component_has_attendees (comp))
- e_cal_backend_mapi_util_fetch_recipients (cbmapi, comp, &recipients);
+ exchange_mapi_cal_util_fetch_recipients (comp, &recipients);
if (e_cal_component_has_attachments (comp))
- e_cal_backend_mapi_util_fetch_attachments (cbmapi, comp, &attachments);
+ exchange_mapi_cal_util_fetch_attachments (comp, &attachments, priv->local_attachments_store);
+
+ cbdata.username = e_cal_backend_mapi_get_user_name (cbmapi);
+ cbdata.userid = e_cal_backend_mapi_get_user_email (cbmapi);
+ cbdata.ownername = e_cal_backend_mapi_get_owner_name (cbmapi);
+ cbdata.ownerid = e_cal_backend_mapi_get_owner_email (cbmapi);
/* Check if object exists */
switch (priv->mode) {
case CAL_MODE_ANY:
case CAL_MODE_REMOTE:
/* Create an appointment */
- cbdata.cbmapi = cbmapi;
cbdata.comp = comp;
cbdata.meeting_type = (recipients != NULL) ? MEETING_OBJECT : NOT_A_MEETING;
cbdata.msgflags = MSGFLAG_READ;
cbdata.new_appt_id = get_new_appt_id (cbmapi);
- mid = exchange_mapi_create_item (priv->olFolder, priv->fid, mapi_cal_build_name_id, cbmapi, mapi_cal_build_props, &cbdata, recipients, attachments, NULL, MAPI_OPTIONS_DONT_SUBMIT);
+ mid = exchange_mapi_create_item (priv->olFolder, priv->fid,
+ exchange_mapi_cal_util_build_name_id, GINT_TO_POINTER(kind),
+ exchange_mapi_cal_util_build_props, &cbdata,
+ recipients, attachments, NULL, MAPI_OPTIONS_DONT_SUBMIT);
if (!mid) {
g_object_unref (comp);
exchange_mapi_util_free_recipient_list (&recipients);
@@ -1309,6 +1278,7 @@
{
ECalBackendMAPI *cbmapi;
ECalBackendMAPIPrivate *priv;
+ icalcomponent_kind kind;
icalcomponent *icalcomp;
ECalComponent *comp, *cache_comp = NULL;
gboolean status;
@@ -1323,6 +1293,7 @@
*old_object = *new_object = NULL;
cbmapi = E_CAL_BACKEND_MAPI (backend);
priv = cbmapi->priv;
+ kind = e_cal_backend_get_kind (E_CAL_BACKEND (backend));
g_return_val_if_fail (E_IS_CAL_BACKEND_MAPI (cbmapi), GNOME_Evolution_Calendar_InvalidObject);
g_return_val_if_fail (calobj != NULL, GNOME_Evolution_Calendar_InvalidObject);
@@ -1346,14 +1317,19 @@
/* FIXME: [WIP] Add support for meetings/assigned tasks */
if (e_cal_component_has_attendees (comp))
- e_cal_backend_mapi_util_fetch_recipients (cbmapi, comp, &recipients);
+ exchange_mapi_cal_util_fetch_recipients (comp, &recipients);
if (e_cal_component_has_attachments (comp))
- e_cal_backend_mapi_util_fetch_attachments (cbmapi, comp, &attachments);
+ exchange_mapi_cal_util_fetch_attachments (comp, &attachments, priv->local_attachments_store);
e_cal_component_get_uid (comp, &uid);
rid = e_cal_component_get_recurid_as_string (comp);
+ cbdata.username = e_cal_backend_mapi_get_user_name (cbmapi);
+ cbdata.userid = e_cal_backend_mapi_get_user_email (cbmapi);
+ cbdata.ownername = e_cal_backend_mapi_get_owner_name (cbmapi);
+ cbdata.ownerid = e_cal_backend_mapi_get_owner_email (cbmapi);
+
switch (priv->mode) {
case CAL_MODE_ANY :
case CAL_MODE_REMOTE : /* when online, send the item to the server */
@@ -1366,12 +1342,14 @@
}
exchange_mapi_util_mapi_id_from_string (uid, &mid);
- cbdata.cbmapi = cbmapi;
cbdata.comp = comp;
// cbdata.meeting_type = (recipients != NULL) ? MEETING_OBJECT : NOT_A_MEETING;
cbdata.msgflags = MSGFLAG_READ;
cbdata.new_appt_id = 0x0;
- status = exchange_mapi_modify_item (priv->olFolder, priv->fid, mid, mapi_cal_build_name_id, cbmapi, mapi_cal_build_props, &cbdata, NULL, NULL, MAPI_OPTIONS_DONT_SUBMIT);
+ status = exchange_mapi_modify_item (priv->olFolder, priv->fid, mid,
+ exchange_mapi_cal_util_build_name_id, GINT_TO_POINTER(kind),
+ exchange_mapi_cal_util_build_props, &cbdata,
+ NULL, NULL, MAPI_OPTIONS_DONT_SUBMIT);
if (!status) {
g_object_unref (comp);
g_object_unref (cache_comp);
@@ -1547,7 +1525,7 @@
res.res.resProperty.relop = RELOP_EQ;
res.res.resProperty.ulPropTag = proptag;
- e_cal_backend_mapi_util_generate_globalobjectid (TRUE, uid, &sb);
+ exchange_mapi_cal_util_generate_globalobjectid (TRUE, uid, &sb);
set_SPropValue_proptag (&sprop, proptag, (const void *) &sb);
cast_mapi_SPropValue (&(res.res.resProperty.lpProp), &sprop);
@@ -1566,10 +1544,12 @@
ECalBackendSyncStatus status = GNOME_Evolution_Calendar_OtherError;
ECalBackendMAPI *cbmapi;
ECalBackendMAPIPrivate *priv;
+ icalcomponent_kind kind;
icalcomponent *icalcomp;
cbmapi = E_CAL_BACKEND_MAPI (backend);
priv = cbmapi->priv;
+ kind = e_cal_backend_get_kind (E_CAL_BACKEND (backend));
g_return_val_if_fail (E_IS_CAL_BACKEND_MAPI (cbmapi), GNOME_Evolution_Calendar_InvalidObject);
g_return_val_if_fail (calobj != NULL, GNOME_Evolution_Calendar_InvalidObject);
@@ -1587,8 +1567,7 @@
if (icalcomponent_isa (icalcomp) == ICAL_VCALENDAR_COMPONENT) {
icalproperty_method method = icalcomponent_get_method (icalcomp);
- icalcomponent *subcomp = icalcomponent_get_first_component (icalcomp,
- e_cal_backend_get_kind (E_CAL_BACKEND (backend)));
+ icalcomponent *subcomp = icalcomponent_get_first_component (icalcomp, kind);
while (subcomp) {
ECalComponent *comp = e_cal_component_new ();
struct cbdata cbdata;
@@ -1606,14 +1585,18 @@
/* FIXME: [WIP] Add support for meetings/assigned tasks */
if (e_cal_component_has_attendees (comp)) {
- e_cal_backend_mapi_util_fetch_recipients (cbmapi, comp, &recipients);
+ exchange_mapi_cal_util_fetch_recipients (comp, &recipients);
method = icalcomponent_get_method (icalcomp);
}
if (e_cal_component_has_attachments (comp))
- e_cal_backend_mapi_util_fetch_attachments (cbmapi, comp, &attachments);
+ exchange_mapi_cal_util_fetch_attachments (comp, &attachments, priv->local_attachments_store);
+
+ cbdata.username = e_cal_backend_mapi_get_user_name (cbmapi);
+ cbdata.userid = e_cal_backend_mapi_get_user_email (cbmapi);
+ cbdata.ownername = e_cal_backend_mapi_get_owner_name (cbmapi);
+ cbdata.ownerid = e_cal_backend_mapi_get_owner_email (cbmapi);
- cbdata.cbmapi = cbmapi;
cbdata.comp = comp;
cbdata.new_appt_id = 0x0;
switch (method) {
@@ -1633,7 +1616,10 @@
get_server_data (cbmapi, subcomp, &cbdata);
- mid = exchange_mapi_create_item (olFolderOutbox, 0, mapi_cal_build_name_id, cbmapi, mapi_cal_build_props, &cbdata, recipients, attachments, NULL, 0);
+ mid = exchange_mapi_create_item (olFolderOutbox, 0,
+ exchange_mapi_cal_util_build_name_id, GINT_TO_POINTER(kind),
+ exchange_mapi_cal_util_build_props, &cbdata,
+ recipients, attachments, NULL, 0);
if (!mid) {
g_object_unref (comp);
exchange_mapi_util_free_recipient_list (&recipients);
Modified: branches/EXCHANGE_MAPI_BRANCH/calendar/backends/mapi/e-cal-backend-mapi.h
==============================================================================
--- branches/EXCHANGE_MAPI_BRANCH/calendar/backends/mapi/e-cal-backend-mapi.h (original)
+++ branches/EXCHANGE_MAPI_BRANCH/calendar/backends/mapi/e-cal-backend-mapi.h Thu Jul 3 08:02:54 2008
@@ -42,6 +42,7 @@
#include <exchange-mapi-connection.h>
#include <exchange-mapi-defs.h>
+#include <exchange-mapi-cal-utils.h>
#include <exchange-mapi-folder.h>
#include <exchange-mapi-utils.h>
@@ -92,30 +93,6 @@
const char *
e_cal_backend_mapi_get_user_email (ECalBackendMAPI *cbmapi);
-typedef enum {
- NOT_A_MEETING = 0,
- MEETING_OBJECT = (1 << 0),
- MEETING_OBJECT_SENT = (1 << 1),
- MEETING_REQUEST = (1 << 2),
- MEETING_RESPONSE = (1 << 3)
-} MAPIMeetingOptions;
-
-struct dup_data {
- struct SBinary *globalid;
- struct SBinary *cleanglobalid;
- uint32_t owner_appt_id;
- uint32_t appt_seq;
-};
-
-struct cbdata {
- ECalBackendMAPI *cbmapi;
- ECalComponent *comp;
- MAPIMeetingOptions meeting_type;
- uint32_t msgflags;
- uint32_t new_appt_id;
- struct dup_data dup;
-};
-
G_END_DECLS
#endif
Modified: branches/EXCHANGE_MAPI_BRANCH/servers/mapi/Makefile.am
==============================================================================
--- branches/EXCHANGE_MAPI_BRANCH/servers/mapi/Makefile.am (original)
+++ branches/EXCHANGE_MAPI_BRANCH/servers/mapi/Makefile.am Thu Jul 3 08:02:54 2008
@@ -1,26 +1,42 @@
-
-INCLUDES = \
- -DG_LOG_DOMAIN=\"libexchangemapi\" \
- -I$(top_srcdir) \
- -I$(top_builddir) \
- $(LIBMAPI_CFLAGS) \
- $(E_DATA_SERVER_CFLAGS)
+INCLUDES = \
+ -DG_LOG_DOMAIN=\"libexchangemapi\" \
+ -I$(top_srcdir) \
+ -I$(top_builddir) \
+ -I$(top_srcdir)/calendar \
+ -I$(top_builddir)/calendar \
+ -I$(top_srcdir)/libical/src \
+ -I$(top_builddir)/libical/src \
+ -I$(top_srcdir)/libical/src/libical \
+ -I$(top_builddir)/libical/src/libical \
+ $(LIBMAPI_CFLAGS) \
+ $(E_DATA_SERVER_CFLAGS) \
+ -DMAPI_DATADIR=\""$(mapidatadir)"\" \
+ $(EVOLUTION_CALENDAR_CFLAGS)
lib_LTLIBRARIES = libexchangemapi-1.0.la
-libexchangemapi_1_0_la_SOURCES = \
- exchange-mapi-defs.h \
- exchange-mapi-folder.c \
- exchange-mapi-folder.h \
- exchange-mapi-connection.c \
- exchange-mapi-connection.h \
- exchange-mapi-utils.c \
- exchange-mapi-utils.h
-
-libexchangemapi_1_0_la_LIBADD = \
- $(E_DATA_SERVER_LIBS) \
- $(LIBMAPI_LIBS)
+mapidata_DATA = \
+ tz-mapi-to-ical \
+ tz-ical-to-mapi
+
+libexchangemapi_1_0_la_SOURCES = \
+ exchange-mapi-defs.h \
+ exchange-mapi-folder.c \
+ exchange-mapi-folder.h \
+ exchange-mapi-connection.c \
+ exchange-mapi-connection.h \
+ exchange-mapi-utils.c \
+ exchange-mapi-utils.h \
+ exchange-mapi-cal-utils.c \
+ exchange-mapi-cal-utils.h \
+ exchange-mapi-cal-tz-utils.c \
+ exchange-mapi-cal-tz-utils.h
+
+libexchangemapi_1_0_la_LIBADD = \
+ $(LIBMAPI_LIBS) \
+ $(E_DATA_SERVER_LIBS) \
+ $(EVOLUTION_CALENDAR_LIBS)
libexchangemapiincludedir = $(privincludedir)/mapi
@@ -28,7 +44,9 @@
exchange-mapi-defs.h \
exchange-mapi-folder.h \
exchange-mapi-connection.h \
- exchange-mapi-utils.h
+ exchange-mapi-utils.h \
+ exchange-mapi-cal-utils.h \
+ exchange-mapi-cal-tz-utils.h
%-1.0.pc: %.pc
cp $< $@
@@ -36,7 +54,9 @@
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = libexchangemapi-1.0.pc
-EXTRA_DIST = $(pkgconfig_DATA:-$(API_VERSION).pc=.pc.in)
+EXTRA_DIST = \
+ $(pkgconfig_DATA:-$(API_VERSION).pc=.pc.in) \
+ $(mapidata_DATA)
DISTCLEANFILES = $(pkgconfig_DATA)
Added: branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-cal-recur-utils.c
==============================================================================
--- (empty file)
+++ branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-cal-recur-utils.c Thu Jul 3 08:02:54 2008
@@ -0,0 +1,420 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Authors:
+ * Suman Manjunath <msuman novell com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU Lesser General Public
+ * License as published by the Free Software Foundation.
+ *
+ * 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to:
+ * Free Software Foundation, 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+
+
+#include "exchange-mapi-cal-recur-utils.h"
+
+#define ZERO_BYTE 0x00
+
+/* preamble */
+#define PREAMBLE 0x30043004
+
+/** Pattern termination **/
+#define REPEAT_UNTIL 0x00002021
+#define REPEAT_FOR_N 0x00002022
+#define REPEAT_FOREVER 0x00002023
+
+/** Outlook version indicator (?) **/
+#define VERSION_PREAMBLE 0x00003006
+/* This version-id is equivalent to Outlook 2007 */
+#define VERSION_ID 0x00003009
+
+
+/* terminal sequence (should add twice) */
+#define TERMINAL_SEQ 0x00000000
+
+struct icaltimetype dt1601;
+struct icaltimetype dt1970;
+
+static icalrecurrencetype_weekday
+get_ical_weekday (uint32_t olWeekday) {
+ switch (olWeekday) {
+ case olSunday:
+ return ICAL_SUNDAY_WEEKDAY;
+ case olMonday:
+ return ICAL_MONDAY_WEEKDAY;
+ case olTuesday:
+ return ICAL_TUESDAY_WEEKDAY;
+ case olWednesday:
+ return ICAL_WEDNESDAY_WEEKDAY;
+ case olThursday:
+ return ICAL_THURSDAY_WEEKDAY;
+ case olFriday:
+ return ICAL_FRIDAY_WEEKDAY;
+ case olSaturday:
+ return ICAL_SATURDAY_WEEKDAY;
+ default:
+ return ICAL_SUNDAY_WEEKDAY;
+ }
+}
+
+gboolean
+exchange_mapi_cal_util_bin_to_rrule (GByteArray *ba, ECalComponent *comp)
+{
+ struct icalrecurrencetype rt;
+ guint16 flag16;
+ guint32 flag32;
+ guint8 *ptr = ba->data;
+ GSList l;
+ gint i;
+
+ icalrecurrencetype_clear (&rt);
+
+ /* Major version */
+ flag32 = *((guint32 *)ptr);
+ ptr += sizeof (guint32);
+ if (PREAMBLE != flag32)
+ return FALSE;
+
+ /* FREQUENCY */
+ flag16 = *((guint16 *)ptr);
+ ptr += sizeof (guint16);
+ if (flag16 == 0x200A) {
+ rt.freq = ICAL_DAILY_RECURRENCE;
+
+ flag32 = *((guint32 *)ptr);
+ ptr += sizeof (guint32);
+ if (flag32 == 0x0) {
+ /* Daily every N days */
+
+ /* some crappy mod here */
+ flag32 = *((guint32 *)ptr);
+ ptr += sizeof (guint32);
+
+ /* INTERVAL */
+ flag32 = *((guint32 *)ptr);
+ ptr += sizeof (guint32);
+ rt.interval = (short) (flag32 / (24 * 60));
+
+ /* some constant 0 for the stuff we handle */
+ flag32 = *((guint32 *)ptr);
+ ptr += sizeof (guint32);
+ if (flag32)
+ return FALSE;
+ } else if (flag32 == 0x1) {
+ /* Daily every weekday */
+
+ /* NOTE: Evolution does not handle daily-every-weekday any different
+ * from a weekly recurrence.
+ */
+ rt.freq = ICAL_WEEKLY_RECURRENCE;
+
+ /* some crappy mod here */
+ flag32 = *((guint32 *)ptr);
+ ptr += sizeof (guint32);
+
+ /* INTERVAL */
+ flag32 = *((guint32 *)ptr);
+ ptr += sizeof (guint32);
+ rt.interval = (short) (flag32);
+
+ /* some constant 0 for the stuff we handle */
+ flag32 = *((guint32 *)ptr);
+ ptr += sizeof (guint32);
+ if (flag32)
+ return FALSE;
+
+ /* BITMASK */
+ flag32 = *((guint32 *)ptr);
+ ptr += sizeof (guint32);
+
+ i = 0;
+ if (flag32 & olSunday)
+ rt.by_day[i++] = ICAL_SUNDAY_WEEKDAY;
+ if (flag32 & olMonday)
+ rt.by_day[i++] = ICAL_MONDAY_WEEKDAY;
+ if (flag32 & olTuesday)
+ rt.by_day[i++] = ICAL_TUESDAY_WEEKDAY;
+ if (flag32 & olWednesday)
+ rt.by_day[i++] = ICAL_WEDNESDAY_WEEKDAY;
+ if (flag32 & olThursday)
+ rt.by_day[i++] = ICAL_THURSDAY_WEEKDAY;
+ if (flag32 & olFriday)
+ rt.by_day[i++] = ICAL_FRIDAY_WEEKDAY;
+ if (flag32 & olSaturday)
+ rt.by_day[i++] = ICAL_SATURDAY_WEEKDAY;
+ }
+
+ } else if (flag16 == 0x200B) {
+ rt.freq = ICAL_WEEKLY_RECURRENCE;
+
+ flag32 = *((guint32 *)ptr);
+ ptr += sizeof (guint32);
+ if (flag32 == 0x1) {
+ /* weekly every N weeks (for all events and non-regenerating tasks) */
+
+ /* some crappy mod here */
+ flag32 = *((guint32 *)ptr);
+ ptr += sizeof (guint32);
+
+ /* INTERVAL */
+ flag32 = *((guint32 *)ptr);
+ ptr += sizeof (guint32);
+ rt.interval = (short) (flag32);
+
+ /* some constant 0 */
+ flag32 = *((guint32 *)ptr);
+ ptr += sizeof (guint32);
+ if (flag32)
+ return FALSE;
+
+ /* BITMASK */
+ flag32 = *((guint32 *)ptr);
+ ptr += sizeof (guint32);
+
+ i = 0;
+ if (flag32 & olSunday)
+ rt.by_day[i++] = ICAL_SUNDAY_WEEKDAY;
+ if (flag32 & olMonday)
+ rt.by_day[i++] = ICAL_MONDAY_WEEKDAY;
+ if (flag32 & olTuesday)
+ rt.by_day[i++] = ICAL_TUESDAY_WEEKDAY;
+ if (flag32 & olWednesday)
+ rt.by_day[i++] = ICAL_WEDNESDAY_WEEKDAY;
+ if (flag32 & olThursday)
+ rt.by_day[i++] = ICAL_THURSDAY_WEEKDAY;
+ if (flag32 & olFriday)
+ rt.by_day[i++] = ICAL_FRIDAY_WEEKDAY;
+ if (flag32 & olSaturday)
+ rt.by_day[i++] = ICAL_SATURDAY_WEEKDAY;
+ } else if (flag32 == 0x0) {
+ /* weekly every N weeks (for all regenerating tasks) */
+
+ /* FIXME: we don't handle regenerating tasks */
+ return FALSE;
+ }
+
+ } else if (flag16 == 0x200C) {
+ rt.freq = ICAL_MONTHLY_RECURRENCE;
+
+ flag32 = *((guint32 *)ptr);
+ ptr += sizeof (guint32);
+
+ if (flag32 == 0x2) {
+ /* Monthly every N months on day D */
+
+ /* some crappy mod here */
+ flag32 = *((guint32 *)ptr);
+ ptr += sizeof (guint32);
+
+ /* INTERVAL */
+ flag32 = *((guint32 *)ptr);
+ ptr += sizeof (guint32);
+ rt.interval = (short) (flag32);
+
+ /* some constant 0 for the stuff we handle */
+ flag32 = *((guint32 *)ptr);
+ ptr += sizeof (guint32);
+ if (flag32)
+ return FALSE;
+
+ /* MONTH_DAY */
+ flag32 = *((guint32 *)ptr);
+ ptr += sizeof (guint32);
+ rt.by_month_day[0] = (short) (flag32);
+ } else if (flag32 == 0x3) {
+ /* Monthly every N months on the Xth Y */
+
+ /* some crappy mod here */
+ flag32 = *((guint32 *)ptr);
+ ptr += sizeof (guint32);
+
+ /* INTERVAL */
+ flag32 = *((guint32 *)ptr);
+ ptr += sizeof (guint32);
+ rt.interval = (short) (flag32);
+
+ /* some constant 0 for the stuff we handle */
+ flag32 = *((guint32 *)ptr);
+ ptr += sizeof (guint32);
+ if (flag32)
+ return FALSE;
+
+
+ flag32 = *((guint32 *)ptr);
+ ptr += sizeof (guint32);
+ if (flag32 > 4)
+
+ }
+
+ } else if (flag16 == 0x200D) {
+ rt.freq = ICAL_YEARLY_RECURRENCE;
+
+ flag32 = *((guint32 *)ptr);
+ ptr += sizeof (guint32);
+
+ if (flag32 == 0x2) {
+ /* Yearly on day D of month M */
+
+ flag32 = *((guint32 *)ptr);
+ ptr += sizeof (guint32);
+
+ /* INTERVAL */
+ flag32 = *((guint32 *)ptr);
+ ptr += sizeof (guint32);
+ rt.interval = (short) (flag32 / 12);
+
+ /* some constant 0 for the stuff we handle */
+ flag32 = *((guint32 *)ptr);
+ ptr += sizeof (guint32);
+ if (flag32)
+ return FALSE;
+
+ flag32 = *((guint32 *)ptr);
+ ptr += sizeof (guint32);
+ } else if (flag32 == 0x3) {
+ /* Yearly on the Xth Y of month M */
+ g_warning ("Encountered a recurrence pattern Evolution cannot handle");
+
+ flag32 = *((guint32 *)ptr);
+ ptr += sizeof (guint32);
+
+ /* INTERVAL */
+ flag32 = *((guint32 *)ptr);
+ ptr += sizeof (guint32);
+ rt.interval = (short) (flag32 / 12);
+
+ /* some constant 0 */
+ flag32 = *((guint32 *)ptr);
+ ptr += sizeof (guint32);
+ if (flag32)
+ return FALSE;
+
+ flag32 = *((guint32 *)ptr);
+ ptr += sizeof (guint32);
+
+ flag32 = *((guint32 *)ptr);
+ ptr += sizeof (guint32);
+
+ /* TODO: Add support for this kinda recurrence in Evolution */
+ return FALSE;
+ }
+ } else
+ return FALSE;
+
+ /* repeat */
+ flag32 = *((guint32 *)ptr);
+ ptr += sizeof (guint32);
+ if (flag32 == REPEAT_UNTIL) {
+ flag32 = *((guint32 *)ptr);
+ ptr += sizeof (guint32);
+ } else if (flag32 == REPEAT_FOR_N) {
+ flag32 = *((guint32 *)ptr);
+ ptr += sizeof (guint32);
+
+ rt.count = flag32;
+ } else if (flag32 == REPEAT_FOREVER) {
+ flag32 = *((guint32 *)ptr);
+ ptr += sizeof (guint32);
+ if (flag32)
+ return FALSE;
+ }
+
+ /* week_start */
+ flag32 = *((guint32 *)ptr);
+ ptr += sizeof (guint32);
+ rt.week_start = get_ical_weekday (flag32);
+g_print ("week start %x\n", flag32);
+
+ /* number of exceptions */
+ flag32 = *((guint32 *)ptr);
+ ptr += sizeof (guint32);
+ /* fixme: exceptions */
+ if (flag32)
+ ptr += flag32 * sizeof (guint32);
+g_print ("excpt no %x\n", flag32);
+
+ /* number of changed exceptions */
+ flag32 = *((guint32 *)ptr);
+ ptr += sizeof (guint32);
+ /* fixme: exceptions */
+ if (flag32)
+ ptr += flag32 * sizeof (guint32);
+g_print ("changed excpt %x\n", flag32);
+
+ /* start date */
+ flag32 = *((guint32 *)ptr);
+ ptr += sizeof (guint32);
+g_print ("start date %x\n", flag32);
+
+ /* end date */
+ flag32 = *((guint32 *)ptr);
+ ptr += sizeof (guint32);
+g_print ("end date %x\n", flag32);
+
+ /* some constant */
+ flag32 = *((guint32 *)ptr);
+ ptr += sizeof (guint32);
+ if (flag32 != VERSION_PREAMBLE)
+ return FALSE;
+g_print ("constant %x\n", flag32);
+
+ /* version info */
+ flag32 = *((guint32 *)ptr);
+ ptr += sizeof (guint32);
+ if (flag32 != VERSION_ID)
+ return FALSE;
+g_print ("ver info %x\n", flag32);
+
+ /* start time in mins */
+ flag32 = *((guint32 *)ptr);
+ ptr += sizeof (guint32);
+g_print ("start time in mins %x\n", flag32);
+
+ /* end time in mins */
+ flag32 = *((guint32 *)ptr);
+ ptr += sizeof (guint32);
+g_print ("end time in mins %x\n", flag32);
+
+ /* exceptions */
+ flag16 = *((guint16 *)ptr);
+ ptr += sizeof (guint16);
+ if (flag16 != 0x0)
+ return FALSE;
+g_print ("excpt no %x\n", flag16);
+
+ /* term seq */
+ flag32 = *((guint32 *)ptr);
+ ptr += sizeof (guint32);
+ if (flag32 != TERMINAL_SEQ)
+ return FALSE;
+g_print ("term seq 1 %x\n", flag32);
+
+ /* term seq */
+ flag32 = *((guint32 *)ptr);
+ ptr += sizeof (guint32);
+ if (flag32 != TERMINAL_SEQ)
+ return FALSE;
+
+ /* Set the recurrence */
+
+ l.data = &rt;
+ l.next = NULL;
+
+ e_cal_component_set_rrule_list (comp, &l);
+
+ g_print ("\n\nyipppeee... parsed the blob..\n\n");
+
+ return TRUE;
+}
Added: branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-cal-recur-utils.h
==============================================================================
--- (empty file)
+++ branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-cal-recur-utils.h Thu Jul 3 08:02:54 2008
@@ -0,0 +1,39 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Authors:
+ * Suman Manjunath <msuman novell com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU Lesser General Public
+ * License as published by the Free Software Foundation.
+ *
+ * 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to:
+ * Free Software Foundation, 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+
+
+#ifndef EXCHANGE_MAPI_CAL_RECUR_UTILS_H
+#define EXCHANGE_MAPI_CAL_RECUR_UTILS_H
+
+#include <glib.h>
+
+G_BEGIN_DECLS
+
+gboolean
+exchange_mapi_cal_util_bin_to_rrule (GByteArray *ba, ECalComponent *comp);
+
+G_END_DECLS
+
+#endif
+
Added: branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-cal-tz-utils.c
==============================================================================
--- (empty file)
+++ branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-cal-tz-utils.c Thu Jul 3 08:02:54 2008
@@ -0,0 +1,563 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Authors:
+ * Suman Manjunath <msuman novell com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU Lesser General Public
+ * License as published by the Free Software Foundation.
+ *
+ * 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to:
+ * Free Software Foundation, 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+
+
+#include "exchange-mapi-cal-tz-utils.h"
+
+#define d(x)
+
+#define MAPPING_SEPARATOR "~~~"
+
+static GStaticRecMutex mutex = G_STATIC_REC_MUTEX_INIT;
+
+static GHashTable *mapi_to_ical = NULL;
+static GHashTable *ical_to_mapi = NULL;
+
+static const gchar *lru_mapi_id = NULL;
+static const gchar *lru_ical_id = NULL;
+
+const gchar *
+exchange_mapi_cal_tz_util_get_mapi_equivalent (const gchar *ical_tzid)
+{
+ g_return_val_if_fail ((ical_tzid && *ical_tzid), NULL);
+
+ g_static_rec_mutex_lock(&mutex);
+ if (!(mapi_to_ical && ical_to_mapi)) {
+ g_static_rec_mutex_unlock(&mutex);
+ return NULL;
+ }
+
+ d(g_message("%s(%d): %s of '%s' ", __FILE__, __LINE__, __PRETTY_FUNCTION__, ical_tzid));
+
+ if (lru_ical_id && !g_ascii_strcasecmp (ical_tzid, lru_ical_id)) {
+ g_static_rec_mutex_unlock(&mutex);
+ return lru_mapi_id;
+ }
+
+ lru_mapi_id = lru_ical_id = NULL;
+ if ((lru_mapi_id = g_hash_table_lookup (ical_to_mapi, ical_tzid)) != NULL)
+ lru_ical_id = ical_tzid;
+
+ g_static_rec_mutex_unlock(&mutex);
+
+ return lru_mapi_id;
+}
+
+const gchar *
+exchange_mapi_cal_tz_util_get_ical_equivalent (const gchar *mapi_tzid)
+{
+ g_return_val_if_fail ((mapi_tzid && *mapi_tzid), NULL);
+
+ g_static_rec_mutex_lock(&mutex);
+ if (!(mapi_to_ical && ical_to_mapi)) {
+ g_static_rec_mutex_unlock(&mutex);
+ return NULL;
+ }
+
+ d(g_message("%s(%d): %s of '%s' ", __FILE__, __LINE__, __PRETTY_FUNCTION__, mapi_tzid));
+
+ if (lru_mapi_id && !g_ascii_strcasecmp (mapi_tzid, lru_mapi_id)) {
+ g_static_rec_mutex_unlock(&mutex);
+ return lru_ical_id;
+ }
+
+ lru_ical_id = lru_mapi_id = NULL;
+ if ((lru_ical_id = g_hash_table_lookup (mapi_to_ical, mapi_tzid)) != NULL)
+ lru_mapi_id = mapi_tzid;
+
+ g_static_rec_mutex_unlock(&mutex);
+
+ return lru_ical_id;
+}
+
+void
+exchange_mapi_cal_tz_util_destroy ()
+{
+ g_static_rec_mutex_lock(&mutex);
+ if (!(mapi_to_ical && ical_to_mapi)) {
+ g_static_rec_mutex_unlock(&mutex);
+ return;
+ }
+
+ g_hash_table_destroy (mapi_to_ical);
+ g_hash_table_destroy (ical_to_mapi);
+
+ /* Reset all the values */
+ mapi_to_ical = NULL;
+ ical_to_mapi = NULL;
+
+ lru_mapi_id = NULL;
+ lru_ical_id = NULL;
+
+ g_static_rec_mutex_unlock(&mutex);
+}
+
+static void
+file_contents_to_hashtable (const char *contents, GHashTable *table)
+{
+ gchar **array = NULL;
+ guint len = 0, i;
+
+ array = g_strsplit (contents, "\n", -1);
+ len = g_strv_length (array);
+
+ for (i=0; i < len-1; ++i) {
+ gchar **mapping = g_strsplit (array[i], MAPPING_SEPARATOR, -1);
+ if (g_strv_length (mapping) == 2)
+ g_hash_table_insert (table, g_strdup (mapping[0]), g_strdup (mapping[1]));
+ g_strfreev (mapping);
+ }
+
+ g_strfreev (array);
+}
+
+gboolean
+exchange_mapi_cal_tz_util_populate ()
+{
+ gchar *mtoi_fn = NULL, *itom_fn = NULL;
+ GMappedFile *mtoi_mf = NULL, *itom_mf = NULL;
+
+ g_static_rec_mutex_lock(&mutex);
+ if (mapi_to_ical && ical_to_mapi) {
+ g_static_rec_mutex_unlock(&mutex);
+ return TRUE;
+ }
+
+ mtoi_fn = g_build_filename (MAPI_DATADIR, "tz-mapi-to-ical", NULL);
+ itom_fn = g_build_filename (MAPI_DATADIR, "tz-ical-to-mapi", NULL);
+
+ mtoi_mf = g_mapped_file_new (mtoi_fn, FALSE, NULL);
+ itom_mf = g_mapped_file_new (itom_fn, FALSE, NULL);
+
+ g_free (mtoi_fn);
+ g_free (itom_fn);
+
+ if (!(mtoi_mf && itom_mf)) {
+ g_warning ("Could not map Exchange MAPI timezone files.");
+
+ if (mtoi_mf)
+ g_mapped_file_free (mtoi_mf);
+ if (itom_mf)
+ g_mapped_file_free (itom_mf);
+
+ g_static_rec_mutex_unlock(&mutex);
+ return FALSE;
+ }
+
+ mapi_to_ical = g_hash_table_new_full ((GHashFunc) g_str_hash,
+ (GEqualFunc) g_str_equal,
+ (GDestroyNotify) g_free,
+ (GDestroyNotify) g_free);
+
+ file_contents_to_hashtable (g_mapped_file_get_contents (mtoi_mf), mapi_to_ical);
+
+ ical_to_mapi = g_hash_table_new_full ((GHashFunc) g_str_hash,
+ (GEqualFunc) g_str_equal,
+ (GDestroyNotify) g_free,
+ (GDestroyNotify) g_free);
+
+ file_contents_to_hashtable (g_mapped_file_get_contents (itom_mf), ical_to_mapi);
+
+ if (!(g_hash_table_size (mapi_to_ical) && g_hash_table_size (ical_to_mapi))) {
+ g_warning ("Exchange MAPI timezone files are not valid.");
+
+ exchange_mapi_cal_tz_util_destroy ();
+
+ g_mapped_file_free (mtoi_mf);
+ g_mapped_file_free (itom_mf);
+
+ g_static_rec_mutex_unlock(&mutex);
+ return FALSE;
+ }
+
+ g_mapped_file_free (mtoi_mf);
+ g_mapped_file_free (itom_mf);
+
+ g_static_rec_mutex_unlock(&mutex);
+ return TRUE;
+}
+
+static void
+exchange_mapi_cal_tz_util_dump_ical_tzs ()
+{
+ guint i;
+ icalarray *zones;
+ GList *l, *list_items = NULL;
+
+ /* Get the array of builtin timezones. */
+ zones = icaltimezone_get_builtin_timezones ();
+
+ g_message("%s(%d): %s: ", __FILE__, __LINE__, __PRETTY_FUNCTION__);
+ for (i = 0; i < zones->num_elements; i++) {
+ icaltimezone *zone;
+ char *tzid = NULL;
+
+ zone = icalarray_element_at (zones, i);
+
+ tzid = icaltimezone_get_tzid (zone);
+
+ list_items = g_list_prepend (list_items, tzid);
+ }
+
+ list_items = g_list_sort (list_items, (GCompareFunc) g_ascii_strcasecmp);
+
+ /* Put the "UTC" entry at the top of the combo's list. */
+ list_items = g_list_prepend (list_items, "UTC");
+
+ for (l = list_items, i = 0; l != NULL; l = l->next, ++i)
+ g_print ("[%3d]\t%s\n", (i+1), (gchar *)(l->data));
+
+// icaltimezone_free_builtin_timezones ();
+
+ g_list_free (list_items);
+}
+
+void
+exchange_mapi_cal_tz_util_dump ()
+{
+ guint i;
+ GList *keys, *values, *l, *m;
+
+ g_static_rec_mutex_lock(&mutex);
+
+ exchange_mapi_cal_tz_util_dump_ical_tzs ();
+
+ if (!(mapi_to_ical && ical_to_mapi)) {
+ g_static_rec_mutex_unlock(&mutex);
+ return;
+ }
+
+ g_message("%s(%d): %s: ", __FILE__, __LINE__, __PRETTY_FUNCTION__);
+
+ g_message ("Dumping #table mapi_to_ical");
+ keys = g_hash_table_get_keys (mapi_to_ical);
+ values = g_hash_table_get_values (mapi_to_ical);
+ l = g_list_first (keys);
+ m = g_list_first (values);
+ for (i=0; l && m; ++i, l=l->next, m=m->next)
+ g_print ("[%3d]\t%s\t%s\t%s\n", (i+1), (gchar *)(l->data), MAPPING_SEPARATOR, (gchar *)(m->data));
+ g_message ("Dumping differences in #tables");
+ l = g_list_first (keys);
+ m = g_list_first (values);
+ for (i=0; l && m; ++i, l=l->next, m=m->next)
+ if (g_ascii_strcasecmp ((gchar *)(l->data), (gchar *) g_hash_table_lookup (ical_to_mapi, (m->data))))
+ g_print ("[%3d] Possible mis-match for %s\n", (i+1), (gchar *)(l->data));
+ g_list_free (keys);
+ g_list_free (values);
+
+ g_message ("Dumping #table ical_to_mapi");
+ keys = g_hash_table_get_keys (ical_to_mapi);
+ values = g_hash_table_get_values (ical_to_mapi);
+ l = g_list_first (keys);
+ m = g_list_first (values);
+ for (i=0; l && m; ++i, l=l->next, m=m->next)
+ g_print ("[%3d]\t%s\t%s\t%s\n", (i+1), (gchar *)(l->data), MAPPING_SEPARATOR, (gchar *)(m->data));
+ g_list_free (keys);
+ g_list_free (values);
+
+ g_static_rec_mutex_unlock(&mutex);
+}
+
+#if 0
+const WORD TZRULE_FLAG_RECUR_CURRENT_TZREG = 0x0001; // see dispidApptTZDefRecur
+const WORD TZRULE_FLAG_EFFECTIVE_TZREG = 0x0002;
+
+// Allocates return value with new.
+// clean up with delete[].
+TZDEFINITION* BinToTZDEFINITION(ULONG cbDef, LPBYTE lpbDef)
+{
+ if (!lpbDef) return NULL;
+
+ // Update this if parsing code is changed!
+ // this checks the size up to the flags member
+ if (cbDef < 2*sizeof(BYTE) + 2*sizeof(WORD)) return NULL;
+
+ TZDEFINITION tzDef;
+ TZRULE* lpRules = NULL;
+ LPBYTE lpPtr = lpbDef;
+ WORD cchKeyName = 0;
+ WCHAR* szKeyName = NULL;
+ WORD i = 0;
+
+ BYTE bMajorVersion = *((BYTE*)lpPtr);
+ lpPtr += sizeof(BYTE);
+ BYTE bMinorVersion = *((BYTE*)lpPtr);
+ lpPtr += sizeof(BYTE);
+
+ // We only understand TZ_BIN_VERSION_MAJOR
+ if (TZ_BIN_VERSION_MAJOR != bMajorVersion) return NULL;
+
+ // We only understand if >= TZ_BIN_VERSION_MINOR
+ if (TZ_BIN_VERSION_MINOR > bMinorVersion) return NULL;
+
+ WORD cbHeader = *((WORD*)lpPtr);
+ lpPtr += sizeof(WORD);
+
+ tzDef.wFlags = *((WORD*)lpPtr);
+ lpPtr += sizeof(WORD);
+
+ if (TZDEFINITION_FLAG_VALID_GUID & tzDef.wFlags)
+ {
+ if (lpbDef + cbDef - lpPtr < sizeof(GUID)) return NULL;
+ tzDef.guidTZID = *((GUID*)lpPtr);
+ lpPtr += sizeof(GUID);
+ }
+
+ if (TZDEFINITION_FLAG_VALID_KEYNAME & tzDef.wFlags)
+ {
+ if (lpbDef + cbDef - lpPtr < sizeof(WORD)) return NULL;
+ cchKeyName = *((WORD*)lpPtr);
+ lpPtr += sizeof(WORD);
+ if (cchKeyName)
+ {
+ if (lpbDef + cbDef - lpPtr < (BYTE)sizeof(WORD)*cchKeyName) return NULL;
+ szKeyName = (WCHAR*)lpPtr;
+ lpPtr += cchKeyName*sizeof(WORD);
+ }
+ }
+
+ if (lpbDef+ cbDef - lpPtr < sizeof(WORD)) return NULL;
+ tzDef.cRules = *((WORD*)lpPtr);
+ lpPtr += sizeof(WORD);
+
+ /* FIXME: parse rules */
+ if (tzDef.cRules) tzDef.cRules = 0;
+#if 0
+ if (tzDef.cRules)
+ {
+ lpRules = new TZRULE[tzDef.cRules];
+ if (!lpRules) return NULL;
+
+ LPBYTE lpNextRule = lpPtr;
+ BOOL bRuleOK = false;
+
+ for (i = 0;i < tzDef.cRules;i++)
+ {
+ bRuleOK = false;
+ lpPtr = lpNextRule;
+
+ if (lpbDef + cbDef - lpPtr <
+ 2*sizeof(BYTE) + 2*sizeof(WORD) + 3*sizeof(long) + 2*sizeof(SYSTEMTIME)) return NULL;
+ bRuleOK = true;
+ BYTE bRuleMajorVersion = *((BYTE*)lpPtr);
+ lpPtr += sizeof(BYTE);
+ BYTE bRuleMinorVersion = *((BYTE*)lpPtr);
+ lpPtr += sizeof(BYTE);
+
+ // We only understand TZ_BIN_VERSION_MAJOR
+ if (TZ_BIN_VERSION_MAJOR != bRuleMajorVersion) return NULL;
+
+ // We only understand if >= TZ_BIN_VERSION_MINOR
+ if (TZ_BIN_VERSION_MINOR > bRuleMinorVersion) return NULL;
+
+ WORD cbRule = *((WORD*)lpPtr);
+ lpPtr += sizeof(WORD);
+
+ lpNextRule = lpPtr + cbRule;
+
+ lpRules[i].wFlags = *((WORD*)lpPtr);
+ lpPtr += sizeof(WORD);
+
+ lpRules[i].stStart = *((SYSTEMTIME*)lpPtr);
+ lpPtr += sizeof(SYSTEMTIME);
+
+ lpRules[i].TZReg.lBias = *((long*)lpPtr);
+ lpPtr += sizeof(long);
+ lpRules[i].TZReg.lStandardBias = *((long*)lpPtr);
+ lpPtr += sizeof(long);
+ lpRules[i].TZReg.lDaylightBias = *((long*)lpPtr);
+ lpPtr += sizeof(long);
+
+ lpRules[i].TZReg.stStandardDate = *((SYSTEMTIME*)lpPtr);
+ lpPtr += sizeof(SYSTEMTIME);
+ lpRules[i].TZReg.stDaylightDate = *((SYSTEMTIME*)lpPtr);
+ lpPtr += sizeof(SYSTEMTIME);
+ }
+ if (!bRuleOK)
+ {
+ delete[] lpRules;
+ return NULL;
+ }
+ }
+#endif
+ // Now we've read everything - allocate a structure and copy it in
+ size_t cbTZDef = sizeof(TZDEFINITION) +
+ sizeof(WCHAR)*(cchKeyName+1) +
+ sizeof(TZRULE)*tzDef.cRules;
+
+ TZDEFINITION* ptzDef = (TZDEFINITION*) malloc (cbTZDef);
+
+ if (ptzDef)
+ {
+ // Copy main struct over
+ *ptzDef = tzDef;
+ lpPtr = (LPBYTE) ptzDef;
+ lpPtr += sizeof(TZDEFINITION);
+
+ if (szKeyName)
+ {
+ ptzDef->pwszKeyName = (WCHAR*)lpPtr;
+ memcpy(lpPtr,szKeyName,cchKeyName*sizeof(WCHAR));
+ ptzDef->pwszKeyName[cchKeyName] = 0;
+ lpPtr += (cchKeyName+1)*sizeof(WCHAR);
+ }
+
+ if (ptzDef -> cRules)
+ {
+ ptzDef -> rgRules = (TZRULE*)lpPtr;
+ for (i = 0;i < ptzDef -> cRules;i++)
+ {
+ ptzDef -> rgRules[i] = lpRules[i];
+ }
+ }
+ }
+// delete[] lpRules;
+
+ free (ptzDef);
+ ptzDef = NULL;
+
+ return ptzDef;
+}
+#endif
+
+#define TZDEFINITION_FLAG_VALID_GUID 0x0001 // the guid is valid
+#define TZDEFINITION_FLAG_VALID_KEYNAME 0x0002 // the keyname is valid
+#define TZ_MAX_RULES 1024
+#define TZ_BIN_VERSION_MAJOR 0x02
+#define TZ_BIN_VERSION_MINOR 0x01
+
+void
+exchange_mapi_cal_util_mapi_tz_to_bin (const char *mapi_tzid, struct SBinary *sb)
+{
+ GByteArray *ba;
+ guint8 flag8;
+ guint16 flag16;
+ gunichar2 *buf;
+ glong items_written;
+ guint32 i;
+
+ ba = g_byte_array_new ();
+
+ /* UTF-8 length of the keyname */
+ flag16 = g_utf8_strlen (mapi_tzid, -1);
+ ba = g_byte_array_append (ba, &flag16, sizeof (guint16));
+ /* Keyname */
+ buf = g_utf8_to_utf16 (mapi_tzid, flag16, NULL, &items_written, NULL);
+ ba = g_byte_array_append (ba, buf, (sizeof (gunichar2) * items_written));
+ g_free (buf);
+
+ /* number of rules *//* FIXME: Need to support rules */
+ flag16 = 0x0000;
+ ba = g_byte_array_append (ba, &flag16, sizeof (guint16));
+
+ /* wFlags: we know only keyname based names */
+ flag16 = TZDEFINITION_FLAG_VALID_KEYNAME;
+ ba = g_byte_array_prepend (ba, &flag16, sizeof (guint16));
+
+ /* Length in bytes until rules info */
+ flag16 = (guint16) (ba->len);
+ ba = g_byte_array_prepend (ba, &flag16, sizeof (guint16));
+
+ /* Minor version */
+ flag8 = TZ_BIN_VERSION_MINOR;
+ ba = g_byte_array_prepend (ba, &flag8, sizeof (guint8));
+
+ /* Major version */
+ flag8 = TZ_BIN_VERSION_MAJOR;
+ ba = g_byte_array_prepend (ba, &flag8, sizeof (guint8));
+
+ /* Rules may now be appended here */
+
+ sb->lpb = ba->data;
+ sb->cb = ba->len;
+
+ d(g_message ("New timezone stream.. Length: %d bytes.. Hex-data follows:", ba->len));
+ d(for (i = 0; i < ba->len; i++)
+ g_print("0x%.2X ", ba->data[i]));
+
+ g_byte_array_free (ba, FALSE);
+}
+
+gchar *
+exchange_mapi_cal_util_bin_to_mapi_tz (GByteArray *ba)
+{
+ guint8 flag8;
+ guint16 flag16, cbHeader = 0;
+ guint8 *ptr = ba->data;
+// guint len = ba->len;
+ gchar *buf = NULL;
+
+ d(g_message ("New timezone stream.. Length: %d bytes.. Info follows:", ba->len));
+
+ /* Major version */
+ flag8 = *((guint8 *)ptr);
+ ptr += sizeof (guint8);
+ d(g_print ("Major version: %d\n", flag8));
+ if (TZ_BIN_VERSION_MAJOR != flag8)
+ return NULL;
+
+ /* Minor version */
+ flag8 = *((guint8 *)ptr);
+ ptr += sizeof (guint8);
+ d(g_print ("Minor version: %d\n", flag8));
+ if (TZ_BIN_VERSION_MINOR > flag8)
+ return NULL;
+
+ /* Length in bytes until rules info */
+ flag16 = *((guint16 *)ptr);
+ ptr += sizeof (guint16);
+ d(g_print ("Length in bytes until rules: %d\n", flag16));
+ cbHeader = flag16;
+
+ /* wFlags: we don't yet understand GUID based names */
+ flag16 = *((guint16 *)ptr);
+ ptr += sizeof (guint16);
+ d(g_print ("wFlags: %d\n", flag16));
+ cbHeader -= sizeof (guint16);
+ if (TZDEFINITION_FLAG_VALID_KEYNAME != flag16)
+ return NULL;
+
+ /* UTF-8 length of the keyname */
+ flag16 = *((guint16 *)ptr);
+ ptr += sizeof (guint16);
+ d(g_print ("UTF8 length of keyname: %d\n", flag16));
+ cbHeader -= sizeof (guint16);
+
+ /* number of rules is at the end of the header.. we'll parse and use later */
+ cbHeader -= sizeof (guint16);
+
+ /* Keyname */
+ buf = g_utf16_to_utf8 ((const gunichar2 *)ptr, cbHeader/sizeof (gunichar2), NULL, NULL, NULL);
+ ptr += cbHeader;
+ d(g_print ("Keyname: %s\n", buf));
+
+ /* number of rules */
+ flag16 = *((guint16 *)ptr);
+ ptr += sizeof (guint16);
+ d(g_print ("Number of rules: %d\n", flag16));
+
+ /* FIXME: Need to support rules */
+
+ return buf;
+}
Added: branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-cal-tz-utils.h
==============================================================================
--- (empty file)
+++ branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-cal-tz-utils.h Thu Jul 3 08:02:54 2008
@@ -0,0 +1,117 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Authors:
+ * Suman Manjunath <msuman novell com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU Lesser General Public
+ * License as published by the Free Software Foundation.
+ *
+ * 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to:
+ * Free Software Foundation, 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+
+
+#ifndef EXCHANGE_MAPI_CAL_TZ_UTILS_H
+#define EXCHANGE_MAPI_CAL_TZ_UTILS_H
+
+#include <glib.h>
+#include "exchange-mapi-cal-utils.h"
+
+G_BEGIN_DECLS
+
+const gchar *
+exchange_mapi_cal_tz_util_get_mapi_equivalent (const gchar *ical_tzid);
+
+const gchar *
+exchange_mapi_cal_tz_util_get_ical_equivalent (const gchar *mapi_tzid);
+
+gboolean
+exchange_mapi_cal_tz_util_populate (void);
+
+void
+exchange_mapi_cal_tz_util_destroy (void);
+
+void
+exchange_mapi_cal_tz_util_dump (void);
+
+void
+exchange_mapi_cal_util_mapi_tz_to_bin (const char *mapi_tzid, struct SBinary *sb);
+
+gchar *
+exchange_mapi_cal_util_bin_to_mapi_tz (GByteArray *ba);
+
+G_END_DECLS
+
+#if 0
+typedef int16_t WORD;
+typedef int8_t BYTE;
+typedef uint32_t GUID;
+typedef uint64_t ULONG;
+typedef time_t SYSTEMTIME;
+typedef uint8_t* LPBYTE;
+typedef char* LPWSTR;
+typedef char WCHAR;
+
+// TZREG
+// =====================
+// This is an individual description that defines when a daylight
+// saving shift, and the return to standard time occurs, and how
+// far the shift is. This is basically the same as
+// TIME_ZONE_INFORMATION documented in MSDN, except that the strings
+// describing the names "daylight" and "standard" time are omitted.
+//
+typedef struct RenTimeZone
+{
+ long lBias; // offset from GMT
+ long lStandardBias; // offset from bias during standard time
+ long lDaylightBias; // offset from bias during daylight time
+ SYSTEMTIME stStandardDate; // time to switch to standard time
+ SYSTEMTIME stDaylightDate; // time to switch to daylight time
+} TZREG;
+
+// TZRULE
+// =====================
+// This structure represents both a description when a daylight.
+// saving shift occurs, and in addition, the year in which that
+// timezone rule came into effect.
+//
+typedef struct
+{
+ WORD wFlags; // indicates which rule matches legacy recur
+ SYSTEMTIME stStart; // indicates when the rule starts
+ TZREG TZReg; // the timezone info
+} TZRULE;
+
+// TZDEFINITION
+// =====================
+// This represents an entire timezone including all historical, current
+// and future timezone shift rules for daylight saving time, etc. It's
+// identified by a unique GUID.
+//
+typedef struct
+{
+ WORD wFlags; // indicates which fields are valid
+ GUID guidTZID; // guid uniquely identifying this timezone
+ LPWSTR pwszKeyName; // the name of the key for this timezone
+ WORD cRules; // the number of timezone rules for this definition
+ TZRULE* rgRules; // an array of rules describing when shifts occur
+} TZDEFINITION;
+
+// Allocates return value with new.
+// clean up with delete[].
+TZDEFINITION* BinToTZDEFINITION(ULONG cbDef, LPBYTE lpbDef);
+#endif
+
+#endif
Added: branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-cal-utils.c
==============================================================================
--- (empty file)
+++ branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-cal-utils.c Thu Jul 3 08:02:54 2008
@@ -0,0 +1,1465 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Authors:
+ * Suman Manjunath <msuman novell com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU Lesser General Public
+ * License as published by the Free Software Foundation.
+ *
+ * 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to:
+ * Free Software Foundation, 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+
+
+#ifndef O_BINARY
+#define O_BINARY 0
+#endif
+
+#include <glib/gstdio.h>
+#include <fcntl.h>
+#include <libecal/e-cal-util.h>
+#include "exchange-mapi-cal-utils.h"
+
+#define d(x)
+
+static void appt_build_name_id (struct mapi_nameid *nameid);
+static void task_build_name_id (struct mapi_nameid *nameid);
+static void note_build_name_id (struct mapi_nameid *nameid);
+
+static struct icaltimetype
+foo (const time_t tm, const int is_date, const icaltimezone *comp_zone)
+{
+ struct icaltimetype itt_utc;
+ struct icaltimetype itt;
+ const icaltimezone *utc_zone;
+
+ utc_zone = icaltimezone_get_utc_timezone ();
+
+ /* First, get the time in UTC */
+ itt_utc = icaltime_from_timet_with_zone (tm, is_date, 0);
+ icaltime_set_timezone (&itt_utc, utc_zone);
+
+ if (comp_zone) {
+ itt = icaltime_convert_to_zone (itt_utc, comp_zone);
+ itt = icaltime_set_timezone (&itt, comp_zone);
+ } else {
+ itt = icaltime_convert_to_zone (itt_utc, utc_zone);
+ itt = icaltime_set_timezone (&itt, utc_zone);
+ }
+
+ return itt;
+}
+
+static icalparameter_role
+get_role_from_type (OlMailRecipientType type)
+{
+ switch (type) {
+ case olCC : return ICAL_ROLE_OPTPARTICIPANT;
+ case olOriginator :
+ case olTo :
+ case olBCC :
+ default : return ICAL_ROLE_REQPARTICIPANT;
+ }
+}
+
+static OlMailRecipientType
+get_type_from_role (icalparameter_role role)
+{
+ switch (role) {
+ case ICAL_ROLE_OPTPARTICIPANT : return olCC;
+ case ICAL_ROLE_CHAIR :
+ case ICAL_ROLE_REQPARTICIPANT :
+ case ICAL_ROLE_NONPARTICIPANT :
+ default : return olTo;
+ }
+}
+
+static icalparameter_partstat
+get_partstat_from_trackstatus (uint32_t trackstatus)
+{
+ switch (trackstatus) {
+ case olMeetingTentative : return ICAL_PARTSTAT_TENTATIVE;
+ case olMeetingAccepted : return ICAL_PARTSTAT_ACCEPTED;
+ case olMeetingDeclined : return ICAL_PARTSTAT_DECLINED;
+ default : return ICAL_PARTSTAT_NEEDSACTION;
+ }
+}
+
+static uint32_t
+get_trackstatus_from_partstat (icalparameter_partstat partstat)
+{
+ switch (partstat) {
+ case ICAL_PARTSTAT_ACCEPTED : return olMeetingAccepted;
+ case ICAL_PARTSTAT_DECLINED : return olMeetingDeclined;
+ case ICAL_PARTSTAT_TENTATIVE :
+ default : return olMeetingTentative;
+ }
+}
+
+static icalproperty_transp
+get_transp_from_prop (uint32_t prop)
+{
+ /* FIXME: is this mapping correct ? */
+ switch (prop) {
+ case olFree :
+ case olTentative : return ICAL_TRANSP_TRANSPARENT;
+ case olBusy :
+ case olOutOfOffice :
+ default : return ICAL_TRANSP_OPAQUE;
+ }
+}
+
+static uint32_t
+get_prop_from_transp (icalproperty_transp transp)
+{
+ /* FIXME: is this mapping correct ? */
+ switch (transp) {
+ case ICAL_TRANSP_TRANSPARENT :
+ case ICAL_TRANSP_TRANSPARENTNOCONFLICT : return olFree;
+ case ICAL_TRANSP_OPAQUE :
+ case ICAL_TRANSP_OPAQUENOCONFLICT :
+ default : return olBusy;
+ }
+}
+
+static icalproperty_status
+get_taskstatus_from_prop (uint32_t prop)
+{
+ /* FIXME: is this mapping correct ? */
+ switch (prop) {
+ case olTaskComplete : return ICAL_STATUS_COMPLETED;
+ case olTaskWaiting :
+ case olTaskInProgress : return ICAL_STATUS_INPROCESS;
+ case olTaskDeferred : return ICAL_STATUS_CANCELLED;
+ case olTaskNotStarted :
+ default : return ICAL_STATUS_NEEDSACTION;
+ }
+}
+
+static uint32_t
+get_prop_from_taskstatus (icalproperty_status status)
+{
+ /* FIXME: is this mapping correct ? */
+ switch (status) {
+ case ICAL_STATUS_INPROCESS : return olTaskInProgress;
+ case ICAL_STATUS_COMPLETED : return olTaskComplete;
+ case ICAL_STATUS_CANCELLED : return olTaskDeferred;
+ default : return olTaskNotStarted;
+ }
+}
+
+static icalproperty_class
+get_class_from_prop (uint32_t prop)
+{
+ /* FIXME: is this mapping correct ? */
+ switch (prop) {
+ case olPersonal :
+ case olPrivate : return ICAL_CLASS_PRIVATE;
+ case olConfidential : return ICAL_CLASS_CONFIDENTIAL;
+ case olNormal :
+ default : return ICAL_CLASS_PUBLIC;
+ }
+}
+
+static uint32_t
+get_prop_from_class (icalproperty_class class)
+{
+ /* FIXME: is this mapping correct ? */
+ switch (class) {
+ case ICAL_CLASS_PRIVATE : return olPrivate;
+ case ICAL_CLASS_CONFIDENTIAL : return olConfidential;
+ default : return olNormal;
+ }
+}
+
+static int
+get_priority_from_prop (uint32_t prop)
+{
+ switch (prop) {
+ case PRIORITY_LOW : return 7;
+ case PRIORITY_HIGH : return 1;
+ case PRIORITY_NORMAL :
+ default : return 5;
+ }
+}
+
+static uint32_t
+get_prop_from_priority (int priority)
+{
+ if (priority > 0 && priority <= 4)
+ return PRIORITY_HIGH;
+ else if (priority > 5 && priority <= 9)
+ return PRIORITY_LOW;
+ else
+ return PRIORITY_NORMAL;
+}
+
+void
+exchange_mapi_cal_util_fetch_attachments (ECalComponent *comp, GSList **attach_list, const char *local_store)
+{
+ GSList *comp_attach_list = NULL, *new_attach_list = NULL;
+ GSList *l;
+ char *dest_file;
+ int fd;
+ const char *uid;
+
+ e_cal_component_get_attachment_list (comp, &comp_attach_list);
+ e_cal_component_get_uid (comp, &uid);
+
+ for (l = comp_attach_list; l ; l = l->next) {
+ gchar *sfname = (gchar *) l->data;
+ gchar *filename, *new_filename;
+ GMappedFile *mapped_file;
+ GError *error = NULL;
+ guint filelength = 0;
+
+ mapped_file = g_mapped_file_new (sfname, FALSE, &error);
+ if (!mapped_file) {
+ g_message ("DEBUG: could not map %s: %s\n", sfname, error->message);
+ g_error_free (error);
+ continue;
+ }
+
+ filename = g_path_get_basename (sfname);
+ new_filename = g_strconcat (uid, "-", filename, NULL);
+ g_free (filename);
+ dest_file = g_build_filename (local_store, new_filename, NULL);
+ g_free (new_filename);
+
+ filelength = g_mapped_file_get_length (mapped_file);
+
+ fd = g_open (dest_file, O_RDWR|O_CREAT|O_TRUNC|O_BINARY, 0600);
+ if (fd == -1) {
+ /* skip gracefully */
+ g_message ("DEBUG: could not open %s for writing\n", dest_file);
+ } else if (write (fd, g_mapped_file_get_contents (mapped_file), filelength) == -1) {
+ /* skip gracefully */
+ g_message ("DEBUG: attachment write failed.\n");
+ }
+ if (fd != -1) {
+ ExchangeMAPIAttachment *attach_item;
+
+ close (fd);
+ new_attach_list = g_slist_append (new_attach_list, g_filename_to_uri (dest_file, NULL, NULL));
+
+ attach_item = g_new0 (ExchangeMAPIAttachment, 1);
+ attach_item->filename = g_path_get_basename (sfname);
+ attach_item->value = g_byte_array_sized_new (filelength);
+ attach_item->value = g_byte_array_append (attach_item->value, g_mapped_file_get_contents (mapped_file), filelength);
+ *attach_list = g_slist_append (*attach_list, attach_item);
+ }
+
+ g_mapped_file_free (mapped_file);
+ g_free (dest_file);
+ }
+
+ e_cal_component_set_attachment_list (comp, new_attach_list);
+
+ for (l = new_attach_list; l != NULL; l = l->next)
+ g_free (l->data);
+ g_slist_free (new_attach_list);
+}
+
+#define RECIP_SENDABLE 0x1
+#define RECIP_ORGANIZER 0x2
+
+void
+exchange_mapi_cal_util_fetch_recipients (ECalComponent *comp, GSList **recip_list)
+{
+ GSList *al = NULL, *l;
+
+ e_cal_component_get_attendee_list (comp, &al);
+
+ for (l = al; l != NULL; l = l->next) {
+ ECalComponentAttendee *attendee = (ECalComponentAttendee *)(l->data);
+ ExchangeMAPIRecipient *recipient = g_new0 (ExchangeMAPIRecipient, 1);
+ uint32_t val = 0;
+ const char *str = NULL;
+ if (attendee->value && !g_ascii_strncasecmp (attendee->value, "mailto:", 7))
+ recipient->email_id = (attendee->value) + 7;
+ else
+ recipient->email_id = (attendee->value);
+ recipient->in.req_lpProps = g_new0 (struct SPropValue, 5);
+ recipient->in.req_cValues = 5;
+ val = 0;
+ set_SPropValue_proptag (&(recipient->in.req_lpProps[0]), PR_SEND_INTERNET_ENCODING, (const void *)&val);
+ val = RECIP_SENDABLE;
+ set_SPropValue_proptag (&(recipient->in.req_lpProps[1]), PR_RECIPIENTS_FLAGS, (const void *)&val);
+ val = get_trackstatus_from_partstat (attendee->status);
+ set_SPropValue_proptag (&(recipient->in.req_lpProps[2]), PR_RECIPIENT_TRACKSTATUS, (const void *)&val);
+ val = get_type_from_role (attendee->role);
+ set_SPropValue_proptag (&(recipient->in.req_lpProps[3]), PR_RECIPIENT_TYPE, (const void *) &val);
+/* if (attendee->cn && *(attendee->cn))
+ str = attendee->cn;
+ else
+ str = "";
+ set_SPropValue_proptag (&(recipient->in.req_lpProps[4]), PR_RECIPIENT_DISPLAY_NAME, (const void *)(str));
+*/
+ *recip_list = g_slist_append (*recip_list, recipient);
+ }
+
+ e_cal_component_free_attendee_list (al);
+}
+
+static void
+set_attachments_to_cal_component (ECalComponent *comp, GSList *attach_list, const char *local_store)
+{
+ GSList *comp_attach_list = NULL, *l;
+ const char *uid;
+
+ e_cal_component_get_uid (comp, &uid);
+ for (l = attach_list; l ; l = l->next) {
+ ExchangeMAPIAttachment *attach_item = (ExchangeMAPIAttachment *) (l->data);
+ gchar *attach_file_url, *filename;
+ struct stat st;
+
+ attach_file_url = g_strconcat (local_store, "/", uid, "-", attach_item->filename, NULL);
+ filename = g_filename_from_uri (attach_file_url, NULL, NULL);
+
+ if (g_stat (filename, &st) == -1) {
+ int fd = g_open (filename, O_RDWR|O_CREAT|O_TRUNC|O_BINARY, 0600);
+ if (fd == -1) {
+ /* skip gracefully */
+ g_message ("DEBUG: could not open %s for writing\n", filename);
+ } else if (write (fd, attach_item->value->data, attach_item->value->len) == -1) {
+ /* skip gracefully */
+ g_message ("DEBUG: attachment write failed.\n");
+ }
+ if (fd != -1) {
+ close (fd);
+ comp_attach_list = g_slist_append (comp_attach_list, g_strdup (attach_file_url));
+ }
+ }
+
+ g_free (filename);
+ g_free (attach_file_url);
+ }
+
+ e_cal_component_set_attachment_list (comp, comp_attach_list);
+}
+
+static void
+ical_attendees_from_props (icalcomponent *ical_comp, GSList *recipients, gboolean rsvp)
+{
+ GSList *l;
+ for (l=recipients; l; l=l->next) {
+ ExchangeMAPIRecipient *recip = (ExchangeMAPIRecipient *)(l->data);
+ icalproperty *prop = NULL;
+ icalparameter *param;
+ gchar *val;
+ const uint32_t *ui32;
+ const char *str;
+ const uint32_t *flags;
+
+ if (recip->email_id)
+ val = g_strdup_printf ("MAILTO:%s", recip->email_id);
+ else
+ continue;
+
+ flags = (const uint32_t *) get_SPropValue(recip->out.all_lpProps, PR_RECIPIENTS_FLAGS);
+
+ if (flags && (*flags & RECIP_ORGANIZER)) {
+ prop = icalproperty_new_organizer (val);
+
+ /* CN */
+ str = (const char *) get_SPropValue(recip->out.all_lpProps, PR_RECIPIENT_DISPLAY_NAME);
+ if (str) {
+ param = icalparameter_new_cn (str);
+ icalproperty_add_parameter (prop, param);
+ }
+ } else {
+ prop = icalproperty_new_attendee (val);
+
+ /* CN */
+ str = (const char *) get_SPropValue(recip->out.all_lpProps, PR_RECIPIENT_DISPLAY_NAME);
+ if (str) {
+ param = icalparameter_new_cn (str);
+ icalproperty_add_parameter (prop, param);
+ }
+ /* RSVP */
+ param = icalparameter_new_rsvp (rsvp ? ICAL_RSVP_TRUE : ICAL_RSVP_FALSE);
+ icalproperty_add_parameter (prop, param);
+ /* PARTSTAT */
+ ui32 = (const uint32_t *) get_SPropValue(recip->out.all_lpProps, PR_RECIPIENT_TRACKSTATUS);
+ if (ui32) {
+ param = icalparameter_new_partstat (get_partstat_from_trackstatus (*ui32));
+ icalproperty_add_parameter (prop, param);
+ }
+ /* ROLE */
+ ui32 = (const uint32_t *) get_SPropValue(recip->out.all_lpProps, PR_RECIPIENT_TYPE);
+ if (ui32) {
+ param = icalparameter_new_role (get_role_from_type (*ui32));
+ icalproperty_add_parameter (prop, param);
+ }
+#if 0
+ /* CALENDAR USER TYPE */
+ param = icalparameter_new_cutype ();
+ icalproperty_add_parameter (prop, param);
+#endif
+ }
+
+ if (prop)
+ icalcomponent_add_property (ical_comp, prop);
+
+ g_free (val);
+ }
+}
+
+static const uint8_t GID_START_SEQ[] = {
+ 0x04, 0x00, 0x00, 0x00, 0x82, 0x00, 0xe0, 0x00,
+ 0x74, 0xc5, 0xb7, 0x10, 0x1a, 0x82, 0xe0, 0x08
+};
+
+void
+exchange_mapi_cal_util_generate_globalobjectid (gboolean is_clean, const char *uid, struct SBinary *sb)
+{
+ GByteArray *ba;
+ guint32 flag32;
+ guchar *buf = NULL;
+ gsize len;
+ d(guint32 i);
+
+ ba = g_byte_array_new ();
+
+ ba = g_byte_array_append (ba, GID_START_SEQ, (sizeof (GID_START_SEQ) / sizeof (GID_START_SEQ[0])));
+
+ /* FIXME for exceptions */
+ if (is_clean || TRUE) {
+ flag32 = 0;
+ ba = g_byte_array_append (ba, &flag32, sizeof (guint32));
+ }
+
+ /* creation time - may be all 0's */
+ flag32 = 0;
+ ba = g_byte_array_append (ba, &flag32, sizeof (guint32));
+ flag32 = 0;
+ ba = g_byte_array_append (ba, &flag32, sizeof (guint32));
+
+ /* RESERVED - should be all 0's */
+ flag32 = 0;
+ ba = g_byte_array_append (ba, &flag32, sizeof (guint32));
+ flag32 = 0;
+ ba = g_byte_array_append (ba, &flag32, sizeof (guint32));
+
+ /* FIXME: cleanup the UID first */
+
+ /* We put Evolution's UID in base64 here */
+ buf = g_base64_decode (uid, &len);
+ if (len % 2 != 0)
+ --len;
+ flag32 = len;
+
+ /* Size in bytes of the following data */
+ ba = g_byte_array_append (ba, &flag32, sizeof (guint32));
+ /* Data */
+ ba = g_byte_array_append (ba, buf, flag32);
+ g_free (buf);
+
+ sb->lpb = ba->data;
+ sb->cb = ba->len;
+
+ d(g_message ("New GlobalObjectId.. Length: %d bytes.. Hex-data follows:", ba->len));
+ d(for (i = 0; i < ba->len; i++)
+ g_print("0x%.2X ", ba->data[i]));
+
+ g_byte_array_free (ba, FALSE);
+}
+
+static gchar *
+id_to_string (GByteArray *ba)
+{
+ guint8 *ptr;
+ guint len;
+ gchar *buf = NULL;
+ guint32 flag32, i, j;
+
+ g_return_val_if_fail (ba != NULL, NULL);
+ /* MSDN docs: the globalID must have an even number of bytes */
+ if ((ba->len)%2 != 0)
+ return NULL;
+
+ ptr = ba->data;
+ len = ba->len;
+
+ /* starting seq - len = 16 bytes */
+ for (i = 0, j = 0;(i < len) && (j < sizeof (GID_START_SEQ)); ++i, ++ptr, ++j)
+ if (*ptr != GID_START_SEQ[j])
+ return NULL;
+
+ /* FIXME: for exceptions - len = 4 bytes */
+ flag32 = *((guint32 *)ptr);
+ i += sizeof (guint32);
+ if (!(i < len) || flag32 != 0)
+ return NULL;
+ ptr += sizeof (guint32);
+
+ /* Creation time - len = 8 bytes - skip it */
+ flag32 = *((guint32 *)ptr);
+ i += sizeof (guint32);
+ if (!(i < len))
+ return NULL;
+ ptr += sizeof (guint32);
+
+ flag32 = *((guint32 *)ptr);
+ i += sizeof (guint32);
+ if (!(i < len))
+ return NULL;
+ ptr += sizeof (guint32);
+
+ /* Reserved bytes - len = 8 bytes */
+ flag32 = *((guint32 *)ptr);
+ i += sizeof (guint32);
+ if (!(i < len) || flag32 != 0)
+ return NULL;
+ ptr += sizeof (guint32);
+
+ flag32 = *((guint32 *)ptr);
+ i += sizeof (guint32);
+ if (!(i < len) || flag32 != 0)
+ return NULL;
+ ptr += sizeof (guint32);
+
+ /* This is the real data */
+ flag32 = *((guint32 *)ptr);
+ i += sizeof (guint32);
+ if (!(i < len) || flag32 != (len - i))
+ return NULL;
+ ptr += sizeof (guint32);
+
+ buf = g_base64_encode (ptr, flag32);
+
+ return buf;
+}
+
+ECalComponent *
+exchange_mapi_cal_util_mapi_props_to_comp (icalcomponent_kind kind, const gchar *mid, struct mapi_SPropValue_array *properties,
+ GSList *streams, GSList *recipients, GSList *attachments,
+ const char *local_store, const icaltimezone *default_zone)
+{
+ ECalComponent *comp = NULL;
+ struct timeval t;
+ const gchar *subject = NULL;
+ const uint32_t *ui32;
+ const bool *b;
+ icalcomponent *ical_comp;
+ icalproperty *prop = NULL;
+ icalparameter *param = NULL;
+ ExchangeMAPIStream *body;
+
+ switch (kind) {
+ case ICAL_VEVENT_COMPONENT:
+ case ICAL_VTODO_COMPONENT:
+ case ICAL_VJOURNAL_COMPONENT:
+ comp = e_cal_component_new ();
+ ical_comp = icalcomponent_new (kind);
+ e_cal_component_set_icalcomponent (comp, ical_comp);
+ icalcomponent_set_uid (ical_comp, mid);
+ e_cal_component_set_uid (comp, mid);
+ break;
+ default:
+ return NULL;
+ }
+
+ subject = (const gchar *)exchange_mapi_util_find_array_propval(properties, PR_SUBJECT);
+ if (!subject)
+ subject = (const gchar *)exchange_mapi_util_find_array_propval(properties, PR_NORMALIZED_SUBJECT);
+
+ body = exchange_mapi_util_find_stream (streams, PR_BODY);
+ if (!body)
+ body = exchange_mapi_util_find_stream (streams, PR_BODY_HTML);
+ if (!body)
+ body = exchange_mapi_util_find_stream (streams, PR_HTML);
+
+ /* set dtstamp - in UTC */
+ if (get_mapi_SPropValue_array_date_timeval (&t, properties, PR_CREATION_TIME) == MAPI_E_SUCCESS)
+ icalcomponent_set_dtstamp (ical_comp, foo (t.tv_sec, 0, 0));
+
+ /* created - in UTC */
+ prop = icalproperty_new_created (icaltime_current_time_with_zone (icaltimezone_get_utc_timezone ()));
+ icalcomponent_add_property (ical_comp, prop);
+
+ /* last modified - in UTC */
+ if (get_mapi_SPropValue_array_date_timeval (&t, properties, PR_LAST_MODIFICATION_TIME) == MAPI_E_SUCCESS) {
+ prop = icalproperty_new_lastmodified (foo (t.tv_sec, 0, 0));
+ icalcomponent_add_property (ical_comp, prop);
+ }
+
+ if (subject && *subject)
+ icalcomponent_set_summary (ical_comp, subject);
+ if (body)
+ icalcomponent_set_description (ical_comp, (const char *) body->value->data);
+
+ if (icalcomponent_isa (ical_comp) == ICAL_VEVENT_COMPONENT) {
+ const char *location = NULL;
+ const gchar *dtstart_tz = NULL, *dtend_tz = NULL;
+ ExchangeMAPIStream *stream;
+
+ /* CleanGlobalObjectId */
+ stream = exchange_mapi_util_find_stream (streams, PROP_TAG(PT_BINARY, 0x0023));
+ if (stream) {
+ gchar *value = id_to_string (stream->value);
+ prop = icalproperty_new_x (value);
+ icalproperty_set_x_name (prop, "X-EVOLUTION-MAPI-CLEAN-GLOBALID");
+ icalcomponent_add_property (ical_comp, prop);
+ g_free (value);
+ }
+
+ /* GlobalObjectId */
+ stream = exchange_mapi_util_find_stream (streams, PROP_TAG(PT_BINARY, 0x0003));
+ if (stream) {
+ gchar *value = id_to_string (stream->value);
+ prop = icalproperty_new_x (value);
+ icalproperty_set_x_name (prop, "X-EVOLUTION-MAPI-GLOBALID");
+ icalcomponent_add_property (ical_comp, prop);
+ g_free (value);
+ }
+
+ location = (const char *)exchange_mapi_util_find_array_propval(properties, PROP_TAG(PT_STRING8, 0x8208));
+ if (location && *location)
+ icalcomponent_set_location (ical_comp, location);
+
+ b = (const bool *)find_mapi_SPropValue_data(properties, PROP_TAG(PT_BOOLEAN, 0x8215));
+
+ stream = exchange_mapi_util_find_stream (streams, PROP_TAG(PT_BINARY, 0x825E));
+ if (stream) {
+ gchar *buf = exchange_mapi_cal_util_bin_to_mapi_tz (stream->value);
+ dtstart_tz = exchange_mapi_cal_tz_util_get_ical_equivalent (buf);
+ g_free (buf);
+ }
+
+ if (get_mapi_SPropValue_array_date_timeval (&t, properties, PROP_TAG(PT_SYSTIME, 0x820D)) == MAPI_E_SUCCESS)
+ icalcomponent_set_dtstart (ical_comp, foo (t.tv_sec, (b && *b), icaltimezone_get_builtin_timezone_from_tzid (dtstart_tz)));
+
+ stream = exchange_mapi_util_find_stream (streams, PROP_TAG(PT_BINARY, 0x825F));
+ if (stream) {
+ gchar *buf = exchange_mapi_cal_util_bin_to_mapi_tz (stream->value);
+ dtend_tz = exchange_mapi_cal_tz_util_get_ical_equivalent (buf);
+ g_free (buf);
+ }
+
+ if (get_mapi_SPropValue_array_date_timeval (&t, properties, PROP_TAG(PT_SYSTIME, 0x820E)) == MAPI_E_SUCCESS)
+ icalcomponent_set_dtend (ical_comp, foo (t.tv_sec, (b && *b), icaltimezone_get_builtin_timezone_from_tzid (dtend_tz)));
+
+ ui32 = (const uint32_t *)find_mapi_SPropValue_data(properties, PROP_TAG(PT_LONG, 0x8205));
+ if (ui32) {
+ prop = icalproperty_new_transp (get_transp_from_prop (*ui32));
+ icalcomponent_add_property (ical_comp, prop);
+ }
+
+ b = (const bool *)find_mapi_SPropValue_data(properties, PROP_TAG(PT_BOOLEAN, 0x8223));
+ if (b && *b) {
+ /* FIXME: recurrence */
+ g_warning ("Encountered a recurring event.");
+/* stream = exchange_mapi_util_find_stream (streams, PROP_TAG(PT_BINARY, 0x8216));
+ if (stream) {
+ e_cal_backend_mapi_util_bin_to_rrule (stream->value, comp);
+ }
+*/ }
+
+ if (recipients) {
+ b = (const bool *)find_mapi_SPropValue_data(properties, PR_RESPONSE_REQUESTED);
+ ical_attendees_from_props (ical_comp, recipients, (b && *b));
+ if (icalcomponent_get_first_property (ical_comp, ICAL_ORGANIZER_PROPERTY) == NULL) {
+ gchar *val;
+// const char *sender_name = (const char *) exchange_mapi_util_find_array_propval (properties, PR_SENDER_NAME);
+ const char *sender_email_type = (const char *) exchange_mapi_util_find_array_propval (properties, PR_SENDER_ADDRTYPE);
+ const char *sender_email = (const char *) exchange_mapi_util_find_array_propval (properties, PR_SENDER_EMAIL_ADDRESS);
+ const char *sent_name = (const char *) exchange_mapi_util_find_array_propval (properties, PR_SENT_REPRESENTING_NAME);
+ const char *sent_email_type = (const char *) exchange_mapi_util_find_array_propval (properties, PR_SENT_REPRESENTING_ADDRTYPE);
+ const char *sent_email = (const char *) exchange_mapi_util_find_array_propval (properties, PR_SENT_REPRESENTING_EMAIL_ADDRESS);
+
+ if (!g_utf8_collate (sender_email_type, "EX"))
+ sender_email = exchange_mapi_util_ex_to_smtp (sender_email);
+ if (!g_utf8_collate (sent_email_type, "EX"))
+ sent_email = exchange_mapi_util_ex_to_smtp (sent_email);
+
+ val = g_strdup_printf ("MAILTO:%s", sent_email);
+ prop = icalproperty_new_organizer (val);
+ g_free (val);
+ /* CN */
+ param = icalparameter_new_cn (sent_name);
+ icalproperty_add_parameter (prop, param);
+ /* SENTBY */
+ if (g_utf8_collate (sent_email, sender_email)) {
+ val = g_strdup_printf ("MAILTO:%s", sender_email);
+ param = icalparameter_new_sentby (val);
+ icalproperty_add_parameter (prop, param);
+ g_free (val);
+ }
+
+ icalcomponent_add_property (ical_comp, prop);
+ }
+ }
+
+ b = (const bool *)find_mapi_SPropValue_data(properties, PROP_TAG(PT_BOOLEAN, 0x8503));
+ if (b && *b) {
+ struct timeval start, displaytime;
+
+ if ((get_mapi_SPropValue_array_date_timeval (&start, properties, PROP_TAG(PT_SYSTIME, 0x8502)) == MAPI_E_SUCCESS)
+ && (get_mapi_SPropValue_array_date_timeval (&displaytime, properties, PROP_TAG(PT_SYSTIME, 0x8560)) == MAPI_E_SUCCESS)) {
+ ECalComponentAlarm *e_alarm = e_cal_component_alarm_new ();
+ ECalComponentAlarmTrigger trigger;
+
+ trigger.type = E_CAL_COMPONENT_ALARM_TRIGGER_RELATIVE_START;
+ trigger.u.rel_duration = icaltime_subtract (icaltime_from_timet_with_zone (displaytime.tv_sec, 0, 0),
+ icaltime_from_timet_with_zone (start.tv_sec, 0, 0));
+
+ e_cal_component_alarm_set_action (e_alarm, E_CAL_COMPONENT_ALARM_DISPLAY);
+ e_cal_component_alarm_set_trigger (e_alarm, trigger);
+
+ e_cal_component_add_alarm (comp, e_alarm);
+ }
+ } else
+ e_cal_component_remove_all_alarms (comp);
+
+ } else if (icalcomponent_isa (ical_comp) == ICAL_VTODO_COMPONENT) {
+ const double *complete = 0;
+
+ /* NOTE: Exchange tasks are DATE values, not DATE-TIME values, but maybe someday, we could expect Exchange to support it ;) */
+ if (get_mapi_SPropValue_array_date_timeval (&t, properties, PROP_TAG(PT_SYSTIME, 0x8104)) == MAPI_E_SUCCESS)
+ icalcomponent_set_dtstart (ical_comp, foo (t.tv_sec, 1, default_zone));
+ if (get_mapi_SPropValue_array_date_timeval (&t, properties, PROP_TAG(PT_SYSTIME, 0x8105)) == MAPI_E_SUCCESS)
+ icalcomponent_set_due (ical_comp, foo (t.tv_sec, 1, default_zone));
+
+ ui32 = (const uint32_t *)find_mapi_SPropValue_data(properties, PROP_TAG(PT_LONG, 0x8101));
+ if (ui32) {
+ icalcomponent_set_status (ical_comp, get_taskstatus_from_prop(*ui32));
+ if (*ui32 == olTaskComplete
+ && get_mapi_SPropValue_array_date_timeval (&t, properties, PROP_TAG(PT_SYSTIME, 0x810F)) == MAPI_E_SUCCESS) {
+ prop = icalproperty_new_completed (foo (t.tv_sec, 1, default_zone));
+ icalcomponent_add_property (ical_comp, prop);
+ }
+ }
+
+ complete = (const double *)find_mapi_SPropValue_data(properties, PROP_TAG(PT_DOUBLE, 0x8102));
+ if (complete) {
+ prop = icalproperty_new_percentcomplete ((int)(*complete * 100));
+ icalcomponent_add_property (ical_comp, prop);
+ }
+
+ b = (const bool *)find_mapi_SPropValue_data(properties, PROP_TAG(PT_BOOLEAN, 0x8126));
+ if (b && *b) {
+ /* FIXME: Evolution does not support recurring tasks */
+ g_warning ("Encountered a recurring task.");
+ }
+
+ b = (const bool *)find_mapi_SPropValue_data(properties, PROP_TAG(PT_BOOLEAN, 0x8503));
+ if (b && *b) {
+ struct timeval abs;
+
+ if (get_mapi_SPropValue_array_date_timeval (&abs, properties, PROP_TAG(PT_SYSTIME, 0x8502)) == MAPI_E_SUCCESS) {
+ ECalComponentAlarm *e_alarm = e_cal_component_alarm_new ();
+ ECalComponentAlarmTrigger trigger;
+
+ trigger.type = E_CAL_COMPONENT_ALARM_TRIGGER_ABSOLUTE;
+ trigger.u.abs_time = icaltime_from_timet_with_zone (abs.tv_sec, 0, 0);
+
+ e_cal_component_alarm_set_action (e_alarm, E_CAL_COMPONENT_ALARM_DISPLAY);
+ e_cal_component_alarm_set_trigger (e_alarm, trigger);
+
+ e_cal_component_add_alarm (comp, e_alarm);
+ }
+ } else
+ e_cal_component_remove_all_alarms (comp);
+
+ } else if (icalcomponent_isa (ical_comp) == ICAL_VJOURNAL_COMPONENT) {
+ if (get_mapi_SPropValue_array_date_timeval (&t, properties, PR_LAST_MODIFICATION_TIME) == MAPI_E_SUCCESS)
+ icalcomponent_set_dtstart (ical_comp, foo (t.tv_sec, TRUE, default_zone));
+ }
+
+ if (icalcomponent_isa (ical_comp) == ICAL_VEVENT_COMPONENT || icalcomponent_isa (ical_comp) == ICAL_VTODO_COMPONENT) {
+ /* priority */
+ ui32 = (const uint32_t *)find_mapi_SPropValue_data(properties, PR_PRIORITY);
+ if (ui32) {
+ prop = icalproperty_new_priority (get_priority_from_prop (*ui32));
+ icalcomponent_add_property (ical_comp, prop);
+ }
+ }
+
+ /* classification */
+ ui32 = (const uint32_t *)find_mapi_SPropValue_data(properties, PR_SENSITIVITY);
+ if (ui32) {
+ prop = icalproperty_new_class (get_class_from_prop (*ui32));
+ icalcomponent_add_property (ical_comp, prop);
+ }
+
+ /* FIXME: categories */
+
+ set_attachments_to_cal_component (comp, attachments, local_store);
+
+ e_cal_component_rescan (comp);
+
+ return comp;
+}
+
+#define COMMON_NAMED_PROPS_N 8
+
+typedef enum
+{
+ I_COMMON_REMMINS = 0 ,
+ I_COMMON_REMTIME ,
+ I_COMMON_REMSET ,
+ I_COMMON_ISPRIVATE ,
+ I_COMMON_SIDEEFFECTS ,
+ I_COMMON_START ,
+ I_COMMON_END ,
+ I_COMMON_REMNEXTTIME
+} CommonNamedPropsIndex;
+
+gboolean
+exchange_mapi_cal_util_build_name_id (struct mapi_nameid *nameid, gpointer data)
+{
+ icalcomponent_kind kind = GPOINTER_TO_INT (data);
+
+ /* NOTE: Avoid using mapi_nameid_OOM_add because:
+ * a) its inefficient (uses strcmp)
+ * b) names may vary in different server/libmapi versions
+ */
+
+ mapi_nameid_lid_add(nameid, 0x8501, PSETID_Common); // PT_LONG - ReminderMinutesBeforeStart
+ mapi_nameid_lid_add(nameid, 0x8502, PSETID_Common); // PT_SYSTIME - ReminderTime
+ mapi_nameid_lid_add(nameid, 0x8503, PSETID_Common); // PT_BOOLEAN - ReminderSet
+ mapi_nameid_lid_add(nameid, 0x8506, PSETID_Common); // PT_BOOLEAN - Private
+ mapi_nameid_lid_add(nameid, 0x8510, PSETID_Common); // PT_LONG - (context menu flags)
+ mapi_nameid_lid_add(nameid, 0x8516, PSETID_Common); // PT_SYSTIME - CommonStart
+ mapi_nameid_lid_add(nameid, 0x8517, PSETID_Common); // PT_SYSTIME - CommonEnd
+ mapi_nameid_lid_add(nameid, 0x8560, PSETID_Common); // PT_SYSTIME - ReminderNextTime
+
+ if (kind == ICAL_VEVENT_COMPONENT)
+ appt_build_name_id (nameid);
+ else if (kind == ICAL_VTODO_COMPONENT)
+ task_build_name_id (nameid);
+ else if (kind == ICAL_VJOURNAL_COMPONENT)
+ note_build_name_id (nameid);
+
+ return TRUE;
+}
+
+/**
+ * NOTE: The enumerations '(Appt/Task/Note)NamedPropsIndex' have been defined
+ * only to make life a little easier for developers. Here's the logic
+ * behind the definition:
+ 1) The first element is initialized with 'COMMON_NAMED_PROPS_N' : When
+ adding named props, we add the common named props first and then the
+ specific named props. So.. the index of the first specific
+ named property = COMMON_NAMED_PROPS_N
+ 2) The order in the enumeration 'must' be the same as that in the routine
+ which adds the specific named props - (appt/task/note)_build_name_id
+ 3) If a specific named prop is added/deleted, an index needs to
+ be created/deleted at the correct position. [Don't forget to update
+ (APPT/TASK/NOTE)_NAMED_PROPS_N].
+
+ * To summarize the pros:
+ 1) Addition/deletion of a common-named-prop would not affect the indexes
+ of the specific named props once COMMON_NAMED_PROPS_N is updated.
+ 2) Values of named props can be added in any order.
+ */
+
+
+#define APPT_NAMED_PROPS_N 31
+#define DEFAULT_APPT_REMINDER_MINS 15
+
+typedef enum
+{
+ I_APPT_SEQ = COMMON_NAMED_PROPS_N ,
+ I_APPT_SEQTIME ,
+ I_APPT_BUSYSTATUS ,
+ I_APPT_LOCATION ,
+ I_APPT_START ,
+ I_APPT_END ,
+ I_APPT_DURATION ,
+ I_APPT_ALLDAY ,
+/**/ I_APPT_RECURBLOB ,
+ I_APPT_MEETINGSTATUS ,
+ I_APPT_RESPONSESTATUS ,
+ I_APPT_RECURRING ,
+ I_APPT_INTENDEDBUSY ,
+/**/ I_APPT_RECURBASE ,
+ I_APPT_INVITED ,
+/**/ I_APPT_RECURTYPE ,
+/**/ I_APPT_RECURPATTERN ,
+ I_APPT_CLIPSTART ,
+ I_APPT_CLIPEND ,
+ I_APPT_AUTOLOCATION ,
+ I_APPT_ISONLINEMEET ,
+ I_APPT_COUNTERPROPOSAL ,
+ I_APPT_STARTTZBLOB ,
+ I_APPT_ENDTZBLOB ,
+
+ I_MEET_WHERE ,
+ I_MEET_GUID ,
+ I_MEET_ISRECURRING ,
+ I_MEET_ISEXCEPTION ,
+ I_MEET_CLEANGUID ,
+ I_MEET_APPTMSGCLASS ,
+ I_MEET_TYPE
+
+// I_SENDASICAL ,
+// I_APPT_LABEL ,
+// I_APPT_DISPTZ
+// I_APPT_ALLATTENDEES ,
+// I_APPT_TOATTENDEES ,
+// I_APPT_CCATTENDEES ,
+} ApptNamedPropsIndex;
+
+static void
+appt_build_name_id (struct mapi_nameid *nameid)
+{
+ mapi_nameid_lid_add(nameid, 0x8201, PSETID_Appointment); // PT_LONG - ApptSequence
+ mapi_nameid_lid_add(nameid, 0x8202, PSETID_Appointment); // PT_SYSTIME - ApptSequenceTime
+ mapi_nameid_lid_add(nameid, 0x8205, PSETID_Appointment); // PT_LONG - BusyStatus
+ mapi_nameid_lid_add(nameid, 0x8208, PSETID_Appointment); // PT_STRING8 - Location
+ mapi_nameid_lid_add(nameid, 0x820D, PSETID_Appointment); // PT_SYSTIME - Start/ApptStartWhole
+ mapi_nameid_lid_add(nameid, 0x820E, PSETID_Appointment); // PT_SYSTIME - End/ApptEndWhole
+ mapi_nameid_lid_add(nameid, 0x8213, PSETID_Appointment); // PT_LONG - Duration/ApptDuration
+ mapi_nameid_lid_add(nameid, 0x8215, PSETID_Appointment); // PT_BOOLEAN - AllDayEvent (also called ApptSubType)
+ mapi_nameid_lid_add(nameid, 0x8216, PSETID_Appointment); // PT_BINARY - (recurrence blob)
+ mapi_nameid_lid_add(nameid, 0x8217, PSETID_Appointment); // PT_LONG - MeetingStatus
+ mapi_nameid_lid_add(nameid, 0x8218, PSETID_Appointment); // PT_LONG - ResponseStatus
+ mapi_nameid_lid_add(nameid, 0x8223, PSETID_Appointment); // PT_BOOLEAN - Recurring
+ mapi_nameid_lid_add(nameid, 0x8224, PSETID_Appointment); // PT_LONG - IntendedBusyStatus
+ mapi_nameid_lid_add(nameid, 0x8228, PSETID_Appointment); // PT_SYSTIME - RecurrenceBase
+ mapi_nameid_lid_add(nameid, 0x8229, PSETID_Appointment); // PT_BOOLEAN - FInvited
+ mapi_nameid_lid_add(nameid, 0x8231, PSETID_Appointment); // PT_LONG - RecurrenceType
+ mapi_nameid_lid_add(nameid, 0x8232, PSETID_Appointment); // PT_STRING8 - RecurrencePattern
+ mapi_nameid_lid_add(nameid, 0x8235, PSETID_Appointment); // PT_SYSTIME - (dtstart)(for recurring events UTC 12 AM of day of start)
+ mapi_nameid_lid_add(nameid, 0x8236, PSETID_Appointment); // PT_SYSTIME - (dtend)(for recurring events UTC 12 AM of day of end)
+ mapi_nameid_lid_add(nameid, 0x823A, PSETID_Appointment); // PT_BOOLEAN - AutoFillLocation
+ mapi_nameid_lid_add(nameid, 0x8240, PSETID_Appointment); // PT_BOOLEAN - IsOnlineMeeting
+ mapi_nameid_lid_add(nameid, 0x8257, PSETID_Appointment); // PT_BOOLEAN - ApptCounterProposal
+ mapi_nameid_lid_add(nameid, 0x825E, PSETID_Appointment); // PT_BINARY - (timezone for dtstart)
+ mapi_nameid_lid_add(nameid, 0x825F, PSETID_Appointment); // PT_BINARY - (timezone for dtend)
+
+ mapi_nameid_lid_add(nameid, 0x0002, PSETID_Meeting); // PT_STRING8 - Where
+ mapi_nameid_lid_add(nameid, 0x0003, PSETID_Meeting); // PT_BINARY - GlobalObjectId
+ mapi_nameid_lid_add(nameid, 0x0005, PSETID_Meeting); // PT_BOOLEAN - IsRecurring
+ mapi_nameid_lid_add(nameid, 0x000a, PSETID_Meeting); // PT_BOOLEAN - IsException
+ mapi_nameid_lid_add(nameid, 0x0023, PSETID_Meeting); // PT_BINARY - CleanGlobalObjectId
+ mapi_nameid_lid_add(nameid, 0x0024, PSETID_Meeting); // PT_STRING8 - AppointmentMessageClass
+ mapi_nameid_lid_add(nameid, 0x0026, PSETID_Meeting); // PT_LONG - MeetingType
+
+ /* These probably would never be used from Evolution */
+// mapi_nameid_lid_add(nameid, 0x8200, PSETID_Appointment); // PT_BOOLEAN - SendAsICAL
+// mapi_nameid_lid_add(nameid, 0x8214, PSETID_Appointment); // PT_LONG - Label
+// mapi_nameid_lid_add(nameid, 0x8234, PSETID_Appointment); // PT_STRING8 - display TimeZone
+// mapi_nameid_lid_add(nameid, 0x8238, PSETID_Appointment); // PT_STRING8 - AllAttendees
+// mapi_nameid_lid_add(nameid, 0x823B, PSETID_Appointment); // PT_STRING8 - ToAttendeesString (dupe PR_DISPLAY_TO)
+// mapi_nameid_lid_add(nameid, 0x823C, PSETID_Appointment); // PT_STRING8 - CCAttendeesString (dupe PR_DISPLAY_CC)
+}
+
+#define TASK_NAMED_PROPS_N 13
+#define DEFAULT_TASK_REMINDER_MINS 1080
+
+typedef enum
+{
+ I_TASK_STATUS = COMMON_NAMED_PROPS_N ,
+ I_TASK_PERCENT ,
+ I_TASK_ISTEAMTASK ,
+ I_TASK_START ,
+ I_TASK_DUE ,
+ I_TASK_COMPLETED ,
+// I_TASK_RECURBLOB ,
+ I_TASK_ISCOMPLETE ,
+ I_TASK_OWNER ,
+ I_TASK_DELEGATOR ,
+ I_TASK_ISRECURRING ,
+ I_TASK_ROLE ,
+ I_TASK_OWNERSHIP ,
+ I_TASK_DELEGATIONSTATE ,
+// I_TASK_ACTUALWORK ,
+// I_TASK_TOTALWORK
+} TaskNamedPropsIndex;
+
+static void
+task_build_name_id (struct mapi_nameid *nameid)
+{
+ mapi_nameid_lid_add(nameid, 0x8101, PSETID_Task); // PT_LONG - Status
+ mapi_nameid_lid_add(nameid, 0x8102, PSETID_Task); // PT_DOUBLE - PercentComplete
+ mapi_nameid_lid_add(nameid, 0x8103, PSETID_Task); // PT_BOOLEAN - TeamTask
+ mapi_nameid_lid_add(nameid, 0x8104, PSETID_Task); // PT_SYSTIME - StartDate/TaskStartDate
+ mapi_nameid_lid_add(nameid, 0x8105, PSETID_Task); // PT_SYSTIME - DueDate/TaskDueDate
+ mapi_nameid_lid_add(nameid, 0x810F, PSETID_Task); // PT_SYSTIME - DateCompleted
+// mapi_nameid_lid_add(nameid, 0x8116, PSETID_Task); // PT_BINARY - (recurrence blob)
+ mapi_nameid_lid_add(nameid, 0x811C, PSETID_Task); // PT_BOOLEAN - Complete
+ mapi_nameid_lid_add(nameid, 0x811F, PSETID_Task); // PT_STRING8 - Owner
+ mapi_nameid_lid_add(nameid, 0x8121, PSETID_Task); // PT_STRING8 - Delegator
+ mapi_nameid_lid_add(nameid, 0x8126, PSETID_Task); // PT_BOOLEAN - IsRecurring/TaskFRecur
+ mapi_nameid_lid_add(nameid, 0x8127, PSETID_Task); // PT_STRING8 - Role
+ mapi_nameid_lid_add(nameid, 0x8129, PSETID_Task); // PT_LONG - Ownership
+ mapi_nameid_lid_add(nameid, 0x812A, PSETID_Task); // PT_LONG - DelegationState
+
+ /* These probably would never be used from Evolution */
+// mapi_nameid_lid_add(nameid, 0x8110, PSETID_Task); // PT_LONG - ActualWork/TaskActualEffort
+// mapi_nameid_lid_add(nameid, 0x8111, PSETID_Task); // PT_LONG - TotalWork/TaskEstimatedEffort
+}
+
+
+#define NOTE_NAMED_PROPS_N 0
+
+/*
+typedef enum
+{
+// I_NOTE_COLOR
+} NoteNamedPropsIndex;
+*/
+
+static void
+note_build_name_id (struct mapi_nameid *nameid)
+{
+ /* These probably would never be used from Evolution */
+// mapi_nameid_lid_add(nameid, 0x8B00, PSETID_Note); // PT_LONG - Color
+}
+
+#define MINUTES_IN_HOUR 60
+#define SECS_IN_MINUTE 60
+
+/**
+ * NOTE: When a new regular property (PR_***) is added, 'REGULAR_PROPS_N'
+ * should be updated.
+ */
+#define REGULAR_PROPS_N 21
+
+int
+exchange_mapi_cal_util_build_props (struct SPropValue **value, struct SPropTagArray *proptag_array, gpointer data)
+{
+ struct cbdata *cbdata = (struct cbdata *) data;
+ ECalComponent *comp = cbdata->comp;
+ icalcomponent *ical_comp = e_cal_component_get_icalcomponent (comp);
+ icalcomponent_kind kind = icalcomponent_isa (ical_comp);
+ gboolean has_attendees = e_cal_component_has_attendees (comp);
+ struct SPropValue *props = NULL;
+ int i=0;
+ uint32_t flag32;
+ bool b;
+ icalproperty *prop;
+ struct icaltimetype dtstart, dtend, utc_dtstart, utc_dtend;
+ const icaltimezone *utc_zone;
+ const char *dtstart_tzid, *dtend_tzid, *text = NULL;
+ const char *uid = NULL;
+ struct timeval t;
+
+ switch (kind) {
+ case ICAL_VEVENT_COMPONENT:
+ props = g_new0 (struct SPropValue, REGULAR_PROPS_N + COMMON_NAMED_PROPS_N + APPT_NAMED_PROPS_N);
+ g_print ("\nAllocating space for %d props\n", REGULAR_PROPS_N + COMMON_NAMED_PROPS_N + APPT_NAMED_PROPS_N);
+ set_SPropValue_proptag(&props[i++], proptag_array->aulPropTag[I_MEET_APPTMSGCLASS], (const void *) "IPM.Appointment");
+ if (has_attendees) {
+ if (cbdata->meeting_type & MEETING_OBJECT)
+ set_SPropValue_proptag(&props[i++], PR_MESSAGE_CLASS, (const void *) "IPM.Appointment");
+ else if (cbdata->meeting_type & MEETING_REQUEST)
+ set_SPropValue_proptag(&props[i++], PR_MESSAGE_CLASS, (const void *) "IPM.Schedule.Meeting.Request");
+ else
+ set_SPropValue_proptag(&props[i++], PR_MESSAGE_CLASS, (const void *) "IPM.Appointment");
+ } else
+ set_SPropValue_proptag(&props[i++], PR_MESSAGE_CLASS, (const void *) "IPM.Appointment");
+ break;
+ case ICAL_VTODO_COMPONENT:
+ props = g_new0 (struct SPropValue, REGULAR_PROPS_N + COMMON_NAMED_PROPS_N + TASK_NAMED_PROPS_N);
+ g_print ("\nAllocating space for %d props\n", REGULAR_PROPS_N + COMMON_NAMED_PROPS_N + TASK_NAMED_PROPS_N);
+ set_SPropValue_proptag(&props[i++], PR_MESSAGE_CLASS, (const void *) "IPM.Task");
+ break;
+ case ICAL_VJOURNAL_COMPONENT:
+ props = g_new0 (struct SPropValue, REGULAR_PROPS_N + COMMON_NAMED_PROPS_N + NOTE_NAMED_PROPS_N);
+ g_print ("\nAllocating space for %d props\n", REGULAR_PROPS_N + COMMON_NAMED_PROPS_N + NOTE_NAMED_PROPS_N);
+ set_SPropValue_proptag(&props[i++], PR_MESSAGE_CLASS, (const void *) "IPM.StickyNote");
+ break;
+ default:
+ return 0;
+ } /* prop count: 1 */
+
+ utc_zone = icaltimezone_get_utc_timezone ();
+
+ dtstart = icalcomponent_get_dtstart (ical_comp);
+
+ /* For VEVENTs */
+ if (icalcomponent_get_first_property (ical_comp, ICAL_DTEND_PROPERTY) != 0)
+ dtend = icalcomponent_get_dtend (ical_comp);
+ /* For VTODOs */
+ else if (icalcomponent_get_first_property (ical_comp, ICAL_DUE_PROPERTY) != 0)
+ dtend = icalcomponent_get_due (ical_comp);
+ else
+ dtend = icalcomponent_get_dtstart (ical_comp);
+
+ dtstart_tzid = icaltime_get_tzid (dtstart);
+ dtend_tzid = icaltime_get_tzid (dtend);
+
+ utc_dtstart = icaltime_convert_to_zone (dtstart, utc_zone);
+ utc_dtend = icaltime_convert_to_zone (dtend, utc_zone);
+
+ /* FIXME: convert to unicode */
+ text = icalcomponent_get_summary (ical_comp);
+ if (!(text && *text))
+ text = "";
+ set_SPropValue_proptag(&props[i++], PR_SUBJECT, /* prop count: 2 */
+ (const void *) text);
+ set_SPropValue_proptag(&props[i++], PR_NORMALIZED_SUBJECT, /* prop count: 3 */
+ (const void *) text);
+ set_SPropValue_proptag(&props[i++], PR_CONVERSATION_TOPIC, /* prop count: 4 */
+ (const void *) text);
+ text = NULL;
+
+ /* we don't support HTML event/task/memo editor */
+ flag32 = olEditorText;
+ set_SPropValue_proptag(&props[i++], PR_MSG_EDITOR_FORMAT, &flag32); /* prop count: 5 */
+
+ /* it'd be better to convert, then set it in unicode */
+ text = icalcomponent_get_description (ical_comp);
+ if (!(text && *text))
+ text = "";
+ set_SPropValue_proptag(&props[i++], PR_BODY, /* prop count: 6 */
+ (const void *) text);
+ text = NULL;
+
+ /* Priority */
+ flag32 = PRIORITY_NORMAL; /* default */
+ prop = icalcomponent_get_first_property (ical_comp, ICAL_PRIORITY_PROPERTY);
+ if (prop)
+ flag32 = get_prop_from_priority (icalproperty_get_priority (prop));
+ set_SPropValue_proptag(&props[i++], PR_PRIORITY, (const void *) &flag32); /* prop count: 7 */
+
+ set_SPropValue_proptag(&props[i++], PR_SENT_REPRESENTING_NAME,
+ (const void *) cbdata->ownerid);
+ text = "SMTP";
+ set_SPropValue_proptag(&props[i++], PR_SENT_REPRESENTING_ADDRTYPE,
+ (const void *) text);
+ set_SPropValue_proptag(&props[i++], PR_SENT_REPRESENTING_EMAIL_ADDRESS,
+ (const void *) cbdata->ownername);
+ set_SPropValue_proptag(&props[i++], PR_SENDER_NAME,
+ (const void *) cbdata->username);
+ text = "SMTP";
+ set_SPropValue_proptag(&props[i++], PR_SENDER_ADDRTYPE,
+ (const void *) text);
+ set_SPropValue_proptag(&props[i++], PR_SENDER_EMAIL_ADDRESS,
+ (const void *) cbdata->userid); /* prop count: 13 */
+
+ flag32 = cbdata->msgflags;
+ set_SPropValue_proptag(&props[i++], PR_MESSAGE_FLAGS, (const void *) &flag32); /* prop count: 14 */
+
+ flag32 = 0x0;
+ b = e_cal_component_has_alarms (comp);
+ if (b) {
+ /* We know there would be only a single alarm of type:DISPLAY [static properties of the backend] */
+ GList *alarm_uids = e_cal_component_get_alarm_uids (comp);
+ ECalComponentAlarm *alarm = e_cal_component_get_alarm (comp, (const char *)(alarm_uids->data));
+ ECalComponentAlarmAction action;
+ e_cal_component_alarm_get_action (alarm, &action);
+ if (action == E_CAL_COMPONENT_ALARM_DISPLAY) {
+ ECalComponentAlarmTrigger trigger;
+ e_cal_component_alarm_get_trigger (alarm, &trigger);
+ switch (trigger.type) {
+ case E_CAL_COMPONENT_ALARM_TRIGGER_RELATIVE_START :
+ flag32 = (icaldurationtype_as_int (trigger.u.rel_duration)) / SECS_IN_MINUTE;
+ /* we cannot set an alarm to popup after the start of an appointment on Exchange */
+ flag32 = (flag32 < 0) ? -(flag32) : 0;
+ break;
+ default :
+ break;
+ }
+ }
+ e_cal_component_alarm_free (alarm);
+ cal_obj_uid_list_free (alarm_uids);
+ }
+ if (!flag32)
+ switch (kind) {
+ case ICAL_VEVENT_COMPONENT:
+ flag32 = DEFAULT_APPT_REMINDER_MINS;
+ break;
+ case ICAL_VTODO_COMPONENT:
+ flag32 = DEFAULT_TASK_REMINDER_MINS;
+ break;
+ default:
+ break;
+ }
+ set_SPropValue_proptag(&props[i++], proptag_array->aulPropTag[I_COMMON_REMSET], (const void *) &b);
+ set_SPropValue_proptag(&props[i++], proptag_array->aulPropTag[I_COMMON_REMMINS], (const void *) &flag32);
+ t.tv_sec = icaltime_as_timet (utc_dtstart);
+ t.tv_usec = 0;
+ set_SPropValue_proptag_date_timeval(&props[i++], proptag_array->aulPropTag[I_COMMON_REMTIME], &t);
+ t.tv_sec = icaltime_as_timet (utc_dtstart) - (flag32 * SECS_IN_MINUTE);
+ t.tv_usec = 0;
+ /* ReminderNextTime: FIXME for recurrence */
+ set_SPropValue_proptag_date_timeval(&props[i++], proptag_array->aulPropTag[I_COMMON_REMNEXTTIME], &t);
+ /* prop count: 14 (no regular props added) */
+ /* Sensitivity, Private */
+ flag32 = olNormal; /* default */
+ b = 0; /* default */
+ prop = icalcomponent_get_first_property (ical_comp, ICAL_CLASS_PROPERTY);
+ if (prop)
+ flag32 = get_prop_from_class (icalproperty_get_class (prop));
+ if (flag32 == olPrivate || flag32 == olConfidential)
+ b = 1;
+ set_SPropValue_proptag(&props[i++], PR_SENSITIVITY, (const void *) &flag32); /* prop count: 15 */
+ set_SPropValue_proptag(&props[i++], proptag_array->aulPropTag[I_COMMON_ISPRIVATE], (const void *) &b);
+
+ t.tv_sec = icaltime_as_timet (utc_dtstart);
+ t.tv_usec = 0;
+ set_SPropValue_proptag_date_timeval(&props[i++], proptag_array->aulPropTag[I_COMMON_START], &t);
+ set_SPropValue_proptag_date_timeval(&props[i++], PR_START_DATE, &t); /* prop count: 16 */
+
+ t.tv_sec = icaltime_as_timet (utc_dtend);
+ t.tv_usec = 0;
+ set_SPropValue_proptag_date_timeval(&props[i++], proptag_array->aulPropTag[I_COMMON_END], &t);
+ set_SPropValue_proptag_date_timeval(&props[i++], PR_END_DATE, &t); /* prop count: 17 */
+
+ b = 1;
+ set_SPropValue_proptag(&props[i++], PR_RESPONSE_REQUESTED, (const void *) &b); /* prop count: 18 */
+
+ /* PR_OWNER_APPT_ID needs to be set in certain cases only */ /* prop count: 19 */
+ /* PR_ICON_INDEX needs to be set appropriately */ /* prop count: 20 */
+
+ b = 0;
+ set_SPropValue_proptag(&props[i++], PR_RTF_IN_SYNC, (const void *) &b); /* prop count: 21 */
+
+ if (kind == ICAL_VEVENT_COMPONENT) {
+ const char *mapi_tzid;
+ struct SBinary start_tz, end_tz, globalid;
+
+ /* Busy Status */
+ flag32 = olBusy; /* default */
+ prop = icalcomponent_get_first_property (ical_comp, ICAL_TRANSP_PROPERTY);
+ if (prop)
+ flag32 = get_prop_from_transp (icalproperty_get_transp (prop));
+ set_SPropValue_proptag(&props[i++], proptag_array->aulPropTag[I_APPT_INTENDEDBUSY], (const void *) &flag32);
+ if (cbdata->meeting_type == MEETING_REQUEST) {
+ flag32 = olTentative;
+ set_SPropValue_proptag(&props[i++], proptag_array->aulPropTag[I_APPT_BUSYSTATUS], (const void *) &flag32);
+ } else
+ set_SPropValue_proptag(&props[i++], proptag_array->aulPropTag[I_APPT_BUSYSTATUS], (const void *) &flag32);
+
+ /* Location */
+ text = icalcomponent_get_location (ical_comp);
+ if (!(text && *text))
+ text = "";
+ set_SPropValue_proptag(&props[i++], proptag_array->aulPropTag[I_APPT_LOCATION], (const void *) text);
+ set_SPropValue_proptag(&props[i++], proptag_array->aulPropTag[I_MEET_WHERE], (const void *) text);
+ text = NULL;
+ /* Auto-Location is always FALSE - Evolution doesn't work that way */
+ b = 0;
+ set_SPropValue_proptag(&props[i++], proptag_array->aulPropTag[I_APPT_AUTOLOCATION], (const void *) &b);
+
+ /* Start */
+ t.tv_sec = icaltime_as_timet (utc_dtstart);
+ t.tv_usec = 0;
+ set_SPropValue_proptag_date_timeval(&props[i++], proptag_array->aulPropTag[I_APPT_START], &t);
+ /* FIXME: for recurrence */
+ set_SPropValue_proptag_date_timeval(&props[i++], proptag_array->aulPropTag[I_APPT_CLIPSTART], &t);
+
+ /* Start TZ */
+ mapi_tzid = exchange_mapi_cal_tz_util_get_mapi_equivalent ((dtstart_tzid && *dtstart_tzid) ? dtstart_tzid : "UTC");
+ if (mapi_tzid && *mapi_tzid) {
+ exchange_mapi_cal_util_mapi_tz_to_bin (mapi_tzid, &start_tz);
+ set_SPropValue_proptag(&props[i++], proptag_array->aulPropTag[I_APPT_STARTTZBLOB], (const void *) &start_tz);
+ }
+
+ /* End */
+ t.tv_sec = icaltime_as_timet (utc_dtend);
+ t.tv_usec = 0;
+ set_SPropValue_proptag_date_timeval(&props[i++], proptag_array->aulPropTag[I_APPT_END], &t);
+ /* FIXME: for recurrence */
+ set_SPropValue_proptag_date_timeval(&props[i++], proptag_array->aulPropTag[I_APPT_CLIPEND], &t);
+
+ /* End TZ */
+ mapi_tzid = exchange_mapi_cal_tz_util_get_mapi_equivalent ((dtend_tzid && *dtend_tzid) ? dtend_tzid : "UTC");
+ if (mapi_tzid && *mapi_tzid) {
+ exchange_mapi_cal_util_mapi_tz_to_bin (mapi_tzid, &end_tz);
+ set_SPropValue_proptag(&props[i++], proptag_array->aulPropTag[I_APPT_ENDTZBLOB], (const void *) &end_tz);
+ }
+
+ /* Duration */
+ flag32 = icaldurationtype_as_int (icaltime_subtract (dtend, dtstart));
+ flag32 /= MINUTES_IN_HOUR;
+ set_SPropValue_proptag(&props[i++], proptag_array->aulPropTag[I_APPT_DURATION], (const void *) &flag32);
+
+ /* All-day event */
+ b = (icaltime_is_date (dtstart) && icaltime_is_date (dtend));
+ set_SPropValue_proptag(&props[i++], proptag_array->aulPropTag[I_APPT_ALLDAY], (const void *) &b);
+
+ /* FIXME: for RecurrenceType */
+ flag32 = rectypeNone ;
+ set_SPropValue_proptag(&props[i++], proptag_array->aulPropTag[I_APPT_RECURTYPE], (const void *) &flag32);
+
+ switch (cbdata->meeting_type) {
+ case MEETING_OBJECT :
+ flag32 = e_cal_component_has_recurrences (comp) ? RecurMeet : SingleMeet;
+ set_SPropValue_proptag(&props[i++], PR_ICON_INDEX, (const void *) &flag32);
+
+ flag32 = 0x0171;
+ set_SPropValue_proptag(&props[i++], proptag_array->aulPropTag[I_COMMON_SIDEEFFECTS], (const void *) &flag32);
+
+ flag32 = olMeeting;
+ set_SPropValue_proptag(&props[i++], proptag_array->aulPropTag[I_APPT_MEETINGSTATUS], (const void *) &flag32);
+
+ flag32 = mtgRequest;
+ set_SPropValue_proptag(&props[i++], proptag_array->aulPropTag[I_MEET_TYPE], (const void *) &flag32);
+
+ flag32 = olResponseOrganized;
+ set_SPropValue_proptag(&props[i++], proptag_array->aulPropTag[I_APPT_RESPONSESTATUS], (const void *) &flag32);
+
+ b = 0;
+ set_SPropValue_proptag(&props[i++], proptag_array->aulPropTag[I_APPT_INVITED], (const void *) &b);
+
+ flag32 = cbdata->new_appt_id;
+ set_SPropValue_proptag(&props[i++], PR_OWNER_APPT_ID, (const void *) &flag32);
+
+ e_cal_component_get_uid (comp, &uid);
+ exchange_mapi_cal_util_generate_globalobjectid (TRUE, uid, &globalid);
+ set_SPropValue_proptag(&props[i++], proptag_array->aulPropTag[I_MEET_CLEANGUID], (const void *) &globalid);
+ set_SPropValue_proptag(&props[i++], proptag_array->aulPropTag[I_MEET_GUID], (const void *) &globalid);
+
+ break;
+ case MEETING_REQUEST :
+ flag32 = 0xFFFFFFFF; /* no idea why this has to be -1, but that's what the docs say */
+ set_SPropValue_proptag(&props[i++], PR_ICON_INDEX, (const void *) &flag32);
+
+ flag32 = 0x1C61;
+ set_SPropValue_proptag(&props[i++], proptag_array->aulPropTag[I_COMMON_SIDEEFFECTS], (const void *) &flag32);
+
+ flag32 = olMeetingReceived;
+ set_SPropValue_proptag(&props[i++], proptag_array->aulPropTag[I_APPT_MEETINGSTATUS], (const void *) &flag32);
+
+ flag32 = mtgRequest;
+ set_SPropValue_proptag(&props[i++], proptag_array->aulPropTag[I_MEET_TYPE], (const void *) &flag32);
+
+ flag32 = olResponseNotResponded;
+ set_SPropValue_proptag(&props[i++], proptag_array->aulPropTag[I_APPT_RESPONSESTATUS], (const void *) &flag32);
+
+ b = 1;
+ set_SPropValue_proptag(&props[i++], proptag_array->aulPropTag[I_APPT_INVITED], (const void *) &b);
+
+ flag32 = cbdata->dup.owner_appt_id;
+ set_SPropValue_proptag(&props[i++], PR_OWNER_APPT_ID, (const void *) &flag32);
+
+ set_SPropValue_proptag(&props[i++], proptag_array->aulPropTag[I_MEET_CLEANGUID], (const void *) cbdata->dup.cleanglobalid);
+ set_SPropValue_proptag(&props[i++], proptag_array->aulPropTag[I_MEET_GUID], (const void *) cbdata->dup.globalid);
+
+ break;
+ case MEETING_RESPONSE :
+ flag32 = RespAccept;
+ set_SPropValue_proptag(&props[i++], PR_ICON_INDEX, (const void *) &flag32);
+
+ flag32 = 0x0171;
+ set_SPropValue_proptag(&props[i++], proptag_array->aulPropTag[I_COMMON_SIDEEFFECTS], (const void *) &flag32);
+/*
+ flag32 = olMeeting;
+ set_SPropValue_proptag(&props[i++], proptag_array->aulPropTag[I_APPT_MEETINGSTATUS], (const void *) &flag32);
+*/
+ flag32 = mtgRequest;
+ set_SPropValue_proptag(&props[i++], proptag_array->aulPropTag[I_MEET_TYPE], (const void *) &flag32);
+
+ flag32 = olResponseAccepted;
+ set_SPropValue_proptag(&props[i++], proptag_array->aulPropTag[I_APPT_RESPONSESTATUS], (const void *) &flag32);
+
+ break;
+ case NOT_A_MEETING :
+ default :
+ flag32 = e_cal_component_has_recurrences (comp) ? RecurAppt : SingleAppt;
+ set_SPropValue_proptag(&props[i++], PR_ICON_INDEX, (const void *) &flag32);
+
+ flag32 = 0x0171;
+ set_SPropValue_proptag(&props[i++], proptag_array->aulPropTag[I_COMMON_SIDEEFFECTS], (const void *) &flag32);
+
+ flag32 = olNonMeeting;
+ set_SPropValue_proptag(&props[i++], proptag_array->aulPropTag[I_APPT_MEETINGSTATUS], (const void *) &flag32);
+
+ flag32 = olResponseNone;
+ set_SPropValue_proptag(&props[i++], proptag_array->aulPropTag[I_APPT_RESPONSESTATUS], (const void *) &flag32);
+
+ b = 0;
+ set_SPropValue_proptag(&props[i++], proptag_array->aulPropTag[I_APPT_INVITED], (const void *) &b);
+
+ break;
+ }
+
+ /* FIXME: Recurring */
+ b = e_cal_component_has_recurrences (comp) && FALSE; b = 0;
+ set_SPropValue_proptag(&props[i++], proptag_array->aulPropTag[I_APPT_RECURRING], (const void *) &b);
+ set_SPropValue_proptag(&props[i++], proptag_array->aulPropTag[I_MEET_ISRECURRING], (const void *) &b);
+ b = e_cal_component_has_exceptions (comp) && FALSE; b = 0;
+ set_SPropValue_proptag(&props[i++], proptag_array->aulPropTag[I_MEET_ISEXCEPTION], (const void *) &b);
+
+ /* Online Meeting : we probably would never support this */
+ b = 0;
+ set_SPropValue_proptag(&props[i++], proptag_array->aulPropTag[I_APPT_ISONLINEMEET], (const void *) &b);
+
+ /* Counter Proposal for appointments : not supported */
+ b = 0;
+ set_SPropValue_proptag(&props[i++], proptag_array->aulPropTag[I_APPT_COUNTERPROPOSAL], (const void *) &b);
+
+ } else if (kind == ICAL_VTODO_COMPONENT) {
+ double d;
+
+ /* Context menu flags */ /* FIXME: for assigned tasks */
+ flag32 = 0x0110;
+ set_SPropValue_proptag(&props[i++], proptag_array->aulPropTag[I_COMMON_SIDEEFFECTS], (const void *) &flag32);
+
+ /* Status, Percent complete, IsComplete */
+ flag32 = olTaskNotStarted; /* default */
+ b = 0; /* default */
+ d = 0.0;
+ prop = icalcomponent_get_first_property (ical_comp, ICAL_PERCENTCOMPLETE_PROPERTY);
+ if (prop)
+ d = 0.01 * icalproperty_get_percentcomplete (prop);
+
+ flag32 = get_prop_from_taskstatus (icalcomponent_get_status (ical_comp));
+ if (flag32 == olTaskComplete) {
+ b = 1;
+ d = 1.0;
+ }
+
+ set_SPropValue_proptag(&props[i++], proptag_array->aulPropTag[I_TASK_STATUS], (const void *) &flag32);
+ set_SPropValue_proptag(&props[i++], proptag_array->aulPropTag[I_TASK_PERCENT], (const void *) &d);
+ set_SPropValue_proptag(&props[i++], proptag_array->aulPropTag[I_TASK_ISCOMPLETE], (const void *) &b);
+
+ /* Date completed */
+ if (b) {
+ struct icaltimetype completed;
+ prop = icalcomponent_get_first_property (ical_comp, ICAL_COMPLETED_PROPERTY);
+ completed = icalproperty_get_completed (prop);
+
+ t.tv_sec = icaltime_as_timet (completed);
+ t.tv_usec = 0;
+ set_SPropValue_proptag_date_timeval(&props[i++], proptag_array->aulPropTag[I_TASK_COMPLETED], &t);
+ }
+
+ /* Start */
+ t.tv_sec = icaltime_as_timet (dtstart);
+ t.tv_usec = 0;
+ set_SPropValue_proptag_date_timeval(&props[i++], proptag_array->aulPropTag[I_TASK_START], &t);
+
+ /* Due */
+ t.tv_sec = icaltime_as_timet (dtend);
+ t.tv_usec = 0;
+ set_SPropValue_proptag_date_timeval(&props[i++], proptag_array->aulPropTag[I_TASK_DUE], &t);
+
+ /* FIXME: Evolution does not support recurring tasks */
+ b = 0;
+ set_SPropValue_proptag(&props[i++], proptag_array->aulPropTag[I_TASK_ISRECURRING], (const void *) &b);
+
+ } else if (kind == ICAL_VJOURNAL_COMPONENT) {
+ /* Context menu flags */
+ flag32 = 0x0110;
+ set_SPropValue_proptag(&props[i++], proptag_array->aulPropTag[I_COMMON_SIDEEFFECTS], (const void *) &flag32);
+
+ flag32 = 0x0300;
+ set_SPropValue_proptag(&props[i++], PR_ICON_INDEX, (const void *) &flag32);
+ }
+
+ *value = props;
+
+ g_print ("\nEnded up setting %d props\n", i);
+
+ return i;
+}
+
Added: branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-cal-utils.h
==============================================================================
--- (empty file)
+++ branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-cal-utils.h Thu Jul 3 08:02:54 2008
@@ -0,0 +1,131 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Authors:
+ * Suman Manjunath <msuman novell com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU Lesser General Public
+ * License as published by the Free Software Foundation.
+ *
+ * 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to:
+ * Free Software Foundation, 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+
+#ifndef EXCHANGE_MAPI_CAL_UTILS_H
+#define EXCHANGE_MAPI_CAL_UTILS_H
+
+#include <libecal/e-cal-component.h>
+#include "exchange-mapi-connection.h"
+#include "exchange-mapi-utils.h"
+#include "exchange-mapi-cal-tz-utils.h"
+#include "exchange-mapi-cal-recur-utils.h"
+#include "exchange-mapi-cal-tz-utils.h"
+
+G_BEGIN_DECLS
+
+typedef enum {
+ NOT_A_MEETING = 0,
+ MEETING_OBJECT = (1 << 0),
+ MEETING_OBJECT_SENT = (1 << 1),
+ MEETING_REQUEST = (1 << 2),
+ MEETING_RESPONSE = (1 << 3)
+} MAPIMeetingOptions;
+
+struct dup_data {
+ struct SBinary *globalid;
+ struct SBinary *cleanglobalid;
+ uint32_t owner_appt_id;
+ uint32_t appt_seq;
+};
+
+struct cbdata {
+ ECalComponent *comp;
+ MAPIMeetingOptions meeting_type;
+ uint32_t msgflags;
+ uint32_t new_appt_id;
+ struct dup_data dup;
+ const char *username;
+ const char *userid;
+ const char *ownername;
+ const char *ownerid;
+};
+
+void
+exchange_mapi_cal_util_fetch_recipients (ECalComponent *comp, GSList **recip_list);
+void
+exchange_mapi_cal_util_fetch_attachments (ECalComponent *comp, GSList **attach_list, const char *local_store);
+
+ECalComponent *
+exchange_mapi_cal_util_mapi_props_to_comp (icalcomponent_kind kind, const gchar *mid, struct mapi_SPropValue_array *properties,
+ GSList *streams, GSList *recipients, GSList *attachments,
+ const char *local_store, const icaltimezone *default_zone);
+gboolean
+exchange_mapi_cal_util_build_name_id (struct mapi_nameid *nameid, gpointer data);
+
+int
+exchange_mapi_cal_util_build_props (struct SPropValue **value, struct SPropTagArray *proptag_array, gpointer data);
+
+void
+exchange_mapi_cal_util_generate_globalobjectid (gboolean is_clean, const char *uid, struct SBinary *sb);
+
+/* we don't have to specify the PR_BODY_* tags since it is fetched by default */
+static const uint32_t cal_GetPropsList[] = {
+ PR_FID,
+ PR_MID,
+ PR_SUBJECT,
+ PR_SUBJECT_UNICODE,
+ PR_SUBJECT_ERROR,
+ PR_NORMALIZED_SUBJECT,
+ PR_NORMALIZED_SUBJECT_UNICODE,
+ PR_NORMALIZED_SUBJECT_ERROR,
+ PR_CREATION_TIME,
+ PR_LAST_MODIFICATION_TIME,
+ PR_PRIORITY,
+ PR_SENSITIVITY,
+ PR_START_DATE,
+ PR_END_DATE,
+ PR_RESPONSE_REQUESTED,
+
+ PR_SENT_REPRESENTING_NAME,
+ PR_SENT_REPRESENTING_NAME_UNICODE,
+ PR_SENT_REPRESENTING_ADDRTYPE,
+ PR_SENT_REPRESENTING_ADDRTYPE_UNICODE,
+ PR_SENT_REPRESENTING_EMAIL_ADDRESS,
+ PR_SENT_REPRESENTING_EMAIL_ADDRESS_UNICODE,
+
+ PR_SENDER_NAME,
+ PR_SENDER_NAME_UNICODE,
+ PR_SENDER_ADDRTYPE,
+ PR_SENDER_ADDRTYPE_UNICODE,
+ PR_SENDER_EMAIL_ADDRESS,
+ PR_SENDER_EMAIL_ADDRESS_UNICODE,
+
+ PR_RCVD_REPRESENTING_NAME,
+ PR_RCVD_REPRESENTING_NAME_UNICODE,
+ PR_RCVD_REPRESENTING_ADDRTYPE,
+ PR_RCVD_REPRESENTING_ADDRTYPE_UNICODE,
+ PR_RCVD_REPRESENTING_EMAIL_ADDRESS,
+ PR_RCVD_REPRESENTING_EMAIL_ADDRESS_UNICODE
+};
+static const uint16_t n_cal_GetPropsList = G_N_ELEMENTS (cal_GetPropsList);
+
+static const uint32_t cal_IDList[] = {
+ PR_FID,
+ PR_MID
+};
+static const uint16_t n_cal_IDList = G_N_ELEMENTS (cal_IDList);
+
+G_END_DECLS
+
+#endif
Added: branches/EXCHANGE_MAPI_BRANCH/servers/mapi/tz-ical-to-mapi
==============================================================================
--- (empty file)
+++ branches/EXCHANGE_MAPI_BRANCH/servers/mapi/tz-ical-to-mapi Thu Jul 3 08:02:54 2008
@@ -0,0 +1,399 @@
+UTC~~~GMT Standard Time
+/softwarestudio.org/Tzfile/Africa/Abidjan~~~Greenwich Standard Time
+/softwarestudio.org/Tzfile/Africa/Accra~~~Greenwich Standard Time
+/softwarestudio.org/Tzfile/Africa/Addis_Ababa~~~E. Africa Standard Time
+/softwarestudio.org/Tzfile/Africa/Algiers~~~W. Central Africa Standard Time
+/softwarestudio.org/Tzfile/Africa/Asmara~~~E. Africa Standard Time
+/softwarestudio.org/Tzfile/Africa/Bamako~~~Greenwich Standard Time
+/softwarestudio.org/Tzfile/Africa/Bangui~~~W. Central Africa Standard Time
+/softwarestudio.org/Tzfile/Africa/Banjul~~~Greenwich Standard Time
+/softwarestudio.org/Tzfile/Africa/Bissau~~~Greenwich Standard Time
+/softwarestudio.org/Tzfile/Africa/Blantyre~~~South Africa Standard Time
+/softwarestudio.org/Tzfile/Africa/Brazzaville~~~W. Central Africa Standard Time
+/softwarestudio.org/Tzfile/Africa/Bujumbura~~~South Africa Standard Time
+/softwarestudio.org/Tzfile/Africa/Cairo~~~Egypt Standard Time
+/softwarestudio.org/Tzfile/Africa/Casablanca~~~Greenwich Standard Time
+/softwarestudio.org/Tzfile/Africa/Ceuta~~~W. Central Africa Standard Time
+/softwarestudio.org/Tzfile/Africa/Conakry~~~Greenwich Standard Time
+/softwarestudio.org/Tzfile/Africa/Dakar~~~Greenwich Standard Time
+/softwarestudio.org/Tzfile/Africa/Dar_es_Salaam~~~E. Africa Standard Time
+/softwarestudio.org/Tzfile/Africa/Djibouti~~~E. Africa Standard Time
+/softwarestudio.org/Tzfile/Africa/Douala~~~W. Central Africa Standard Time
+/softwarestudio.org/Tzfile/Africa/El_Aaiun~~~Greenwich Standard Time
+/softwarestudio.org/Tzfile/Africa/Freetown~~~Greenwich Standard Time
+/softwarestudio.org/Tzfile/Africa/Gaborone~~~South Africa Standard Time
+/softwarestudio.org/Tzfile/Africa/Harare~~~South Africa Standard Time
+/softwarestudio.org/Tzfile/Africa/Johannesburg~~~South Africa Standard Time
+/softwarestudio.org/Tzfile/Africa/Kampala~~~E. Africa Standard Time
+/softwarestudio.org/Tzfile/Africa/Khartoum~~~E. Africa Standard Time
+/softwarestudio.org/Tzfile/Africa/Kigali~~~Egypt Standard Time
+/softwarestudio.org/Tzfile/Africa/Kinshasa~~~W. Central Africa Standard Time
+/softwarestudio.org/Tzfile/Africa/Lagos~~~Greenwich Standard Time
+/softwarestudio.org/Tzfile/Africa/Libreville~~~W. Central Africa Standard Time
+/softwarestudio.org/Tzfile/Africa/Lome~~~Greenwich Standard Time
+/softwarestudio.org/Tzfile/Africa/Luanda~~~W. Central Africa Standard Time
+/softwarestudio.org/Tzfile/Africa/Lubumbashi~~~South Africa Standard Time
+/softwarestudio.org/Tzfile/Africa/Lusaka~~~South Africa Standard Time
+/softwarestudio.org/Tzfile/Africa/Malabo~~~W. Central Africa Standard Time
+/softwarestudio.org/Tzfile/Africa/Maputo~~~South Africa Standard Time
+/softwarestudio.org/Tzfile/Africa/Maseru~~~South Africa Standard Time
+/softwarestudio.org/Tzfile/Africa/Mbabane~~~South Africa Standard Time
+/softwarestudio.org/Tzfile/Africa/Mogadishu~~~E. Africa Standard Time
+/softwarestudio.org/Tzfile/Africa/Monrovia~~~Greenwich Standard Time
+/softwarestudio.org/Tzfile/Africa/Nairobi~~~E. Africa Standard Time
+/softwarestudio.org/Tzfile/Africa/Ndjamena~~~W. Central Africa Standard Time
+/softwarestudio.org/Tzfile/Africa/Niamey~~~W. Central Africa Standard Time
+/softwarestudio.org/Tzfile/Africa/Nouakchott~~~Greenwich Standard Time
+/softwarestudio.org/Tzfile/Africa/Ouagadougou~~~Greenwich Standard Time
+/softwarestudio.org/Tzfile/Africa/Porto-Novo~~~W. Central Africa Standard Time
+/softwarestudio.org/Tzfile/Africa/Sao_Tome~~~Cape Verde Standard Time
+/softwarestudio.org/Tzfile/Africa/Tripoli~~~Egypt Standard Time
+/softwarestudio.org/Tzfile/Africa/Tunis~~~W. Central Africa Standard Time
+/softwarestudio.org/Tzfile/Africa/Windhoek~~~Namibia Standard Time
+/softwarestudio.org/Tzfile/America/Adak~~~Hawaiian Standard Time
+/softwarestudio.org/Tzfile/America/Anchorage~~~Alaskan Standard Time
+/softwarestudio.org/Tzfile/America/Anguilla~~~SA Western Standard Time
+/softwarestudio.org/Tzfile/America/Antigua~~~SA Western Standard Time
+/softwarestudio.org/Tzfile/America/Araguaina~~~E. South America Standard Time
+/softwarestudio.org/Tzfile/America/Argentina/Buenos_Aires~~~SA Eastern Standard Time
+/softwarestudio.org/Tzfile/America/Argentina/Catamarca~~~SA Eastern Standard Time
+/softwarestudio.org/Tzfile/America/Argentina/Cordoba~~~SA Eastern Standard Time
+/softwarestudio.org/Tzfile/America/Argentina/Jujuy~~~SA Eastern Standard Time
+/softwarestudio.org/Tzfile/America/Argentina/La_Rioja~~~SA Eastern Standard Time
+/softwarestudio.org/Tzfile/America/Argentina/Mendoza~~~SA Eastern Standard Time
+/softwarestudio.org/Tzfile/America/Argentina/Rio_Gallegos~~~SA Eastern Standard Time
+/softwarestudio.org/Tzfile/America/Argentina/San_Juan~~~SA Eastern Standard Time
+/softwarestudio.org/Tzfile/America/Argentina/Tucuman~~~SA Eastern Standard Time
+/softwarestudio.org/Tzfile/America/Argentina/Ushuaia~~~SA Eastern Standard Time
+/softwarestudio.org/Tzfile/America/Aruba~~~Venezuela Standard Time
+/softwarestudio.org/Tzfile/America/Asuncion~~~SA Eastern Standard Time
+/softwarestudio.org/Tzfile/America/Atikokan~~~US Eastern Standard Time
+/softwarestudio.org/Tzfile/America/Bahia~~~E. South America Standard Time
+/softwarestudio.org/Tzfile/America/Barbados~~~SA Western Standard Time
+/softwarestudio.org/Tzfile/America/Belem~~~E. South America Standard Time
+/softwarestudio.org/Tzfile/America/Belize~~~Mexico Standard Time
+/softwarestudio.org/Tzfile/America/Blanc-Sablon~~~Atlantic Standard Time
+/softwarestudio.org/Tzfile/America/Boa_Vista~~~SA Western Standard Time
+/softwarestudio.org/Tzfile/America/Bogota~~~SA Pacific Standard Time
+/softwarestudio.org/Tzfile/America/Boise~~~US Mountain Standard Time
+/softwarestudio.org/Tzfile/America/Cambridge_Bay~~~Mountain Standard Time
+/softwarestudio.org/Tzfile/America/Campo_Grande~~~E. South America Standard Time
+/softwarestudio.org/Tzfile/America/Cancun~~~Central America Standard Time
+/softwarestudio.org/Tzfile/America/Caracas~~~Venezuela Standard Time
+/softwarestudio.org/Tzfile/America/Cayenne~~~E. South America Standard Time
+/softwarestudio.org/Tzfile/America/Cayman~~~SA Pacific Standard Time
+/softwarestudio.org/Tzfile/America/Chicago~~~Central Standard Time
+/softwarestudio.org/Tzfile/America/Chihuahua~~~Mexico Standard Time 2
+/softwarestudio.org/Tzfile/America/Costa_Rica~~~Central America Standard Time
+/softwarestudio.org/Tzfile/America/Cuiaba~~~E. South America Standard Time
+/softwarestudio.org/Tzfile/America/Curacao~~~Venezuela Standard Time
+/softwarestudio.org/Tzfile/America/Danmarkshavn~~~GMT Standard Time
+/softwarestudio.org/Tzfile/America/Dawson~~~Pacific Standard Time
+/softwarestudio.org/Tzfile/America/Dawson_Creek~~~Mountain Standard Time
+/softwarestudio.org/Tzfile/America/Denver~~~Mountain Standard Time
+/softwarestudio.org/Tzfile/America/Detroit~~~Eastern Standard Time
+/softwarestudio.org/Tzfile/America/Dominica~~~SA Western Standard Time
+/softwarestudio.org/Tzfile/America/Edmonton~~~Mountain Standard Time
+/softwarestudio.org/Tzfile/America/Eirunepe~~~SA Pacific Standard Time
+/softwarestudio.org/Tzfile/America/El_Salvador~~~Central America Standard Time
+/softwarestudio.org/Tzfile/America/Fortaleza~~~E. South America Standard Time
+/softwarestudio.org/Tzfile/America/Glace_Bay~~~Atlantic Standard Time
+/softwarestudio.org/Tzfile/America/Godthab~~~Greenland Standard Time
+/softwarestudio.org/Tzfile/America/Goose_Bay~~~Atlantic Standard Time
+/softwarestudio.org/Tzfile/America/Grand_Turk~~~SA Pacific Standard Time
+/softwarestudio.org/Tzfile/America/Grenada~~~SA Western Standard Time
+/softwarestudio.org/Tzfile/America/Guadeloupe~~~SA Western Standard Time
+/softwarestudio.org/Tzfile/America/Guatemala~~~Central America Standard Time
+/softwarestudio.org/Tzfile/America/Guayaquil~~~SA Pacific Standard Time
+/softwarestudio.org/Tzfile/America/Guyana~~~Venezuela Standard Time
+/softwarestudio.org/Tzfile/America/Halifax~~~Atlantic Standard Time
+/softwarestudio.org/Tzfile/America/Havana~~~SA Pacific Standard Time
+/softwarestudio.org/Tzfile/America/Hermosillo~~~Mexico Standard Time 2
+/softwarestudio.org/Tzfile/America/Indiana/Indianapolis~~~US Eastern Standard Time
+/softwarestudio.org/Tzfile/America/Indiana/Knox~~~Canada Central Standard Time
+/softwarestudio.org/Tzfile/America/Indiana/Marengo~~~US Eastern Standard Time
+/softwarestudio.org/Tzfile/America/Indiana/Petersburg~~~US Eastern Standard Time
+/softwarestudio.org/Tzfile/America/Indiana/Tell_City~~~Canada Central Standard Time
+/softwarestudio.org/Tzfile/America/Indiana/Vevay~~~US Eastern Standard Time
+/softwarestudio.org/Tzfile/America/Indiana/Vincennes~~~US Eastern Standard Time
+/softwarestudio.org/Tzfile/America/Indiana/Winamac~~~US Eastern Standard Time
+/softwarestudio.org/Tzfile/America/Inuvik~~~Mountain Standard Time
+/softwarestudio.org/Tzfile/America/Iqaluit~~~Eastern Standard Time
+/softwarestudio.org/Tzfile/America/Jamaica~~~SA Pacific Standard Time
+/softwarestudio.org/Tzfile/America/Juneau~~~Alaskan Standard Time
+/softwarestudio.org/Tzfile/America/Kentucky/Louisville~~~US Eastern Standard Time
+/softwarestudio.org/Tzfile/America/Kentucky/Monticello~~~US Eastern Standard Time
+/softwarestudio.org/Tzfile/America/La_Paz~~~SA Western Standard Time
+/softwarestudio.org/Tzfile/America/Lima~~~SA Pacific Standard Time
+/softwarestudio.org/Tzfile/America/Los_Angeles~~~Pacific Standard Time
+/softwarestudio.org/Tzfile/America/Maceio~~~E. South America Standard Time
+/softwarestudio.org/Tzfile/America/Managua~~~Central America Standard Time
+/softwarestudio.org/Tzfile/America/Manaus~~~Central Brazilian Standard Time
+/softwarestudio.org/Tzfile/America/Martinique~~~SA Western Standard Time
+/softwarestudio.org/Tzfile/America/Mazatlan~~~Mountain Standard Time (Mexico)
+/softwarestudio.org/Tzfile/America/Menominee~~~Central Standard Time
+/softwarestudio.org/Tzfile/America/Merida~~~Central America Standard Time
+/softwarestudio.org/Tzfile/America/Mexico_City~~~Mexico Standard Time
+/softwarestudio.org/Tzfile/America/Miquelon~~~Greenland Standard Time
+/softwarestudio.org/Tzfile/America/Moncton~~~Atlantic Standard Time
+/softwarestudio.org/Tzfile/America/Monterrey~~~Central Standard Time (Mexico)
+/softwarestudio.org/Tzfile/America/Montevideo~~~Montevideo Standard Time
+/softwarestudio.org/Tzfile/America/Montreal~~~Eastern Standard Time
+/softwarestudio.org/Tzfile/America/Montserrat~~~SA Western Standard Time
+/softwarestudio.org/Tzfile/America/Nassau~~~Eastern Standard Time
+/softwarestudio.org/Tzfile/America/New_York~~~Eastern Standard Time
+/softwarestudio.org/Tzfile/America/Nipigon~~~Eastern Standard Time
+/softwarestudio.org/Tzfile/America/Nome~~~Alaskan Standard Time
+/softwarestudio.org/Tzfile/America/Noronha~~~Mid-Atlantic Standard Time
+/softwarestudio.org/Tzfile/America/North_Dakota/Center~~~Central Standard Time
+/softwarestudio.org/Tzfile/America/North_Dakota/New_Salem~~~Central Standard Time
+/softwarestudio.org/Tzfile/America/Panama~~~SA Pacific Standard Time
+/softwarestudio.org/Tzfile/America/Pangnirtung~~~Eastern Standard Time
+/softwarestudio.org/Tzfile/America/Paramaribo~~~Venezuela Standard Time
+/softwarestudio.org/Tzfile/America/Phoenix~~~US Mountain Standard Time
+/softwarestudio.org/Tzfile/America/Port-au-Prince~~~SA Western Standard Time
+/softwarestudio.org/Tzfile/America/Port_of_Spain~~~SA Western Standard Time
+/softwarestudio.org/Tzfile/America/Porto_Velho~~~SA Western Standard Time
+/softwarestudio.org/Tzfile/America/Puerto_Rico~~~SA Western Standard Time
+/softwarestudio.org/Tzfile/America/Rainy_River~~~Canada Central Standard Time
+/softwarestudio.org/Tzfile/America/Rankin_Inlet~~~Canada Central Standard Time
+/softwarestudio.org/Tzfile/America/Recife~~~E. South America Standard Time
+/softwarestudio.org/Tzfile/America/Regina~~~Central America Standard Time
+/softwarestudio.org/Tzfile/America/Resolute~~~Eastern Standard Time
+/softwarestudio.org/Tzfile/America/Rio_Branco~~~SA Pacific Standard Time
+/softwarestudio.org/Tzfile/America/Santiago~~~Pacific SA Standard Time
+/softwarestudio.org/Tzfile/America/Santo_Domingo~~~SA Western Standard Time
+/softwarestudio.org/Tzfile/America/Sao_Paulo~~~Mid-Atlantic Standard Time
+/softwarestudio.org/Tzfile/America/Scoresbysund~~~Azores Standard Time
+/softwarestudio.org/Tzfile/America/Shiprock~~~US Mountain Standard Time
+/softwarestudio.org/Tzfile/America/St_Johns~~~Newfoundland Standard Time
+/softwarestudio.org/Tzfile/America/St_Kitts~~~SA Western Standard Time
+/softwarestudio.org/Tzfile/America/St_Lucia~~~SA Western Standard Time
+/softwarestudio.org/Tzfile/America/St_Thomas~~~SA Western Standard Time
+/softwarestudio.org/Tzfile/America/St_Vincent~~~SA Western Standard Time
+/softwarestudio.org/Tzfile/America/Swift_Current~~~Central Standard Time
+/softwarestudio.org/Tzfile/America/Tegucigalpa~~~Central America Standard Time
+/softwarestudio.org/Tzfile/America/Thule~~~Atlantic Standard Time
+/softwarestudio.org/Tzfile/America/Thunder_Bay~~~Eastern Standard Time
+/softwarestudio.org/Tzfile/America/Tijuana~~~Pacific Standard Time (Mexico)
+/softwarestudio.org/Tzfile/America/Toronto~~~Eastern Standard Time
+/softwarestudio.org/Tzfile/America/Tortola~~~SA Western Standard Time
+/softwarestudio.org/Tzfile/America/Vancouver~~~Pacific Standard Time
+/softwarestudio.org/Tzfile/America/Whitehorse~~~Pacific Standard Time
+/softwarestudio.org/Tzfile/America/Winnipeg~~~Canada Central Standard Time
+/softwarestudio.org/Tzfile/America/Yakutat~~~Alaskan Standard Time
+/softwarestudio.org/Tzfile/America/Yellowknife~~~Mountain Standard Time
+/softwarestudio.org/Tzfile/Antarctica/Casey~~~GMT Standard Time
+/softwarestudio.org/Tzfile/Antarctica/Davis~~~SE Asia Standard Time
+/softwarestudio.org/Tzfile/Antarctica/DumontDUrville~~~West Pacific Standard Time
+/softwarestudio.org/Tzfile/Antarctica/Mawson~~~GMT Standard Time
+/softwarestudio.org/Tzfile/Antarctica/McMurdo~~~Tonga Standard Time
+/softwarestudio.org/Tzfile/Antarctica/Palmer~~~Greenland Standard Time
+/softwarestudio.org/Tzfile/Antarctica/Rothera~~~GMT Standard Time
+/softwarestudio.org/Tzfile/Antarctica/South_Pole~~~GMT Standard Time
+/softwarestudio.org/Tzfile/Antarctica/Syowa~~~GMT Standard Time
+/softwarestudio.org/Tzfile/Antarctica/Vostok~~~GMT Standard Time
+/softwarestudio.org/Tzfile/Arctic/Longyearbyen~~~Central Europe Standard Time
+/softwarestudio.org/Tzfile/Asia/Aden~~~Arab Standard Time
+/softwarestudio.org/Tzfile/Asia/Almaty~~~N. Central Asia Standard Time
+/softwarestudio.org/Tzfile/Asia/Amman~~~Jordan Standard Time
+/softwarestudio.org/Tzfile/Asia/Anadyr~~~Fiji Standard Time
+/softwarestudio.org/Tzfile/Asia/Aqtau~~~Ekaterinburg Standard Time
+/softwarestudio.org/Tzfile/Asia/Aqtobe~~~Ekaterinburg Standard Time
+/softwarestudio.org/Tzfile/Asia/Ashgabat~~~Ekaterinburg Standard Time
+/softwarestudio.org/Tzfile/Asia/Baghdad~~~Arabic Standard Time
+/softwarestudio.org/Tzfile/Asia/Bahrain~~~Arab Standard Time
+/softwarestudio.org/Tzfile/Asia/Baku~~~Azerbaijan Standard Time
+/softwarestudio.org/Tzfile/Asia/Bangkok~~~SE Asia Standard Time
+/softwarestudio.org/Tzfile/Asia/Beijing~~~China Standard Time
+/softwarestudio.org/Tzfile/Asia/Beirut~~~Middle East Standard Time
+/softwarestudio.org/Tzfile/Asia/Bishkek~~~Central Asia Standard Time
+/softwarestudio.org/Tzfile/Asia/Brunei~~~Taipei Standard Time
+/softwarestudio.org/Tzfile/Asia/Calcutta~~~India Standard Time
+/softwarestudio.org/Tzfile/Asia/Choibalsan~~~Yakutsk Standard Time
+/softwarestudio.org/Tzfile/Asia/Chongqing~~~China Standard Time
+/softwarestudio.org/Tzfile/Asia/Colombo~~~India Standard Time
+/softwarestudio.org/Tzfile/Asia/Damascus~~~Israel Standard Time
+/softwarestudio.org/Tzfile/Asia/Dhaka~~~Central Asia Standard Time
+/softwarestudio.org/Tzfile/Asia/Dili~~~Yakutsk Standard Time
+/softwarestudio.org/Tzfile/Asia/Dubai~~~Iran Standard Time
+/softwarestudio.org/Tzfile/Asia/Dushanbe~~~West Asia Standard Time
+/softwarestudio.org/Tzfile/Asia/Gaza~~~Israel Standard Time
+/softwarestudio.org/Tzfile/Asia/Harbin~~~China Standard Time
+/softwarestudio.org/Tzfile/Asia/Hong_Kong~~~China Standard Time
+/softwarestudio.org/Tzfile/Asia/Hovd~~~North Asia Standard Time
+/softwarestudio.org/Tzfile/Asia/Irkutsk~~~North Asia East Standard Time
+/softwarestudio.org/Tzfile/Asia/Jakarta~~~SE Asia Standard Time
+/softwarestudio.org/Tzfile/Asia/Jayapura~~~Yakutsk Standard Time
+/softwarestudio.org/Tzfile/Asia/Jerusalem~~~Israel Standard Time
+/softwarestudio.org/Tzfile/Asia/Kabul~~~Afghanistan Standard Time
+/softwarestudio.org/Tzfile/Asia/Kamchatka~~~Fiji Standard Time
+/softwarestudio.org/Tzfile/Asia/Karachi~~~West Asia Standard Time
+/softwarestudio.org/Tzfile/Asia/Kashgar~~~China Standard Time
+/softwarestudio.org/Tzfile/Asia/Katmandu~~~Nepal Standard Time
+/softwarestudio.org/Tzfile/Asia/Krasnoyarsk~~~North Asia Standard Time
+/softwarestudio.org/Tzfile/Asia/Kuala_Lumpur~~~Singapore Standard Time
+/softwarestudio.org/Tzfile/Asia/Kuching~~~Taipei Standard Time
+/softwarestudio.org/Tzfile/Asia/Kuwait~~~Arab Standard Time
+/softwarestudio.org/Tzfile/Asia/Macau~~~China Standard Time
+/softwarestudio.org/Tzfile/Asia/Magadan~~~Central Pacific Standard Time
+/softwarestudio.org/Tzfile/Asia/Makassar~~~Taipei Standard Time
+/softwarestudio.org/Tzfile/Asia/Manila~~~Taipei Standard Time
+/softwarestudio.org/Tzfile/Asia/Muscat~~~Arabian Standard Time
+/softwarestudio.org/Tzfile/Asia/Nicosia~~~Israel Standard Time
+/softwarestudio.org/Tzfile/Asia/Novosibirsk~~~N. Central Asia Standard Time
+/softwarestudio.org/Tzfile/Asia/Omsk~~~N. Central Asia Standard Time
+/softwarestudio.org/Tzfile/Asia/Oral~~~Ekaterinburg Standard Time
+/softwarestudio.org/Tzfile/Asia/Phnom_Penh~~~SE Asia Standard Time
+/softwarestudio.org/Tzfile/Asia/Pontianak~~~SE Asia Standard Time
+/softwarestudio.org/Tzfile/Asia/Pyongyang~~~Korea Standard Time
+/softwarestudio.org/Tzfile/Asia/Qatar~~~Arab Standard Time
+/softwarestudio.org/Tzfile/Asia/Qyzylorda~~~Central Asia Standard Time
+/softwarestudio.org/Tzfile/Asia/Rangoon~~~Myanmar Standard Time
+/softwarestudio.org/Tzfile/Asia/Riyadh~~~Arab Standard Time
+/softwarestudio.org/Tzfile/Asia/Saigon~~~SE Asia Standard Time
+/softwarestudio.org/Tzfile/Asia/Sakhalin~~~Vladivostok Standard Time
+/softwarestudio.org/Tzfile/Asia/Samarkand~~~West Asia Standard Time
+/softwarestudio.org/Tzfile/Asia/Seoul~~~Korea Standard Time
+/softwarestudio.org/Tzfile/Asia/Shanghai~~~China Standard Time
+/softwarestudio.org/Tzfile/Asia/Singapore~~~Singapore Standard Time
+/softwarestudio.org/Tzfile/Asia/Taipei~~~Taipei Standard Time
+/softwarestudio.org/Tzfile/Asia/Tashkent~~~West Asia Standard Time
+/softwarestudio.org/Tzfile/Asia/Tbilisi~~~Georgian Standard Time
+/softwarestudio.org/Tzfile/Asia/Tehran~~~Iran Standard Time
+/softwarestudio.org/Tzfile/Asia/Thimphu~~~Central Asia Standard Time
+/softwarestudio.org/Tzfile/Asia/Tokyo~~~Tokyo Standard Time
+/softwarestudio.org/Tzfile/Asia/Ulaanbaatar~~~North Asia East Standard Time
+/softwarestudio.org/Tzfile/Asia/Urumqi~~~China Standard Time
+/softwarestudio.org/Tzfile/Asia/Vientiane~~~SE Asia Standard Time
+/softwarestudio.org/Tzfile/Asia/Vladivostok~~~Vladivostok Standard Time
+/softwarestudio.org/Tzfile/Asia/Yakutsk~~~Yakutsk Standard Time
+/softwarestudio.org/Tzfile/Asia/Yekaterinburg~~~Ekaterinburg Standard Time
+/softwarestudio.org/Tzfile/Asia/Yerevan~~~Armenian Standard Time
+/softwarestudio.org/Tzfile/Atlantic/Azores~~~Azores Standard Time
+/softwarestudio.org/Tzfile/Atlantic/Bermuda~~~Atlantic Standard Time
+/softwarestudio.org/Tzfile/Atlantic/Canary~~~GMT Standard Time
+/softwarestudio.org/Tzfile/Atlantic/Cape_Verde~~~Cape Verde Standard Time
+/softwarestudio.org/Tzfile/Atlantic/Faroe~~~GMT Standard Time
+/softwarestudio.org/Tzfile/Atlantic/Jan_Mayen~~~W. Europe Standard Time
+/softwarestudio.org/Tzfile/Atlantic/Madeira~~~GMT Standard Time
+/softwarestudio.org/Tzfile/Atlantic/Reykjavik~~~GMT Standard Time
+/softwarestudio.org/Tzfile/Atlantic/South_Georgia~~~Mid-Atlantic Standard Time
+/softwarestudio.org/Tzfile/Atlantic/Stanley~~~SA Eastern Standard Time
+/softwarestudio.org/Tzfile/Atlantic/St_Helena~~~Greenwich Standard Time
+/softwarestudio.org/Tzfile/Australia/Adelaide~~~Cen. Australia Standard Time
+/softwarestudio.org/Tzfile/Australia/Brisbane~~~E. Australia Standard Time
+/softwarestudio.org/Tzfile/Australia/Broken_Hill~~~Cen. Australia Standard Time
+/softwarestudio.org/Tzfile/Australia/Currie~~~AUS Eastern Standard Time
+/softwarestudio.org/Tzfile/Australia/Darwin~~~AUS Central Standard Time
+/softwarestudio.org/Tzfile/Australia/Eucla~~~AUS Central Standard Time
+/softwarestudio.org/Tzfile/Australia/Hobart~~~Tasmania Standard Time
+/softwarestudio.org/Tzfile/Australia/Lindeman~~~E. Australia Standard Time
+/softwarestudio.org/Tzfile/Australia/Lord_Howe~~~AUS Eastern Standard Time
+/softwarestudio.org/Tzfile/Australia/Melbourne~~~AUS Eastern Standard Time
+/softwarestudio.org/Tzfile/Australia/Perth~~~W. Australia Standard Time
+/softwarestudio.org/Tzfile/Australia/Sydney~~~AUS Eastern Standard Time
+/softwarestudio.org/Tzfile/Europe/Amsterdam~~~W. Europe Standard Time
+/softwarestudio.org/Tzfile/Europe/Andorra~~~W. Europe Standard Time
+/softwarestudio.org/Tzfile/Europe/Athens~~~GTB Standard Time
+/softwarestudio.org/Tzfile/Europe/Belgrade~~~Central European Standard Time
+/softwarestudio.org/Tzfile/Europe/Berlin~~~W. Europe Standard Time
+/softwarestudio.org/Tzfile/Europe/Bratislava~~~Central Europe Standard Time
+/softwarestudio.org/Tzfile/Europe/Brussels~~~Romance Standard Time
+/softwarestudio.org/Tzfile/Europe/Bucharest~~~E. Europe Standard Time
+/softwarestudio.org/Tzfile/Europe/Budapest~~~Central Europe Standard Time
+/softwarestudio.org/Tzfile/Europe/Chisinau~~~FLE Standard Time
+/softwarestudio.org/Tzfile/Europe/Copenhagen~~~Romance Standard Time
+/softwarestudio.org/Tzfile/Europe/Dublin~~~GMT Standard Time
+/softwarestudio.org/Tzfile/Europe/Gibraltar~~~Romance Standard Time
+/softwarestudio.org/Tzfile/Europe/Guernsey~~~GMT Standard Time
+/softwarestudio.org/Tzfile/Europe/Helsinki~~~FLE Standard Time
+/softwarestudio.org/Tzfile/Europe/Isle_of_Man~~~GMT Standard Time
+/softwarestudio.org/Tzfile/Europe/Istanbul~~~GTB Standard Time
+/softwarestudio.org/Tzfile/Europe/Jersey~~~GMT Standard Time
+/softwarestudio.org/Tzfile/Europe/Kaliningrad~~~FLE Standard Time
+/softwarestudio.org/Tzfile/Europe/Kiev~~~FLE Standard Time
+/softwarestudio.org/Tzfile/Europe/Lisbon~~~GMT Standard Time
+/softwarestudio.org/Tzfile/Europe/Ljubljana~~~Central Europe Standard Time
+/softwarestudio.org/Tzfile/Europe/London~~~GMT Standard Time
+/softwarestudio.org/Tzfile/Europe/Luxembourg~~~Romance Standard Time
+/softwarestudio.org/Tzfile/Europe/Madrid~~~Romance Standard Time
+/softwarestudio.org/Tzfile/Europe/Malta~~~W. Europe Standard Time
+/softwarestudio.org/Tzfile/Europe/Mariehamn~~~FLE Standard Time
+/softwarestudio.org/Tzfile/Europe/Minsk~~~E. Europe Standard Time
+/softwarestudio.org/Tzfile/Europe/Monaco~~~W. Europe Standard Time
+/softwarestudio.org/Tzfile/Europe/Moscow~~~Russian Standard Time
+/softwarestudio.org/Tzfile/Europe/Oslo~~~W. Europe Standard Time
+/softwarestudio.org/Tzfile/Europe/Paris~~~Romance Standard Time
+/softwarestudio.org/Tzfile/Europe/Podgorica~~~Central European Standard Time
+/softwarestudio.org/Tzfile/Europe/Prague~~~Central Europe Standard Time
+/softwarestudio.org/Tzfile/Europe/Riga~~~FLE Standard Time
+/softwarestudio.org/Tzfile/Europe/Rome~~~W. Europe Standard Time
+/softwarestudio.org/Tzfile/Europe/Samara~~~Caucasus Standard Time
+/softwarestudio.org/Tzfile/Europe/San_Marino~~~W. Europe Standard Time
+/softwarestudio.org/Tzfile/Europe/Sarajevo~~~Central European Standard Time
+/softwarestudio.org/Tzfile/Europe/Simferopol~~~FLE Standard Time
+/softwarestudio.org/Tzfile/Europe/Skopje~~~Central European Standard Time
+/softwarestudio.org/Tzfile/Europe/Sofia~~~FLE Standard Time
+/softwarestudio.org/Tzfile/Europe/Stockholm~~~W. Europe Standard Time
+/softwarestudio.org/Tzfile/Europe/Tallinn~~~FLE Standard Time
+/softwarestudio.org/Tzfile/Europe/Tirane~~~Central European Standard Time
+/softwarestudio.org/Tzfile/Europe/Uzhgorod~~~FLE Standard Time
+/softwarestudio.org/Tzfile/Europe/Vaduz~~~W. Europe Standard Time
+/softwarestudio.org/Tzfile/Europe/Vatican~~~W. Europe Standard Time
+/softwarestudio.org/Tzfile/Europe/Vienna~~~W. Europe Standard Time
+/softwarestudio.org/Tzfile/Europe/Vilnius~~~FLE Standard Time
+/softwarestudio.org/Tzfile/Europe/Volgograd~~~Russian Standard Time
+/softwarestudio.org/Tzfile/Europe/Warsaw~~~Central European Standard Time
+/softwarestudio.org/Tzfile/Europe/Zagreb~~~Central European Standard Time
+/softwarestudio.org/Tzfile/Europe/Zaporozhye~~~FLE Standard Time
+/softwarestudio.org/Tzfile/Europe/Zurich~~~W. Europe Standard Time
+/softwarestudio.org/Tzfile/Indian/Antananarivo~~~E. Africa Standard Time
+/softwarestudio.org/Tzfile/Indian/Chagos~~~Sri Lanka Standard Time
+/softwarestudio.org/Tzfile/Indian/Christmas~~~SE Asia Standard Time
+/softwarestudio.org/Tzfile/Indian/Cocos~~~Myanmar Standard Time
+/softwarestudio.org/Tzfile/Indian/Comoro~~~E. Africa Standard Time
+/softwarestudio.org/Tzfile/Indian/Kerguelen~~~GMT Standard Time
+/softwarestudio.org/Tzfile/Indian/Mahe~~~Iran Standard Time
+/softwarestudio.org/Tzfile/Indian/Maldives~~~West Asia Standard Time
+/softwarestudio.org/Tzfile/Indian/Mauritius~~~Arabian Standard Time
+/softwarestudio.org/Tzfile/Indian/Mayotte~~~E. Africa Standard Time
+/softwarestudio.org/Tzfile/Indian/Reunion~~~Iran Standard Time
+/softwarestudio.org/Tzfile/Pacific/Apia~~~Dateline Standard Time
+/softwarestudio.org/Tzfile/Pacific/Auckland~~~New Zealand Standard Time
+/softwarestudio.org/Tzfile/Pacific/Chatham~~~Tonga Standard Time
+/softwarestudio.org/Tzfile/Pacific/Easter~~~SA Pacific Standard Time
+/softwarestudio.org/Tzfile/Pacific/Efate~~~Central Pacific Standard Time
+/softwarestudio.org/Tzfile/Pacific/Enderbury~~~Tonga Standard Time
+/softwarestudio.org/Tzfile/Pacific/Fakaofo~~~Hawaiian Standard Time
+/softwarestudio.org/Tzfile/Pacific/Fiji~~~Fiji Standard Time
+/softwarestudio.org/Tzfile/Pacific/Funafuti~~~Fiji Standard Time
+/softwarestudio.org/Tzfile/Pacific/Galapagos~~~Mexico Standard Time
+/softwarestudio.org/Tzfile/Pacific/Gambier~~~Alaskan Standard Time
+/softwarestudio.org/Tzfile/Pacific/Guadalcanal~~~Central Pacific Standard Time
+/softwarestudio.org/Tzfile/Pacific/Guam~~~West Pacific Standard Time
+/softwarestudio.org/Tzfile/Pacific/Honolulu~~~Hawaiian Standard Time
+/softwarestudio.org/Tzfile/Pacific/Johnston~~~Hawaiian Standard Time
+/softwarestudio.org/Tzfile/Pacific/Kiritimati~~~Tonga Standard Time
+/softwarestudio.org/Tzfile/Pacific/Kosrae~~~Central Pacific Standard Time
+/softwarestudio.org/Tzfile/Pacific/Kwajalein~~~Fiji Standard Time
+/softwarestudio.org/Tzfile/Pacific/Majuro~~~Central Pacific Standard Time
+/softwarestudio.org/Tzfile/Pacific/Marquesas~~~Alaskan Standard Time
+/softwarestudio.org/Tzfile/Pacific/Midway~~~Samoa Standard Time
+/softwarestudio.org/Tzfile/Pacific/Nauru~~~Fiji Standard Time
+/softwarestudio.org/Tzfile/Pacific/Niue~~~Samoa Standard Time
+/softwarestudio.org/Tzfile/Pacific/Norfolk~~~Central Pacific Standard Time
+/softwarestudio.org/Tzfile/Pacific/Noumea~~~Central Pacific Standard Time
+/softwarestudio.org/Tzfile/Pacific/Pago_Pago~~~Samoa Standard Time
+/softwarestudio.org/Tzfile/Pacific/Palau~~~Yakutsk Standard Time
+/softwarestudio.org/Tzfile/Pacific/Pitcairn~~~Pacific Standard Time
+/softwarestudio.org/Tzfile/Pacific/Ponape~~~Central Pacific Standard Time
+/softwarestudio.org/Tzfile/Pacific/Port_Moresby~~~West Pacific Standard Time
+/softwarestudio.org/Tzfile/Pacific/Rarotonga~~~Hawaiian Standard Time
+/softwarestudio.org/Tzfile/Pacific/Saipan~~~West Pacific Standard Time
+/softwarestudio.org/Tzfile/Pacific/Tahiti~~~Hawaiian Standard Time
+/softwarestudio.org/Tzfile/Pacific/Tarawa~~~Fiji Standard Time
+/softwarestudio.org/Tzfile/Pacific/Tongatapu~~~Tonga Standard Time
+/softwarestudio.org/Tzfile/Pacific/Truk~~~West Pacific Standard Time
+/softwarestudio.org/Tzfile/Pacific/Wake~~~Fiji Standard Time
+/softwarestudio.org/Tzfile/Pacific/Wallis~~~Fiji Standard Time
Added: branches/EXCHANGE_MAPI_BRANCH/servers/mapi/tz-mapi-to-ical
==============================================================================
--- (empty file)
+++ branches/EXCHANGE_MAPI_BRANCH/servers/mapi/tz-mapi-to-ical Thu Jul 3 08:02:54 2008
@@ -0,0 +1,87 @@
+Dateline Standard Time~~~/softwarestudio.org/Tzfile/Pacific/Apia
+Samoa Standard Time~~~/softwarestudio.org/Tzfile/Pacific/Midway
+Hawaiian Standard Time~~~/softwarestudio.org/Tzfile/Pacific/Honolulu
+Alaskan Standard Time~~~/softwarestudio.org/Tzfile/America/Anchorage
+Pacific Standard Time~~~/softwarestudio.org/Tzfile/America/Los_Angeles
+Pacific Standard Time (Mexico)~~~/softwarestudio.org/Tzfile/America/Tijuana
+US Mountain Standard Time~~~/softwarestudio.org/Tzfile/America/Phoenix
+Mountain Standard Time (Mexico)~~~/softwarestudio.org/Tzfile/America/Mazatlan
+Mexico Standard Time 2~~~/softwarestudio.org/Tzfile/America/Chihuahua
+Mountain Standard Time~~~/softwarestudio.org/Tzfile/America/Denver
+Central America Standard Time~~~/softwarestudio.org/Tzfile/America/Costa_Rica
+Central Standard Time~~~/softwarestudio.org/Tzfile/America/Chicago
+Central Standard Time (Mexico)~~~/softwarestudio.org/Tzfile/America/Monterrey
+Mexico Standard Time~~~/softwarestudio.org/Tzfile/America/Mexico_City
+Canada Central Standard Time~~~/softwarestudio.org/Tzfile/America/Winnipeg
+SA Pacific Standard Time~~~/softwarestudio.org/Tzfile/America/Bogota
+Eastern Standard Time~~~/softwarestudio.org/Tzfile/America/New_York
+US Eastern Standard Time~~~/softwarestudio.org/Tzfile/America/Indiana/Indianapolis
+Venezuela Standard Time~~~/softwarestudio.org/Tzfile/America/Caracas
+Atlantic Standard Time~~~/softwarestudio.org/Tzfile/America/Halifax
+SA Western Standard Time~~~/softwarestudio.org/Tzfile/America/La_Paz
+Central Brazilian Standard Time~~~/softwarestudio.org/Tzfile/America/Manaus
+Pacific SA Standard Time~~~/softwarestudio.org/Tzfile/America/La_Paz
+Newfoundland Standard Time~~~/softwarestudio.org/Tzfile/America/St_Johns
+E. South America Standard Time~~~/softwarestudio.org/Tzfile/America/Bahia
+SA Eastern Standard Time~~~/softwarestudio.org/Tzfile/America/Argentina/Buenos_Aires
+Greenland Standard Time~~~/softwarestudio.org/Tzfile/America/Godthab
+Montevideo Standard Time~~~/softwarestudio.org/Tzfile/America/Montevideo
+Mid-Atlantic Standard Time~~~/softwarestudio.org/Tzfile/Atlantic/South_Georgia
+Azores Standard Time~~~/softwarestudio.org/Tzfile/Atlantic/Azores
+Cape Verde Standard Time~~~/softwarestudio.org/Tzfile/Atlantic/Cape_Verde
+Greenwich Standard Time~~~/softwarestudio.org/Tzfile/Africa/Casablanca
+GMT Standard Time~~~UTC
+W. Europe Standard Time~~~/softwarestudio.org/Tzfile/Europe/Berlin
+Central Europe Standard Time~~~/softwarestudio.org/Tzfile/Europe/Prague
+Romance Standard Time~~~/softwarestudio.org/Tzfile/Europe/Paris
+Central European Standard Time~~~/softwarestudio.org/Tzfile/Europe/Belgrade
+W. Central Africa Standard Time~~~/softwarestudio.org/Tzfile/Africa/Luanda
+Jordan Standard Time~~~/softwarestudio.org/Tzfile/Asia/Amman
+GTB Standard Time~~~/softwarestudio.org/Tzfile/Europe/Athens
+Middle East Standard Time~~~/softwarestudio.org/Tzfile/Asia/Beirut
+Egypt Standard Time~~~/softwarestudio.org/Tzfile/Africa/Cairo
+South Africa Standard Time~~~/softwarestudio.org/Tzfile/Africa/Harare
+FLE Standard Time~~~/softwarestudio.org/Tzfile/Europe/Helsinki
+Israel Standard Time~~~/softwarestudio.org/Tzfile/Asia/Jerusalem
+E. Europe Standard Time~~~/softwarestudio.org/Tzfile/Europe/Minsk
+Namibia Standard Time~~~/softwarestudio.org/Tzfile/Africa/Windhoek
+Arabic Standard Time~~~/softwarestudio.org/Tzfile/Asia/Baghdad
+Arab Standard Time~~~/softwarestudio.org/Tzfile/Asia/Qatar
+Russian Standard Time~~~/softwarestudio.org/Tzfile/Europe/Moscow
+E. Africa Standard Time~~~/softwarestudio.org/Tzfile/Africa/Nairobi
+Georgian Standard Time~~~/softwarestudio.org/Tzfile/Asia/Tbilisi
+Iran Standard Time~~~/softwarestudio.org/Tzfile/Asia/Tehran
+Arabian Standard Time~~~/softwarestudio.org/Tzfile/Asia/Muscat
+Azerbaijan Standard Time~~~/softwarestudio.org/Tzfile/Asia/Baku
+Caucasus Standard Time~~~/softwarestudio.org/Tzfile/Asia/Yerevan
+Armenian Standard Time~~~/softwarestudio.org/Tzfile/Asia/Yerevan
+Afghanistan Standard Time~~~/softwarestudio.org/Tzfile/Asia/Kabul
+Ekaterinburg Standard Time~~~/softwarestudio.org/Tzfile/Asia/Yekaterinburg
+West Asia Standard Time~~~/softwarestudio.org/Tzfile/Asia/Karachi
+India Standard Time~~~/softwarestudio.org/Tzfile/Asia/Calcutta
+Sri Lanka Standard Time~~~/softwarestudio.org/Tzfile/Asia/Colombo
+Nepal Standard Time~~~/softwarestudio.org/Tzfile/Asia/Katmandu
+N. Central Asia Standard Time~~~/softwarestudio.org/Tzfile/Asia/Novosibirsk
+Central Asia Standard Time~~~/softwarestudio.org/Tzfile/Asia/Dhaka
+Myanmar Standard Time~~~/softwarestudio.org/Tzfile/Asia/Rangoon
+SE Asia Standard Time~~~/softwarestudio.org/Tzfile/Asia/Bangkok
+North Asia Standard Time~~~/softwarestudio.org/Tzfile/Asia/Krasnoyarsk
+China Standard Time~~~/softwarestudio.org/Tzfile/Asia/Shanghai
+North Asia East Standard Time~~~/softwarestudio.org/Tzfile/Asia/Ulaanbaatar
+Singapore Standard Time~~~/softwarestudio.org/Tzfile/Asia/Singapore
+W. Australia Standard Time~~~/softwarestudio.org/Tzfile/Australia/Perth
+Taipei Standard Time~~~/softwarestudio.org/Tzfile/Asia/Taipei
+Tokyo Standard Time~~~/softwarestudio.org/Tzfile/Asia/Tokyo
+Korea Standard Time~~~/softwarestudio.org/Tzfile/Asia/Seoul
+Yakutsk Standard Time~~~/softwarestudio.org/Tzfile/Asia/Yakutsk
+Cen. Australia Standard Time~~~/softwarestudio.org/Tzfile/Australia/Adelaide
+AUS Central Standard Time~~~/softwarestudio.org/Tzfile/Australia/Darwin
+E. Australia Standard Time~~~/softwarestudio.org/Tzfile/Australia/Brisbane
+AUS Eastern Standard Time~~~/softwarestudio.org/Tzfile/Australia/Sydney
+West Pacific Standard Time~~~/softwarestudio.org/Tzfile/Pacific/Guam
+Tasmania Standard Time~~~/softwarestudio.org/Tzfile/Australia/Hobart
+Vladivostok Standard Time~~~/softwarestudio.org/Tzfile/Asia/Vladivostok
+Central Pacific Standard Time~~~/softwarestudio.org/Tzfile/Asia/Magadan
+New Zealand Standard Time~~~/softwarestudio.org/Tzfile/Pacific/Auckland
+Fiji Standard Time~~~/softwarestudio.org/Tzfile/Pacific/Fiji
+Tonga Standard Time~~~/softwarestudio.org/Tzfile/Pacific/Tongatapu
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]