[evolution-mapi/native-gal] Add new files and create the MAPIGAL factory. Also pulls in
- From: Bharath Acharya <abharath src gnome org>
- To: svn-commits-list gnome org
- Subject: [evolution-mapi/native-gal] Add new files and create the MAPIGAL factory. Also pulls in
- Date: Mon, 20 Jul 2009 04:49:01 +0000 (UTC)
commit 87033ab585551d9e83e47b3410d6d00a5ba7d6db
Author: Bharath Acharya <abharath novell com>
Date: Mon Jul 20 10:16:36 2009 +0530
Add new files and create the MAPIGAL factory. Also pulls in
GAL entries from the Exchange server.
src/addressbook/Makefile.am | 17 +-
src/addressbook/e-book-backend-mapi-gal-factory.c | 51 ++
src/addressbook/e-book-backend-mapi-gal.c | 581 +++++++++++++++++++++
src/addressbook/e-book-backend-mapi-gal.h | 54 ++
src/libexchangemapi/exchange-mapi-connection.c | 57 ++
src/libexchangemapi/exchange-mapi-connection.h | 11 +-
6 files changed, 766 insertions(+), 5 deletions(-)
---
diff --git a/src/addressbook/Makefile.am b/src/addressbook/Makefile.am
index b385b9d..d6f2a00 100644
--- a/src/addressbook/Makefile.am
+++ b/src/addressbook/Makefile.am
@@ -7,13 +7,19 @@ AM_CPPFLAGS = \
$(LIBEDATABOOK_CFLAGS) \
$(LIBMAPI_CFLAGS)
-extension_LTLIBRARIES = libebookbackendmapi.la
+extension_LTLIBRARIES = libebookbackendmapi.la \
+ libebookbackendmapigal.la
libebookbackendmapi_la_SOURCES = \
e-book-backend-mapi.c \
e-book-backend-mapi.h \
e-book-backend-mapi-factory.c
+libebookbackendmapigal_la_SOURCES = \
+ e-book-backend-mapi-gal.c \
+ e-book-backend-mapi-gal.h \
+ e-book-backend-mapi-gal-factory.c
+
libebookbackendmapi_la_LIBADD = \
$(top_builddir)/src/libexchangemapi/libexchangemapi-1.0.la \
$(LIBEBACKEND_LIBS) \
@@ -21,8 +27,17 @@ libebookbackendmapi_la_LIBADD = \
$(LIBEDATABOOK_LIBS) \
$(LIBMAPI_LIBS)
+libebookbackendmapigal_la_LIBADD = \
+ $(top_builddir)/src/libexchangemapi/libexchangemapi-1.0.la \
+ $(LIBEBACKEND_LIBS) \
+ $(LIBEBOOK_LIBS) \
+ $(LIBEDATABOOK_LIBS) \
+ $(LIBMAPI_LIBS)
+
libebookbackendmapi_la_LDFLAGS = \
-module -avoid-version $(NO_UNDEFINED)
+libebookbackendmapigal_la_LDFLAGS = \
+ -module -avoid-version $(NO_UNDEFINED)
-include $(top_srcdir)/git.mk
diff --git a/src/addressbook/e-book-backend-mapi-gal-factory.c b/src/addressbook/e-book-backend-mapi-gal-factory.c
new file mode 100644
index 0000000..0fc5a8f
--- /dev/null
+++ b/src/addressbook/e-book-backend-mapi-gal-factory.c
@@ -0,0 +1,51 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * 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 the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * Bharath Acharya <abharath novell com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <libebackend/e-data-server-module.h>
+#include <libedata-book/e-book-backend-factory.h>
+#include "e-book-backend-mapi-gal.h"
+
+E_BOOK_BACKEND_FACTORY_SIMPLE (mapigal, MAPIGAL, e_book_backend_mapigal_new)
+
+static GType mapigal_type;
+
+void
+eds_module_initialize (GTypeModule *module)
+{
+ mapigal_type = _mapigal_factory_get_type (module);
+}
+
+void
+eds_module_shutdown (void)
+{
+}
+
+void
+eds_module_list_types (const GType **types, int *num_types)
+{
+ *types = & mapigal_type;
+ *num_types = 1;
+}
diff --git a/src/addressbook/e-book-backend-mapi-gal.c b/src/addressbook/e-book-backend-mapi-gal.c
new file mode 100644
index 0000000..fa28457
--- /dev/null
+++ b/src/addressbook/e-book-backend-mapi-gal.c
@@ -0,0 +1,581 @@
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <fcntl.h>
+#include <string.h>
+#include <glib.h>
+#include <glib/gstdio.h>
+
+#include <sys/time.h>
+
+#include <libedataserver/e-sexp.h>
+#include "libedataserver/e-flag.h"
+#include <libebook/e-contact.h>
+
+#include <libedata-book/e-book-backend-sexp.h>
+#include <libedata-book/e-data-book.h>
+#include <libedata-book/e-data-book-view.h>
+#include <libedata-book/e-book-backend-cache.h>
+#include <libedata-book/e-book-backend-summary.h>
+#include "e-book-backend-mapi-gal.h"
+
+static EBookBackendClass *e_book_backend_mapi_gal_parent_class;
+static gboolean enable_debug = TRUE;
+
+#define ELEMENT_TYPE_SIMPLE 0x01
+#define ELEMENT_TYPE_COMPLEX 0x02
+
+static const struct field_element_mapping {
+ EContactField field_id;
+ int element_type;
+ int mapi_id;
+ int contact_type;
+// char *element_name;
+// void (*populate_contact_func)(EContact *contact, gpointer data);
+// void (*set_value_in_gw_item) (EGwItem *item, gpointer data);
+// void (*set_changes) (EGwItem *new_item, EGwItem *old_item);
+
+ } mappings [] = {
+
+ { E_CONTACT_UID, PT_STRING8, 0, ELEMENT_TYPE_SIMPLE},
+ { E_CONTACT_REV, PT_SYSTIME, PR_LAST_MODIFICATION_TIME, ELEMENT_TYPE_SIMPLE},
+
+ { E_CONTACT_FILE_AS, PT_STRING8, PR_EMS_AB_MANAGER_T, ELEMENT_TYPE_SIMPLE},
+ { E_CONTACT_FULL_NAME, PT_STRING8, PR_DISPLAY_NAME, ELEMENT_TYPE_SIMPLE },
+ { E_CONTACT_GIVEN_NAME, PT_STRING8, PR_GIVEN_NAME, ELEMENT_TYPE_SIMPLE},
+ { E_CONTACT_FAMILY_NAME, PT_STRING8, PR_SURNAME , ELEMENT_TYPE_SIMPLE},
+ { E_CONTACT_NICKNAME, PT_STRING8, PR_NICKNAME, ELEMENT_TYPE_SIMPLE },
+
+ { E_CONTACT_EMAIL_1, PT_STRING8, PROP_TAG(PT_UNICODE, 0x8084), ELEMENT_TYPE_SIMPLE},
+ { E_CONTACT_EMAIL_2, PT_STRING8, PROP_TAG(PT_UNICODE, 0x8094), ELEMENT_TYPE_SIMPLE},
+ { E_CONTACT_EMAIL_3, PT_STRING8, PROP_TAG(PT_UNICODE, 0x80a4), ELEMENT_TYPE_SIMPLE},
+ { E_CONTACT_IM_AIM, PT_STRING8, PROP_TAG(PT_UNICODE, 0x8062), ELEMENT_TYPE_COMPLEX},
+
+ { E_CONTACT_PHONE_BUSINESS, PT_STRING8, PR_OFFICE_TELEPHONE_NUMBER, ELEMENT_TYPE_SIMPLE},
+ { E_CONTACT_PHONE_HOME, PT_STRING8, PR_HOME_TELEPHONE_NUMBER, ELEMENT_TYPE_SIMPLE},
+ { E_CONTACT_PHONE_MOBILE, PT_STRING8, PR_MOBILE_TELEPHONE_NUMBER, ELEMENT_TYPE_SIMPLE},
+ { E_CONTACT_PHONE_HOME_FAX, PT_STRING8, PR_HOME_FAX_NUMBER ,ELEMENT_TYPE_SIMPLE},
+ { E_CONTACT_PHONE_BUSINESS_FAX, PT_STRING8, PR_BUSINESS_FAX_NUMBER,ELEMENT_TYPE_SIMPLE},
+ { E_CONTACT_PHONE_PAGER, PT_STRING8, PR_PAGER_TELEPHONE_NUMBER,ELEMENT_TYPE_SIMPLE},
+ { E_CONTACT_PHONE_ASSISTANT, PT_STRING8, PR_ASSISTANT_TELEPHONE_NUMBER ,ELEMENT_TYPE_SIMPLE},
+ { E_CONTACT_PHONE_COMPANY, PT_STRING8, PR_COMPANY_MAIN_PHONE_NUMBER ,ELEMENT_TYPE_SIMPLE},
+
+ { E_CONTACT_HOMEPAGE_URL, PT_STRING8, 0x802b001e, ELEMENT_TYPE_SIMPLE},
+ { E_CONTACT_FREEBUSY_URL, PT_STRING8, 0x80d8001e, ELEMENT_TYPE_SIMPLE},
+
+ { E_CONTACT_ROLE, PT_STRING8, PR_PROFESSION, ELEMENT_TYPE_SIMPLE},
+ { E_CONTACT_TITLE, PT_STRING8, PR_TITLE, ELEMENT_TYPE_SIMPLE},
+ { E_CONTACT_ORG, PT_STRING8, PR_COMPANY_NAME, ELEMENT_TYPE_SIMPLE},
+ { E_CONTACT_ORG_UNIT, PT_STRING8, PR_DEPARTMENT_NAME,ELEMENT_TYPE_SIMPLE},
+ { E_CONTACT_MANAGER, PT_STRING8, PR_MANAGER_NAME, ELEMENT_TYPE_SIMPLE},
+ { E_CONTACT_ASSISTANT, PT_STRING8, PR_ASSISTANT, ELEMENT_TYPE_SIMPLE},
+
+ { E_CONTACT_OFFICE, PT_STRING8, PR_OFFICE_LOCATION, ELEMENT_TYPE_SIMPLE},
+ { E_CONTACT_SPOUSE, PT_STRING8, PR_SPOUSE_NAME, ELEMENT_TYPE_SIMPLE},
+
+ { E_CONTACT_BIRTH_DATE, PT_SYSTIME, PR_BIRTHDAY, ELEMENT_TYPE_COMPLEX},
+ { E_CONTACT_ANNIVERSARY, PT_SYSTIME, PR_WEDDING_ANNIVERSARY, ELEMENT_TYPE_COMPLEX},
+
+ { E_CONTACT_NOTE, PT_STRING8, PR_BODY, ELEMENT_TYPE_SIMPLE},
+
+
+ { E_CONTACT_ADDRESS_HOME, PT_STRING8, 0x801a001e, ELEMENT_TYPE_COMPLEX},
+ { E_CONTACT_ADDRESS_WORK, PT_STRING8, 0x801c001e, ELEMENT_TYPE_COMPLEX},
+// { E_CONTACT_BOOK_URI, ELEMENT_TYPE_SIMPLE, "book_uri"}
+// { E_CONTACT_EMAIL, PT_STRING8, 0x8084001e},
+// { E_CONTACT_CATEGORIES, },
+ };
+
+static int maplen = G_N_ELEMENTS(mappings);
+
+struct _EBookBackendMAPIGALPrivate
+{
+ char *profile;
+ mapi_id_t fid;
+ int mode;
+ gboolean marked_for_offline;
+ gboolean is_cache_ready;
+ gboolean is_summary_ready;
+ gboolean is_writable;
+ char *uri;
+ char *book_name;
+
+ GMutex *lock;
+ char *summary_file_name;
+ EBookBackendSummary *summary;
+ EBookBackendCache *cache;
+
+};
+
+#define SUMMARY_FLUSH_TIMEOUT 5000
+
+static char *
+e_book_backend_mapi_gal_get_static_capabilities (EBookBackend *backend)
+{
+ if(enable_debug)
+ printf("mapi get_static_capabilities\n");
+ //FIXME: Implement this.
+
+ return g_strdup ("net,bulk-removes,do-initial-query,contact-lists");
+}
+
+static void
+e_book_backend_mapi_gal_authenticate_user (EBookBackend *backend,
+ EDataBook *book,
+ guint32 opid,
+ const char *user,
+ const char *passwd,
+ const char *auth_method)
+{
+ EBookBackendMAPIGALPrivate *priv = ((EBookBackendMAPIGAL *) backend)->priv;
+
+ if (enable_debug) {
+ printf ("mapi: authenticate user\n");
+ }
+
+
+ switch (priv->mode) {
+ case GNOME_Evolution_Addressbook_MODE_LOCAL:
+ e_book_backend_notify_writable (backend, FALSE);
+ e_book_backend_notify_connection_status (backend, FALSE);
+ e_data_book_respond_authenticate_user (book, opid, GNOME_Evolution_Addressbook_Success);
+ return;
+
+ case GNOME_Evolution_Addressbook_MODE_REMOTE:
+
+ if (!exchange_mapi_connection_new (priv->profile, NULL))
+ return e_data_book_respond_authenticate_user (book, opid,GNOME_Evolution_Addressbook_OtherError);
+
+ if (priv->cache && priv->is_cache_ready) {
+ printf("FIXME: Should check for an update in the cache\n");
+// g_thread_create ((GThreadFunc) update_cache,
+ // backend, FALSE, backend);
+ } else if (priv->marked_for_offline && !priv->is_cache_ready) {
+ /* Means we dont have a cache. Lets build that first */
+ printf("Preparing to build cache\n");
+ // g_thread_create ((GThreadFunc) build_cache, backend, FALSE, NULL);
+ }
+ e_book_backend_set_is_writable (backend, TRUE);
+ e_data_book_respond_authenticate_user (book, opid, GNOME_Evolution_Addressbook_Success);
+ return;
+
+ default :
+ break;
+ }
+}
+
+static char *
+get_filename_from_uri (const char *uri, const char *file)
+{
+ char *mangled_uri, *filename;
+ int i;
+
+ /* mangle the URI to not contain invalid characters */
+ mangled_uri = g_strdup (uri);
+ for (i = 0; i < strlen (mangled_uri); i++) {
+ switch (mangled_uri[i]) {
+ case ':' :
+ case '/' :
+ mangled_uri[i] = '_';
+ }
+ }
+
+ /* generate the file name */
+ filename = g_build_filename (g_get_home_dir (), ".evolution/cache/addressbook",
+ mangled_uri, file, NULL);
+
+ /* free memory */
+ g_free (mangled_uri);
+
+ return filename;
+}
+
+static GNOME_Evolution_Addressbook_CallStatus
+e_book_backend_mapi_gal_load_source (EBookBackend *backend,
+ ESource *source,
+ gboolean only_if_exists)
+{
+ EBookBackendMAPIGALPrivate *priv = ((EBookBackendMAPIGAL *) backend)->priv;
+ const gchar *offline, *tmp;
+ char **tokens;
+ char *uri = NULL;
+ if (enable_debug)
+ printf("MAPI load source\n");
+ offline = e_source_get_property (source, "offline_sync");
+ if (offline && g_str_equal (offline, "1"))
+ priv->marked_for_offline = TRUE;
+
+
+
+ /* Either we are in Online mode or this is marked for offline */
+
+ priv->uri = g_strdup (e_source_get_uri (source));
+
+ tokens = g_strsplit (priv->uri, ";", 2);
+ if (tokens[0])
+ uri = g_strdup (tokens [0]);
+ priv->book_name = g_strdup (tokens[1]);
+ if (priv->book_name == NULL) {
+ g_warning ("Bookname is null for %s\n", uri);
+ return GNOME_Evolution_Addressbook_OtherError;
+ }
+ g_strfreev (tokens);
+
+ if (priv->mode == GNOME_Evolution_Addressbook_MODE_LOCAL &&
+ !priv->marked_for_offline ) {
+ return GNOME_Evolution_Addressbook_OfflineUnavailable;
+ }
+
+ if (priv->marked_for_offline) {
+ priv->summary_file_name = get_filename_from_uri (priv->uri, "cache.summary");
+ if (g_file_test (priv->summary_file_name, G_FILE_TEST_EXISTS)) {
+ printf("Loading the summary\n");
+ priv->summary = e_book_backend_summary_new (priv->summary_file_name,
+ SUMMARY_FLUSH_TIMEOUT);
+ e_book_backend_summary_load (priv->summary);
+ priv->is_summary_ready = TRUE;
+ }
+
+ /* Load the cache as well.*/
+ if (e_book_backend_cache_exists (priv->uri)) {
+ printf("Loading the cache\n");
+ priv->cache = e_book_backend_cache_new (priv->uri);
+ priv->is_cache_ready = TRUE;
+ }
+ //FIXME: We may have to do a time based reload. Or deltas should upload.
+ } else {
+ priv->summary = e_book_backend_summary_new (NULL,SUMMARY_FLUSH_TIMEOUT);
+ }
+
+ g_free (uri);
+ e_book_backend_set_is_loaded (E_BOOK_BACKEND (backend), TRUE);
+ e_book_backend_set_is_writable (backend, TRUE);
+ if (priv->mode == GNOME_Evolution_Addressbook_MODE_LOCAL) {
+ e_book_backend_set_is_writable (backend, FALSE);
+ e_book_backend_notify_writable (backend, FALSE);
+ e_book_backend_notify_connection_status (backend, FALSE);
+ if (!priv->cache) {
+ printf("Unfortunately the cache is not yet created\n");
+ return GNOME_Evolution_Addressbook_OfflineUnavailable;
+ }
+ } else {
+ e_book_backend_notify_connection_status (backend, TRUE);
+ }
+
+ priv->profile = g_strdup (e_source_get_property (source, "profile"));
+ exchange_mapi_util_mapi_id_from_string (e_source_get_property (source, "folder-id"), &priv->fid);
+
+ tmp = e_source_get_property (source, "folder-id");
+
+ /* Once aunthentication in address book works this can be removed */
+ if (priv->mode == GNOME_Evolution_Addressbook_MODE_LOCAL) {
+ return GNOME_Evolution_Addressbook_Success;
+ }
+
+ // writable property will be set in authenticate_user callback
+ e_book_backend_set_is_loaded (E_BOOK_BACKEND (backend), TRUE);
+ e_book_backend_notify_connection_status (E_BOOK_BACKEND (backend), TRUE);
+
+
+ if (enable_debug)
+ printf("For profile %s and folder %s - %016" G_GINT64_MODIFIER "X\n", priv->profile, tmp, priv->fid);
+
+ return GNOME_Evolution_Addressbook_Success;
+}
+
+static void
+e_book_backend_mapi_gal_set_mode (EBookBackend *backend, int mode)
+{
+ EBookBackendMAPIGALPrivate *priv = ((EBookBackendMAPIGAL *) backend)->priv;
+
+ if(enable_debug)
+ printf("mapi: set_mode \n");
+
+ priv->mode = mode;
+ if (e_book_backend_is_loaded (backend)) {
+ if (mode == GNOME_Evolution_Addressbook_MODE_LOCAL) {
+ e_book_backend_notify_writable (backend, FALSE);
+ e_book_backend_notify_connection_status (backend, FALSE);
+ /* FIXME: Uninitialize mapi here. may be.*/
+ }
+ else if (mode == GNOME_Evolution_Addressbook_MODE_REMOTE) {
+ e_book_backend_notify_writable (backend, TRUE);
+ e_book_backend_notify_connection_status (backend, TRUE);
+// e_book_backend_notify_auth_required (backend); //FIXME: WTH is this required.
+ }
+ }
+}
+
+static void
+e_book_backend_mapi_gal_dispose (GObject *object)
+{
+ /* FIXME : provide implmentation */
+ EBookBackendMAPIGALPrivate *priv = ((EBookBackendMAPIGAL *) object)->priv;
+
+ if (priv->profile) {
+ g_free (priv->profile);
+ priv->profile = NULL;
+ }
+ if (priv->uri) {
+ g_free (priv->uri);
+ priv->uri = NULL;
+ }
+
+}
+
+typedef struct {
+ EBookBackendMAPIGAL *bg;
+ GThread *thread;
+ EFlag *running;
+} BESearchClosure;
+
+static BESearchClosure*
+get_closure (EDataBookView *book_view)
+{
+ return g_object_get_data (G_OBJECT (book_view), "closure");
+}
+
+static EContact *
+emapidump_gal (struct SRow *gal_entry)
+{
+ EContact *contact = e_contact_new ();
+ int i;
+
+// exchange_mapi_debug_property_dump (properties);
+ for (i=1; i<maplen; i++) {
+ gpointer value;
+
+ /* can cast it, no writing to the value; and it'll be freed not before the end of this function */
+ value = (gpointer) find_SPropValue_data (gal_entry, mappings[i].mapi_id);
+ if (mappings[i].element_type == PT_STRING8 && mappings[i].contact_type == ELEMENT_TYPE_SIMPLE) {
+ if (value)
+ e_contact_set (contact, mappings[i].field_id, value);
+ } else if (mappings[i].contact_type == ELEMENT_TYPE_SIMPLE) {
+ if (value && mappings[i].element_type == PT_SYSTIME) {
+ struct FILETIME *t = value;
+ time_t time;
+ NTTIME nt;
+ char buff[129];
+
+ nt = t->dwHighDateTime;
+ nt = nt << 32;
+ nt |= t->dwLowDateTime;
+ time = nt_time_to_unix (nt);
+ e_contact_set (contact, mappings[i].field_id, ctime_r (&time, buff));
+ } else
+ printf("Nothing is printed\n");
+ }
+ }
+}
+
+static gboolean
+create_gal_contact_cb (FetchItemsCallbackData *item_data, gpointer data)
+{
+ EDataBookView *book_view = data;
+ BESearchClosure *closure = get_closure (book_view);
+ EBookBackendMAPIGAL *be = closure->bg;
+ EContact *contact;
+ EBookBackendMAPIGALPrivate *priv = ((EBookBackendMAPIGAL *) be)->priv;
+ char *suid;
+ GSList *l;
+ int counter;
+
+ if (!e_flag_is_set (closure->running)) {
+ printf("Might be that the operation is cancelled. Lets ask our parent also to do.\n");
+ return FALSE;
+ }
+
+// contact = emapidump_contact (item_data->properties);
+ for (l=item_data->gallist; l; l=l->next) {
+ struct SRow *SRow = (struct SRow *) (l->data);
+ counter++;
+ contact = emapidump_gal (SRow);
+ suid = exchange_mapi_util_mapi_ids_to_uid (item_data->fid, item_data->mid);
+
+ if (contact) {
+ /* UID of the contact is nothing but the concatenated string of hex id of folder and the message.*/
+ e_contact_set (contact, E_CONTACT_UID, suid);
+ e_contact_set (contact, E_CONTACT_BOOK_URI, priv->uri);
+ e_data_book_view_notify_update (book_view, contact);
+ g_object_unref(contact);
+ }
+
+ g_free (suid);
+ }
+ g_print ("\n The counter for the above data is %d\n", counter);
+ return TRUE;
+}
+
+static void
+book_view_thread (gpointer data)
+{
+ struct mapi_SRestriction res;
+ struct mapi_SRestriction_or *or_res = NULL;
+ EDataBookView *book_view = data;
+ BESearchClosure *closure = get_closure (book_view);
+ EBookBackendMAPIGAL *backend = closure->bg;
+ EBookBackendMAPIGALPrivate *priv = backend->priv;
+ const char *query = NULL;
+ GPtrArray *ids = NULL;
+ GList *contacts = NULL, *temp_list = NULL;
+ //Number of multiple restriction to apply
+ unsigned int res_count = 6;
+
+ if (enable_debug)
+ printf("mapi: book view\n");
+
+ bonobo_object_ref (book_view);
+ e_flag_set (closure->running);
+
+ e_data_book_view_notify_status_message (book_view, "Searching...");
+ query = e_data_book_view_get_card_query (book_view);
+
+ switch (priv->mode) {
+ case GNOME_Evolution_Addressbook_MODE_REMOTE:
+ if (!exchange_mapi_connection_fetch_items (priv->fid, NULL, NULL,
+ NULL, 0,
+ NULL, NULL,
+ create_gal_contact_cb, book_view,
+ MAPI_OPTIONS_FETCH_GAL)) {
+ if (e_flag_is_set (closure->running))
+ e_data_book_view_notify_complete (book_view,
+ GNOME_Evolution_Addressbook_OtherError);
+ bonobo_object_unref (book_view);
+ return;
+ }
+
+ if (e_flag_is_set (closure->running))
+ e_data_book_view_notify_complete (book_view,
+ GNOME_Evolution_Addressbook_Success);
+ bonobo_object_unref (book_view);
+ break;
+
+ }
+}
+
+static void
+closure_destroy (BESearchClosure *closure)
+{
+ e_flag_free (closure->running);
+ g_free (closure);
+}
+
+static BESearchClosure*
+init_closure (EDataBookView *book_view, EBookBackendMAPIGAL *bg)
+{
+ BESearchClosure *closure = g_new (BESearchClosure, 1);
+
+ closure->bg = bg;
+ closure->thread = NULL;
+ closure->running = e_flag_new ();
+
+ g_object_set_data_full (G_OBJECT (book_view), "closure",
+ closure, (GDestroyNotify)closure_destroy);
+
+ return closure;
+}
+
+
+static void
+e_book_backend_mapi_gal_start_book_view (EBookBackend *backend,
+ EDataBookView *book_view)
+{
+ BESearchClosure *closure = init_closure (book_view, E_BOOK_BACKEND_MAPIGAL (backend));
+
+ if (enable_debug)
+ printf ("mapi: start_book_view...\n");
+ closure->thread = g_thread_create ((GThreadFunc) book_view_thread, book_view, FALSE, NULL);
+ e_flag_wait (closure->running);
+
+ /* at this point we know the book view thread is actually running */
+}
+
+static void
+e_book_backend_mapi_gal_stop_book_view (EBookBackend *backend,
+ EDataBookView *book_view)
+{
+ if(enable_debug)
+ printf("mapi: stop book view\n");
+ /* FIXME : provide implmentation */
+}
+
+static void e_book_backend_mapi_gal_class_init (EBookBackendMAPIGALClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ EBookBackendClass *parent_class;
+
+ e_book_backend_mapi_gal_parent_class = g_type_class_peek_parent (klass);
+
+ parent_class = E_BOOK_BACKEND_CLASS (klass);
+
+ /* Set the virtual methods. */
+ parent_class->load_source = e_book_backend_mapi_gal_load_source;
+ parent_class->get_static_capabilities = e_book_backend_mapi_gal_get_static_capabilities;
+
+ parent_class->start_book_view = e_book_backend_mapi_gal_start_book_view;
+ parent_class->stop_book_view = e_book_backend_mapi_gal_stop_book_view;
+ parent_class->authenticate_user = e_book_backend_mapi_gal_authenticate_user;
+ parent_class->set_mode = e_book_backend_mapi_gal_set_mode;
+ object_class->dispose = e_book_backend_mapi_gal_dispose;
+}
+
+/**
+ * e_book_backend_mapigal_new:
+ */
+EBookBackend *
+e_book_backend_mapigal_new (void)
+{
+ EBookBackendMAPIGAL *backend;
+
+// if (enable_debug)
+ printf ("\ne_book_backend_mapigal_new...\n");
+
+ backend = g_object_new (E_TYPE_BOOK_BACKEND_MAPIGAL, NULL);
+
+ return E_BOOK_BACKEND (backend);
+}
+
+static void e_book_backend_mapi_gal_init (EBookBackendMAPIGAL *backend)
+{
+ EBookBackendMAPIGALPrivate *priv;
+
+ priv= g_new0 (EBookBackendMAPIGALPrivate, 1);
+ /* Priv Struct init */
+ backend->priv = priv;
+
+/* priv->marked_for_offline = FALSE;
+ priv->uri = NULL;
+ priv->cache = NULL;
+ priv->is_summary_ready = FALSE;
+ priv->is_cache_ready = FALSE;
+
+*/ if (g_getenv ("MAPI_DEBUG"))
+ enable_debug = TRUE;
+ else
+ enable_debug = FALSE;
+}
+
+GType e_book_backend_mapigal_get_type (void)
+{
+ static GType type = 0;
+
+ if (! type) {
+ GTypeInfo info = {
+ sizeof (EBookBackendMAPIGALClass),
+ NULL, /* base_class_init */
+ NULL, /* base_class_finalize */
+ (GClassInitFunc) e_book_backend_mapi_gal_class_init,
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof (EBookBackendMAPIGAL),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) e_book_backend_mapi_gal_init
+ };
+
+ type = g_type_register_static (E_TYPE_BOOK_BACKEND, "EBookBackendMAPIGAL", &info, 0);
+ }
+
+ return type;
+}
diff --git a/src/addressbook/e-book-backend-mapi-gal.h b/src/addressbook/e-book-backend-mapi-gal.h
new file mode 100644
index 0000000..3e17ae1
--- /dev/null
+++ b/src/addressbook/e-book-backend-mapi-gal.h
@@ -0,0 +1,54 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * 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 the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * Bharath Acharya <abharath novell com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef __E_BOOK_BACKEND_MAPIGAL_H__
+#define __E_BOOK_BACKEND_MAPIGAL_H__
+
+#include <libedata-book/e-book-backend.h>
+#include <libedata-book/e-book-backend-sync.h>
+#include "exchange-mapi-connection.h"
+#include "exchange-mapi-defs.h"
+#include "exchange-mapi-utils.h"
+
+typedef struct _EBookBackendMAPIGALPrivate EBookBackendMAPIGALPrivate;
+
+typedef struct {
+ EBookBackend parent_object;
+ EBookBackendMAPIGALPrivate *priv;
+} EBookBackendMAPIGAL;
+
+typedef struct {
+ EBookBackendClass parent_class;
+} EBookBackendMAPIGALClass;
+
+EBookBackend *e_book_backend_mapigal_new (void);
+GType e_book_backend_mapigal_get_type (void);
+
+#define E_TYPE_BOOK_BACKEND_MAPIGAL (e_book_backend_mapigal_get_type ())
+#define E_BOOK_BACKEND_MAPIGAL(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), E_TYPE_BOOK_BACKEND_MAPIGAL, EBookBackendMAPIGAL))
+#define E_BOOK_BACKEND_MAPIGAL_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), E_TYPE_BOOK_BACKEND_MAPIGAL, EBookBackendMAPIGALClass))
+#define E_IS_BOOK_BACKEND_MAPIGAL(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), E_TYPE_BOOK_BACKEND_MAPIGAL))
+#define E_IS_BOOK_BACKEND_MAPIGAL_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), E_TYPE_BOOK_BACKEND_MAPIGAL))
+
+#endif /* ! __E_BOOK_BACKEND_MAPIGAL_H__ */
+
diff --git a/src/libexchangemapi/exchange-mapi-connection.c b/src/libexchangemapi/exchange-mapi-connection.c
index b5a1a77..2a34fd0 100644
--- a/src/libexchangemapi/exchange-mapi-connection.c
+++ b/src/libexchangemapi/exchange-mapi-connection.c
@@ -708,6 +708,59 @@ cleanup:
return status;
}
+static gboolean
+exchange_mapi_util_get_gal (GSList **gal_list)
+{
+ struct SPropTagArray *SPropTagArray;
+ struct SRowSet *SRowSet;
+ enum MAPISTATUS retval;
+ uint32_t i;
+ uint32_t count;
+ uint8_t ulFlags;
+ TALLOC_CTX *mem_ctx;
+
+ mem_ctx = talloc_init ("ExchangeMAPI_GetGAL");
+
+ SPropTagArray = set_SPropTagArray(mem_ctx, 0xc,
+ PR_INSTANCE_KEY,
+ PR_ENTRYID,
+ PR_DISPLAY_NAME_UNICODE,
+ PR_EMAIL_ADDRESS_UNICODE,
+ PR_DISPLAY_TYPE,
+ PR_OBJECT_TYPE,
+ PR_ADDRTYPE_UNICODE,
+ PR_OFFICE_TELEPHONE_NUMBER_UNICODE,
+ PR_OFFICE_LOCATION_UNICODE,
+ PR_TITLE_UNICODE,
+ PR_COMPANY_NAME_UNICODE,
+ PR_ACCOUNT_UNICODE);
+
+ count = 0x7;
+ ulFlags = TABLE_START;
+ do {
+ count += 0x2;
+ retval = GetGALTable(global_mapi_session, SPropTagArray, &SRowSet, count, ulFlags);
+ if ((!SRowSet) || (!(SRowSet->aRow))) {
+ return false;
+ }
+ if (SRowSet->cRows) {
+ for (i = 0; i < SRowSet->cRows; i++) {
+ mapidump_PAB_entry(&SRowSet->aRow[i]);
+ }
+ }
+ ulFlags = TABLE_CUR;
+ MAPIFreeBuffer(SRowSet);
+ } while (SRowSet->cRows == count);
+ mapi_errstr("GetPABTable", GetLastError());
+
+ MAPIFreeBuffer(SPropTagArray);
+
+ return true;
+
+}
+
+
+
/* Returns TRUE if all recipients were read succcesfully, else returns FALSE */
static gboolean
exchange_mapi_util_get_recipients (mapi_object_t *obj_message, GSList **recip_list)
@@ -1133,6 +1186,7 @@ exchange_mapi_connection_fetch_items (mapi_id_t fid,
const bool *has_attach = NULL;
GSList *attach_list = NULL;
GSList *recip_list = NULL;
+ GSList *gal_list = NULL;
GSList *stream_list = NULL;
gboolean cb_retval = false;
@@ -1156,6 +1210,9 @@ exchange_mapi_connection_fetch_items (mapi_id_t fid,
if (options & MAPI_OPTIONS_FETCH_RECIPIENTS)
exchange_mapi_util_get_recipients (&obj_message, &recip_list);
+ if (options & MAPI_OPTIONS_FETCH_GAL)
+ exchange_mapi_util_get_gal (&gal_list);
+
/* get the main body stream no matter what */
if (options & MAPI_OPTIONS_FETCH_BODY_STREAM)
exchange_mapi_util_read_body_stream (&obj_message, &stream_list,
diff --git a/src/libexchangemapi/exchange-mapi-connection.h b/src/libexchangemapi/exchange-mapi-connection.h
index ca13543..4261c1c 100644
--- a/src/libexchangemapi/exchange-mapi-connection.h
+++ b/src/libexchangemapi/exchange-mapi-connection.h
@@ -33,10 +33,11 @@ typedef enum {
MAPI_OPTIONS_FETCH_ATTACHMENTS = 1<<0,
MAPI_OPTIONS_FETCH_RECIPIENTS = 1<<1,
MAPI_OPTIONS_FETCH_BODY_STREAM = 1<<2,
- MAPI_OPTIONS_FETCH_GENERIC_STREAMS = 1<<3,
- MAPI_OPTIONS_DONT_SUBMIT = 1<<4,
- MAPI_OPTIONS_GETBESTBODY = 1<<5,
- MAPI_OPTIONS_USE_PFSTORE = 1<<6
+ MAPI_OPTIONS_FETCH_GENERIC_STREAMS = 1<<3,
+ MAPI_OPTIONS_FETCH_GAL = 1 <<4,
+ MAPI_OPTIONS_DONT_SUBMIT = 1<<5,
+ MAPI_OPTIONS_GETBESTBODY = 1<<6,
+ MAPI_OPTIONS_USE_PFSTORE = 1<<7
} ExchangeMAPIOptions;
#define MAPI_OPTIONS_FETCH_ALL MAPI_OPTIONS_FETCH_ATTACHMENTS | \
@@ -44,6 +45,7 @@ typedef enum {
MAPI_OPTIONS_FETCH_BODY_STREAM | \
MAPI_OPTIONS_FETCH_GENERIC_STREAMS
+
typedef struct {
GByteArray *value;
uint32_t proptag;
@@ -95,6 +97,7 @@ typedef struct {
mapi_id_t mid;
GSList *attachments;
GSList *recipients;
+ GSList *gallist;
GSList *streams;
guint total; /*Total number of results*/
guint index; /*Index of this Item*/
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]