1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2 /* camel-groupwise-store.c : class for an groupwise store */
6 * Sivaiah Nallagatla <snallagatla@novell.com>
7 * parthasarathi susarla <sparthasarathi@novell.com>
9 * Copyright 2004 Novell, Inc.
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of version 2 of the GNU Lesser General Public
13 * License as published by the Free Software Foundation.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * General Public License for more details.
20 * You should have received a copy of the GNU Lesser General Public
21 * License along with this program; if not, write to the
22 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
23 * Boston, MA 02110-1301, USA.
34 #include <sys/types.h>
38 #include <glib/gi18n-lib.h>
39 #include <glib/gstdio.h>
41 #include "camel-debug.h"
42 #include "camel-folder.h"
43 #include "camel-net-utils.h"
44 #include "camel-private.h"
45 #include "camel-session.h"
46 #include "camel-types.h"
48 #include "camel-groupwise-folder.h"
49 #include "camel-groupwise-store-summary.h"
50 #include "camel-groupwise-store.h"
51 #include "camel-groupwise-summary.h"
52 #include "camel-groupwise-utils.h"
55 #define CURSOR_ITEM_LIMIT 100
57 #define JUNK_PERSISTENCE 14
60 struct _CamelGroupwiseStorePrivate {
69 GHashTable *id_hash; /*get names from ids*/
70 GHashTable *name_hash;/*get ids from names*/
71 GHashTable *parent_hash;
75 static CamelOfflineStoreClass *parent_class = NULL;
77 extern CamelServiceAuthType camel_groupwise_password_authtype; /*for the query_auth_types function*/
78 CamelFolderInfo *convert_to_folder_info (CamelGroupwiseStore *store, EGwContainer *container, const char *url, CamelException *ex);
79 static void groupwise_folders_sync (CamelGroupwiseStore *store, CamelException *ex);
80 static int match_path(const char *path, const char *name);
85 groupwise_store_construct (CamelService *service, CamelSession *session,
86 CamelProvider *provider, CamelURL *url,
89 CamelGroupwiseStore *groupwise_store = CAMEL_GROUPWISE_STORE (service);
90 CamelStore *store = CAMEL_STORE (service);
91 const char *property_value;
92 CamelGroupwiseStorePrivate *priv = groupwise_store->priv;
95 d("in groupwise store constrcut\n");
97 CAMEL_SERVICE_CLASS (parent_class)->construct (service, session, provider, url, ex);
98 if (camel_exception_is_set (ex))
101 if (!(url->host || url->user)) {
102 camel_exception_set (ex, CAMEL_EXCEPTION_SERVICE_INVALID,
103 _("Host or user not available in url"));
106 /*XXX: The number 3 assigned to the list_loaded variable denotes
107 * the number of times the get_folder_info is called during startup.
108 * We are just trying to minimize the call.
109 * This is a dirty hack. But it *WORKS*
111 groupwise_store->list_loaded = 3;
114 priv->storage_path = camel_session_get_storage_path (session, service, ex);
115 if (!priv->storage_path)
119 path = g_alloca (strlen (priv->storage_path) + 32);
120 sprintf (path, "%s/.summary", priv->storage_path);
121 groupwise_store->summary = camel_groupwise_store_summary_new ();
122 camel_store_summary_set_filename ((CamelStoreSummary *)groupwise_store->summary, path);
123 camel_store_summary_touch ((CamelStoreSummary *)groupwise_store->summary);
124 camel_store_summary_load ((CamelStoreSummary *) groupwise_store->summary);
127 priv->server_name = g_strdup (url->host);
128 priv->user = g_strdup (url->user);
131 priv->base_url = camel_url_to_string (service->url, (CAMEL_URL_HIDE_PASSWORD |
132 CAMEL_URL_HIDE_PARAMS |
133 CAMEL_URL_HIDE_AUTH) );
136 property_value = camel_url_get_param (url, "soap_port");
137 if (property_value == NULL)
138 priv->port = g_strdup ("7191");
139 else if(strlen(property_value) == 0)
140 priv->port = g_strdup ("7191");
142 priv->port = g_strdup (property_value);
145 if (camel_url_get_param (url, "filter"))
146 store->flags |= CAMEL_STORE_FILTER_INBOX;
149 priv->id_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
150 priv->name_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
151 priv->parent_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
154 priv->use_ssl = g_strdup (camel_url_get_param (url, "use_ssl"));
156 store->flags &= ~CAMEL_STORE_VJUNK;
157 store->flags &= ~CAMEL_STORE_VTRASH;
161 groupwise_hash_folder_name (gconstpointer key)
163 return g_str_hash (key);
167 groupwise_compare_folder_name (gconstpointer a, gconstpointer b)
169 gconstpointer aname = a, bname = b;
171 return g_str_equal (aname, bname);
175 groupwise_auth_loop (CamelService *service, CamelException *ex)
177 CamelSession *session = camel_service_get_session (service);
178 CamelStore *store = CAMEL_STORE (service);
179 CamelGroupwiseStore *groupwise_store = CAMEL_GROUPWISE_STORE (store);
180 CamelGroupwiseStorePrivate *priv = groupwise_store->priv;
182 gboolean authenticated = FALSE;
185 if (priv->use_ssl && !g_str_equal (priv->use_ssl, "never"))
186 uri = g_strconcat ("https://", priv->server_name, ":", priv->port, "/soap", NULL);
188 uri = g_strconcat ("http://", priv->server_name, ":", priv->port, "/soap", NULL);
189 service->url->passwd = NULL;
192 while (!authenticated) {
194 /* We need to un-cache the password before prompting again */
195 camel_session_forget_password (session, service, "Groupwise", "password", ex);
196 g_free (service->url->passwd);
197 service->url->passwd = NULL;
201 if (!service->url->passwd && !(store->flags & CAMEL_STORE_PROXY)) {
204 prompt = g_strdup_printf (_("%sPlease enter the GroupWise "
205 "password for %s@%s"),
206 errbuf ? errbuf : "",
209 service->url->passwd =
210 camel_session_get_password (session, service, "Groupwise",
211 prompt, "password", CAMEL_SESSION_PASSWORD_SECRET, ex);
216 if (!service->url->passwd) {
217 camel_exception_set (ex, CAMEL_EXCEPTION_USER_CANCEL,
218 _("You did not enter a password."));
223 priv->cnc = e_gw_connection_new (uri, priv->user, service->url->passwd);
224 if (!E_IS_GW_CONNECTION(priv->cnc) && priv->use_ssl && g_str_equal (priv->use_ssl, "when-possible")) {
225 char *http_uri = g_strconcat ("http://", uri + 8, NULL);
226 priv->cnc = e_gw_connection_new (http_uri, priv->user, service->url->passwd);
229 if (!E_IS_GW_CONNECTION(priv->cnc)) {
230 errbuf = g_strdup_printf (_("Unable to authenticate "
231 "to GroupWise server. "));
233 camel_exception_clear (ex);
235 authenticated = TRUE;
243 check_for_connection (CamelService *service, CamelException *ex)
245 CamelGroupwiseStore *groupwise_store = CAMEL_GROUPWISE_STORE (service);
246 CamelGroupwiseStorePrivate *priv = groupwise_store->priv;
247 struct addrinfo hints, *ai;
249 memset (&hints, 0, sizeof(hints));
250 hints.ai_socktype = SOCK_STREAM;
251 hints.ai_family = PF_UNSPEC;
252 ai = camel_getaddrinfo(priv->server_name, "groupwise", &hints, ex);
253 if (ai == NULL && priv->port != NULL && camel_exception_get_id(ex) != CAMEL_EXCEPTION_USER_CANCEL) {
254 camel_exception_clear (ex);
255 ai = camel_getaddrinfo(priv->server_name, priv->port, &hints, ex);
260 camel_freeaddrinfo (ai);
267 groupwise_connect (CamelService *service, CamelException *ex)
269 CamelGroupwiseStore *store = CAMEL_GROUPWISE_STORE (service);
270 CamelGroupwiseStorePrivate *priv = store->priv;
271 CamelGroupwiseStoreNamespace *ns;
272 CamelSession *session = service->session;
274 d("in groupwise store connect\n");
276 /* if (((CamelOfflineStore *) store)->state == CAMEL_OFFLINE_STORE_NETWORK_UNAVAIL ||
277 (service->status == CAMEL_SERVICE_DISCONNECTED))
279 if (service->status == CAMEL_SERVICE_DISCONNECTED)
283 store->priv = g_new0 (CamelGroupwiseStorePrivate, 1);
285 camel_service_construct (service, service->session, service->provider, service->url, ex);
288 CAMEL_SERVICE_REC_LOCK (service, connect_lock);
291 CAMEL_SERVICE_REC_UNLOCK (service, connect_lock);
295 if (!check_for_connection (service, ex) || !groupwise_auth_loop (service, ex)) {
296 CAMEL_SERVICE_REC_UNLOCK (service, connect_lock);
297 camel_service_disconnect (service, TRUE, NULL);
302 service->status = CAMEL_SERVICE_CONNECTED;
303 ((CamelOfflineStore *) store)->state = CAMEL_OFFLINE_STORE_NETWORK_AVAIL;
305 if (!e_gw_connection_get_version (priv->cnc)) {
306 camel_session_alert_user(session,
307 CAMEL_SESSION_ALERT_WARNING,
308 _("Some features may not work correctly with your current server version"),
313 ns = camel_groupwise_store_summary_namespace_new (store->summary, priv->storage_path, '/');
314 camel_groupwise_store_summary_namespace_set (store->summary, ns);
316 if (camel_store_summary_count ((CamelStoreSummary *)store->summary) == 0) {
317 /*Settting the refresh stamp to the current time*/
318 store->refresh_stamp = time (0);
321 camel_store_summary_save ((CamelStoreSummary *) store->summary);
323 CAMEL_SERVICE_REC_UNLOCK (service, connect_lock);
324 if (E_IS_GW_CONNECTION (priv->cnc)) {
333 groupwise_disconnect_cleanup (CamelService *service, gboolean clean, CamelException *ex)
335 CamelGroupwiseStore *groupwise_store = CAMEL_GROUPWISE_STORE (service);
336 CamelGroupwiseStorePrivate *priv = groupwise_store->priv;
338 g_print ("camel_groupwise_store_finalize\n");
339 if (groupwise_store->summary) {
340 camel_store_summary_save ((CamelStoreSummary *)groupwise_store->summary);
341 camel_object_unref (groupwise_store->summary);
349 if (priv->server_name) {
350 g_free (priv->server_name);
351 priv->server_name = NULL;
358 g_free (priv->use_ssl);
359 priv->use_ssl = NULL;
361 if (priv->base_url) {
362 g_free (priv->base_url);
363 priv->base_url = NULL;
366 if (priv->storage_path)
367 g_free(priv->storage_path);
369 if(groupwise_store->root_container)
370 g_free (groupwise_store->root_container);
373 g_hash_table_destroy (priv->id_hash);
376 g_hash_table_destroy (priv->name_hash);
378 if (priv->parent_hash)
379 g_hash_table_destroy (priv->parent_hash);
381 g_free (groupwise_store->priv);
382 groupwise_store->priv = NULL;
388 groupwise_disconnect (CamelService *service, gboolean clean, CamelException *ex)
390 CamelGroupwiseStore *groupwise_store = CAMEL_GROUPWISE_STORE (service);
393 CAMEL_SERVICE_REC_LOCK (groupwise_store, connect_lock);
394 if (groupwise_store->priv && groupwise_store->priv->cnc) {
395 g_object_unref (groupwise_store->priv->cnc);
396 groupwise_store->priv->cnc = NULL;
398 CAMEL_SERVICE_REC_UNLOCK (groupwise_store, connect_lock);
401 //groupwise_disconnect_cleanup (service, clean, ex);
406 groupwise_store_query_auth_types (CamelService *service, CamelException *ex)
408 GList *auth_types = NULL;
410 d("in query auth types\n");
411 auth_types = g_list_prepend (auth_types, &camel_groupwise_password_authtype);
416 groupwise_is_system_folder (const char *folder_name)
418 if (!strcmp (folder_name, "Mailbox") ||
419 !strcmp (folder_name, "Trash") ||
420 !strcmp (folder_name, "Junk Mail") ||
421 !strcmp (folder_name, "Sent Items") ||
422 !strcmp (folder_name, "Cabinet") ||
423 !strcmp (folder_name, "Documents") )
429 /*Build/populate CamelFolderInfo structure based on the imap_build_folder_info function*/
430 static CamelFolderInfo *
431 groupwise_build_folder_info(CamelGroupwiseStore *gw_store, const char *parent_name, const char *folder_name)
436 CamelGroupwiseStorePrivate *priv = gw_store->priv;
438 fi = g_malloc0(sizeof(*fi));
444 if (strlen(parent_name) > 0)
445 fi->full_name = g_strconcat(parent_name, "/", folder_name, NULL);
447 fi->full_name = g_strdup (folder_name);
449 fi->full_name = g_strdup(folder_name);
451 url = camel_url_new(priv->base_url,NULL);
453 url->path = g_strdup_printf("/%s", fi->full_name);
454 fi->uri = camel_url_to_string(url,CAMEL_URL_HIDE_ALL);
457 name = strrchr(fi->full_name,'/');
459 name = fi->full_name;
462 if (!strcmp (folder_name, "Sent Items"))
463 fi->flags |= CAMEL_FOLDER_TYPE_SENT;
464 else if (!strcmp (folder_name, "Mailbox"))
465 fi->flags |= CAMEL_FOLDER_TYPE_INBOX;
466 else if (!strcmp (folder_name, "Trash"))
467 fi->flags |= CAMEL_FOLDER_TYPE_TRASH;
468 else if (!strcmp (folder_name, "Junk Mail"))
469 fi->flags |= CAMEL_FOLDER_TYPE_JUNK;
471 fi->name = g_strdup(name);
476 groupwise_forget_folder (CamelGroupwiseStore *gw_store, const char *folder_name, CamelException *ex)
478 CamelFolderSummary *summary;
479 CamelGroupwiseStorePrivate *priv = gw_store->priv;
480 char *summary_file, *state_file;
481 char *folder_dir, *storage_path;
488 storage_path = g_strdup_printf ("%s/folders", priv->storage_path);
489 folder_dir = g_strdup(e_path_to_physical (storage_path,folder_name));
491 if (g_access(folder_dir, F_OK) != 0) {
496 summary_file = g_strdup_printf ("%s/summary", folder_dir);
497 summary = camel_groupwise_summary_new(NULL,summary_file);
499 g_free(summary_file);
504 camel_object_unref (summary);
505 g_unlink (summary_file);
506 g_free (summary_file);
509 state_file = g_strdup_printf ("%s/cmeta", folder_dir);
510 g_unlink (state_file);
513 g_rmdir (folder_dir);
516 camel_store_summary_remove_path ( (CamelStoreSummary *)gw_store->summary, folder_name);
517 camel_store_summary_save ( (CamelStoreSummary *)gw_store->summary);
519 fi = groupwise_build_folder_info(gw_store, NULL, folder_name);
520 camel_object_trigger_event (CAMEL_OBJECT (gw_store), "folder_deleted", fi);
521 camel_folder_info_free (fi);
525 groupwise_get_folder_from_disk (CamelStore *store, const char *folder_name, guint32 flags, CamelException *ex)
527 CamelGroupwiseStore *gw_store = CAMEL_GROUPWISE_STORE (store);
528 CamelGroupwiseStorePrivate *priv = gw_store->priv;
530 char *folder_dir, *storage_path;
532 storage_path = g_strdup_printf("%s/folders", priv->storage_path);
533 folder_dir = e_path_to_physical (storage_path, folder_name);
534 g_free(storage_path);
535 if (!folder_dir || g_access (folder_dir, F_OK) != 0) {
537 camel_exception_setv (ex, CAMEL_EXCEPTION_STORE_NO_FOLDER,
538 _("No such folder %s"), folder_name);
542 folder = camel_gw_folder_new (store, folder_name, folder_dir, ex);
549 groupwise_get_folder (CamelStore *store, const char *folder_name, guint32 flags, CamelException *ex)
551 CamelGroupwiseStore *gw_store = CAMEL_GROUPWISE_STORE (store);
552 CamelGroupwiseStorePrivate *priv = gw_store->priv;
554 CamelGroupwiseSummary *summary;
555 char *container_id, *folder_dir, *storage_path;
556 EGwConnectionStatus status;
558 gboolean done = FALSE, all_ok = TRUE;
559 const char *position = E_GW_CURSOR_POSITION_END;
560 int count = 0, cursor, summary_count = 0;
561 CamelStoreInfo *si = NULL;
564 folder = groupwise_get_folder_from_disk (store, folder_name, flags, ex);
566 camel_object_ref (folder);
570 camel_exception_clear (ex);
572 CAMEL_SERVICE_REC_LOCK (gw_store, connect_lock);
574 if (!camel_groupwise_store_connected ((CamelGroupwiseStore *)store, ex)) {
575 CAMEL_SERVICE_REC_UNLOCK (gw_store, connect_lock);
579 if (gw_store->current_folder) {
580 camel_object_unref (gw_store->current_folder);
581 gw_store->current_folder = NULL;
584 if (!E_IS_GW_CONNECTION( priv->cnc)) {
585 if (!groupwise_connect (CAMEL_SERVICE(store), ex)) {
586 camel_exception_set (ex, CAMEL_EXCEPTION_SERVICE_CANT_AUTHENTICATE, _("Authentication failed"));
587 CAMEL_SERVICE_REC_UNLOCK (gw_store, connect_lock);
592 container_id = g_strdup (g_hash_table_lookup (priv->name_hash, folder_name));
595 storage_path = g_strdup_printf("%s/folders", priv->storage_path);
596 folder_dir = e_path_to_physical (storage_path, folder_name);
597 g_free(storage_path);
598 folder = camel_gw_folder_new (store, folder_name, folder_dir, ex);
600 CAMEL_SERVICE_REC_UNLOCK (gw_store, connect_lock);
601 camel_exception_set (ex, CAMEL_EXCEPTION_SERVICE_INVALID, _("Authentication failed"));
603 g_free (container_id);
608 si = camel_store_summary_path ((CamelStoreSummary *)gw_store->summary, folder_name);
611 camel_store_summary_info_free ((CamelStoreSummary *)(gw_store)->summary, si);
614 summary = (CamelGroupwiseSummary *) folder->summary;
616 summary_count = camel_folder_summary_count (folder->summary);
617 if(!summary_count || !summary->time_string) {
618 d(g_print ("\n\n** %s **: No summary as yet : using get cursor request\n\n", folder->name);)
620 status = e_gw_connection_create_cursor (priv->cnc, container_id,
621 "peek id recipient attachments distribution subject status options priority startDate created delivered size hasAttachment",
624 if (status != E_GW_CONNECTION_STATUS_OK) {
625 CAMEL_SERVICE_REC_UNLOCK (gw_store, connect_lock);
626 g_free (container_id);
630 camel_operation_start (NULL, _("Fetching summary information for new messages in %s"), folder->name);
631 camel_folder_summary_clear (folder->summary);
634 status = e_gw_connection_read_cursor (priv->cnc, container_id,
636 CURSOR_ITEM_LIMIT, position, &list);
637 if (status != E_GW_CONNECTION_STATUS_OK) {
641 CAMEL_SERVICE_REC_UNLOCK (gw_store, connect_lock);
642 e_gw_connection_destroy_cursor (priv->cnc, container_id, cursor);
643 //camel_folder_summary_clear (folder->summary);
644 camel_folder_summary_save (folder->summary);
645 camel_exception_set (ex, CAMEL_EXCEPTION_SERVICE_INVALID, _("Authentication failed"));
646 camel_operation_end (NULL);
647 camel_object_unref (folder);
648 g_free (container_id);
652 count += g_list_length (list);
655 camel_operation_progress (NULL, (100*count)/total);
656 gw_update_summary (folder, list, ex);
660 g_list_foreach (list, (GFunc)g_object_unref, NULL);
663 position = E_GW_CURSOR_POSITION_CURRENT;
666 e_gw_connection_destroy_cursor (priv->cnc, container_id, cursor);
668 camel_operation_end (NULL);
670 if (done && all_ok) {
671 if (summary->time_string)
672 g_free (summary->time_string);
673 summary->time_string = g_strdup (e_gw_connection_get_server_time (priv->cnc));
676 camel_folder_summary_save (folder->summary);
678 gw_store->current_folder = folder;
679 camel_object_ref (folder);
681 g_free (container_id);
682 CAMEL_SERVICE_REC_UNLOCK (gw_store, connect_lock);
688 gw_store_reload_folder (CamelGroupwiseStore *gw_store, CamelFolder *folder, guint32 flags, CamelException *ex)
690 CamelGroupwiseStorePrivate *priv = gw_store->priv;
691 CamelGroupwiseSummary *summary;
693 EGwConnectionStatus status;
695 gboolean done = FALSE;
696 const char *position = E_GW_CURSOR_POSITION_END;
697 int count = 0, cursor, summary_count = 0;
698 CamelStoreInfo *si = NULL;
701 camel_exception_clear (ex);
703 CAMEL_SERVICE_REC_LOCK (gw_store, connect_lock);
705 if (!camel_groupwise_store_connected (gw_store, ex)) {
706 CAMEL_SERVICE_REC_UNLOCK (gw_store, connect_lock);
710 if (!E_IS_GW_CONNECTION( priv->cnc)) {
711 if (!groupwise_connect (CAMEL_SERVICE((CamelStore*)gw_store), ex)) {
712 camel_exception_set (ex, CAMEL_EXCEPTION_SERVICE_CANT_AUTHENTICATE, _("Authentication failed"));
713 CAMEL_SERVICE_REC_UNLOCK (gw_store, connect_lock);
718 container_id = g_strdup (g_hash_table_lookup (priv->name_hash, folder->full_name));
720 si = camel_store_summary_path ((CamelStoreSummary *)gw_store->summary, folder->name);
723 camel_store_summary_info_free ((CamelStoreSummary *)(gw_store)->summary, si);
726 summary = (CamelGroupwiseSummary *) folder->summary;
727 camel_folder_summary_clear (folder->summary);
728 camel_folder_summary_save (folder->summary);
730 summary_count = camel_folder_summary_count (folder->summary);
731 if(!summary_count || !summary->time_string) {
732 d(g_print ("\n\n** %s **: Summary missing???? Reloading summary....\n\n", folder->name);)
734 status = e_gw_connection_create_cursor (priv->cnc, container_id,
735 "peek id recipient attachments distribution subject status options priority startDate created delivered size hasAttachment",
738 if (status != E_GW_CONNECTION_STATUS_OK) {
739 CAMEL_SERVICE_REC_UNLOCK (gw_store, connect_lock);
740 g_free (container_id);
744 camel_operation_start (NULL, _("Fetching summary information for new messages in %s"), folder->name);
747 status = e_gw_connection_read_cursor (priv->cnc, container_id,
749 CURSOR_ITEM_LIMIT, position, &list);
750 if (status != E_GW_CONNECTION_STATUS_OK) {
751 CAMEL_SERVICE_REC_UNLOCK (gw_store, connect_lock);
752 e_gw_connection_destroy_cursor (priv->cnc, container_id, cursor);
753 camel_folder_summary_save (folder->summary);
754 camel_exception_set (ex, CAMEL_EXCEPTION_SERVICE_INVALID, _("Authentication failed"));
755 camel_operation_end (NULL);
756 g_free (container_id);
760 count += g_list_length (list);
763 camel_operation_progress (NULL, (100*count)/total);
764 gw_update_summary (folder, list, ex);
768 g_list_foreach (list, (GFunc)g_object_unref, NULL);
771 position = E_GW_CURSOR_POSITION_CURRENT;
774 e_gw_connection_destroy_cursor (priv->cnc, container_id, cursor);
776 camel_operation_end (NULL);
780 if (summary->time_string)
781 g_free (summary->time_string);
782 summary->time_string = g_strdup (e_gw_connection_get_server_time (priv->cnc));
785 camel_folder_summary_save (folder->summary);
787 gw_store->current_folder = folder;
789 g_free (container_id);
790 CAMEL_SERVICE_REC_UNLOCK (gw_store, connect_lock);
795 convert_to_folder_info (CamelGroupwiseStore *store, EGwContainer *container, const char *url, CamelException *ex)
797 const char *name = NULL, *id = NULL, *parent = NULL;
798 char *par_name = NULL;
800 CamelGroupwiseStoreInfo *si = NULL;
801 CamelGroupwiseStorePrivate *priv = store->priv;
802 EGwContainerType type;
804 name = e_gw_container_get_name (container);
805 id = e_gw_container_get_id (container);
806 type = e_gw_container_get_container_type (container);
808 fi = g_new0 (CamelFolderInfo, 1);
810 if (type == E_GW_CONTAINER_TYPE_INBOX)
811 fi->flags |= CAMEL_FOLDER_TYPE_INBOX;
812 if (type == E_GW_CONTAINER_TYPE_TRASH)
813 fi->flags |= CAMEL_FOLDER_TYPE_TRASH;
814 if (type == E_GW_CONTAINER_TYPE_SENT)
815 fi->flags |= CAMEL_FOLDER_TYPE_SENT;
817 if ( (type == E_GW_CONTAINER_TYPE_INBOX) ||
818 (type == E_GW_CONTAINER_TYPE_SENT) ||
819 (type == E_GW_CONTAINER_TYPE_DOCUMENTS) ||
820 (type == E_GW_CONTAINER_TYPE_QUERY) ||
821 (type == E_GW_CONTAINER_TYPE_CHECKLIST) ||
822 (type == E_GW_CONTAINER_TYPE_DRAFT) ||
823 (type == E_GW_CONTAINER_TYPE_CABINET) ||
824 (type == E_GW_CONTAINER_TYPE_JUNK) ||
825 (type == E_GW_CONTAINER_TYPE_TRASH) )
826 fi->flags |= CAMEL_FOLDER_SYSTEM;
828 parent_hash contains the "parent id <-> container id" combination. So we form
829 the path for the full name in camelfolder info by looking up the hash table until
833 parent = e_gw_container_get_parent_id (container);
834 par_name = g_hash_table_lookup (priv->id_hash, parent);
836 if (par_name != NULL) {
837 gchar *temp_parent = NULL, *temp = NULL;
838 gchar *str = g_strconcat (par_name, "/", name, NULL);
840 fi->name = g_strdup (name);
842 temp_parent = g_hash_table_lookup (priv->parent_hash, parent);
843 while (temp_parent) {
844 temp = g_hash_table_lookup (priv->id_hash, temp_parent );
848 str = g_strconcat ( temp, "/", str, NULL);
850 temp_parent = g_hash_table_lookup (priv->parent_hash, temp_parent);
853 fi->full_name = g_strdup (str);
854 fi->uri = g_strconcat (url, str, NULL);
858 fi->name = g_strdup (name);
859 fi->full_name = g_strdup (name);
860 fi->uri = g_strconcat (url, "", name, NULL);
863 si = camel_groupwise_store_summary_add_from_full (store->summary, fi->full_name, '/');
865 camel_folder_info_free (fi);
869 /*name_hash returns the container id given the name */
870 g_hash_table_insert (priv->name_hash, g_strdup(fi->full_name), g_strdup(id));
872 if (e_gw_container_get_is_shared_to_me (container))
873 fi->flags |= CAMEL_FOLDER_SHARED_TO_ME;
875 if (e_gw_container_get_is_shared_by_me (container))
876 fi->flags |= CAMEL_FOLDER_SHARED_BY_ME;
878 fi->total = e_gw_container_get_total_count (container);
879 fi->unread = e_gw_container_get_unread_count (container);
881 si->info.total = fi->total;
882 si->info.unread = fi->unread;
883 si->info.flags = fi->flags;
885 if (store->current_folder
886 && !strcmp (store->current_folder->full_name, fi->full_name)
887 && type != E_GW_CONTAINER_TYPE_INBOX) {
888 CAMEL_FOLDER_CLASS (CAMEL_OBJECT_GET_CLASS (store->current_folder))->refresh_info(store->current_folder, ex);
894 get_folders_free (void *k, void *v, void *d)
896 CamelFolderInfo *fi = v;
897 camel_folder_info_free (fi);
901 groupwise_folders_sync (CamelGroupwiseStore *store, CamelException *ex)
903 CamelGroupwiseStorePrivate *priv = store->priv;
905 GList *folder_list = NULL, *temp_list = NULL, *list = NULL;
906 char *url, *temp_url;
907 CamelFolderInfo *info = NULL, *hfi = NULL;
909 CamelStoreInfo *si = NULL;
912 if (!priv->cnc && ((CamelOfflineStore *) store)->state == CAMEL_OFFLINE_STORE_NETWORK_AVAIL) {
913 if (((CamelService *)store)->status == CAMEL_SERVICE_DISCONNECTED){
914 ((CamelService *)store)->status = CAMEL_SERVICE_CONNECTING;
915 groupwise_connect ((CamelService *)store, ex);
919 status = e_gw_connection_get_container_list (priv->cnc, "folders", &folder_list);
920 if (status != E_GW_CONNECTION_STATUS_OK) {
921 g_warning ("Could not get folder list..\n");
925 temp_list = folder_list;
928 url = camel_url_to_string (CAMEL_SERVICE(store)->url,
929 (CAMEL_URL_HIDE_PASSWORD|
930 CAMEL_URL_HIDE_PARAMS|
931 CAMEL_URL_HIDE_AUTH) );
933 if ( url[strlen(url) - 1] != '/') {
934 temp_url = g_strconcat (url, "/", NULL);
935 g_free ((char *)url);
939 /*populate the hash table for finding the mapping from container id <-> folder name*/
940 for (;temp_list != NULL ; temp_list = g_list_next (temp_list) ) {
941 const char *name, *id, *parent;
942 name = e_gw_container_get_name (E_GW_CONTAINER (temp_list->data));
943 id = e_gw_container_get_id(E_GW_CONTAINER(temp_list->data));
944 parent = e_gw_container_get_parent_id (E_GW_CONTAINER(temp_list->data));
946 if (e_gw_container_is_root (E_GW_CONTAINER(temp_list->data))) {
947 store->root_container = g_strdup (id);
951 /*id_hash returns the name for a given container id*/
952 g_hash_table_insert (priv->id_hash, g_strdup(id), g_strdup(name));
953 /*parent_hash returns the parent container id, given an id*/
954 g_hash_table_insert (priv->parent_hash, g_strdup(id), g_strdup(parent));
957 present = g_hash_table_new (g_str_hash, g_str_equal);
959 for (;folder_list != NULL; folder_list = g_list_next (folder_list)) {
960 EGwContainerType type;
961 EGwContainer *container = E_GW_CONTAINER (folder_list->data);
963 type = e_gw_container_get_container_type (container);
965 if (e_gw_container_is_root(container))
967 if ( (type == E_GW_CONTAINER_TYPE_CALENDAR) || (type == E_GW_CONTAINER_TYPE_CONTACTS) )
970 info = convert_to_folder_info (store, E_GW_CONTAINER (folder_list->data), (const char *)url, ex);
972 hfi = g_hash_table_lookup (present, info->full_name);
974 g_hash_table_insert (present, info->full_name, info);
976 camel_folder_info_free (info);
982 g_free ((char *)url);
983 e_gw_connection_free_container_list (list);
984 count = camel_store_summary_count ((CamelStoreSummary *)store->summary);
986 count = camel_store_summary_count ((CamelStoreSummary *)store->summary);
987 for (i=0;i<count;i++) {
988 si = camel_store_summary_index ((CamelStoreSummary *)store->summary, i);
992 info = g_hash_table_lookup (present, camel_store_info_path (store->summary, si));
994 camel_store_summary_touch ((CamelStoreSummary *)store->summary);
996 camel_store_summary_remove ((CamelStoreSummary *)store->summary, si);
1000 camel_store_summary_info_free ((CamelStoreSummary *)store->summary, si);
1003 g_hash_table_foreach (present, get_folders_free, NULL);
1004 g_hash_table_destroy (present);
1007 static CamelFolderInfo *
1008 groupwise_get_folder_info_offline (CamelStore *store, const char *top,
1009 guint32 flags, CamelException *ex)
1011 CamelGroupwiseStore *groupwise_store = CAMEL_GROUPWISE_STORE (store);
1012 CamelFolderInfo *fi;
1017 folders = g_ptr_array_new ();
1022 /* get starting point */
1024 name = g_strdup("");
1026 name = camel_groupwise_store_summary_full_from_path(groupwise_store->summary, top);
1028 name = camel_groupwise_store_summary_path_to_full(groupwise_store->summary, top, '/');
1031 path = gw_concat (name, "*");
1033 for (i=0;i<camel_store_summary_count((CamelStoreSummary *)groupwise_store->summary);i++) {
1034 CamelStoreInfo *si = camel_store_summary_index((CamelStoreSummary *)groupwise_store->summary, i);
1039 if ( !strcmp(name, camel_groupwise_store_info_full_name (groupwise_store->summary, si))
1040 || match_path (path, camel_groupwise_store_info_full_name (groupwise_store->summary, si))) {
1041 fi = groupwise_build_folder_info(groupwise_store, NULL, camel_store_info_path((CamelStoreSummary *)groupwise_store->summary, si));
1042 fi->unread = si->unread;
1043 fi->total = si->total;
1044 fi->flags = si->flags;
1045 g_ptr_array_add (folders, fi);
1047 camel_store_summary_info_free((CamelStoreSummary *)groupwise_store->summary, si);
1052 fi = camel_folder_info_build (folders, top, '/', TRUE);
1053 g_ptr_array_free (folders, TRUE);
1057 /*** Thread stuff for refreshing folder tree begins ***/
1058 struct _store_refresh_msg {
1059 CamelSessionThreadMsg msg;
1067 store_refresh_refresh (CamelSession *session, CamelSessionThreadMsg *msg)
1069 struct _store_refresh_msg *m = (struct _store_refresh_msg *)msg;
1070 CamelGroupwiseStore *groupwise_store = (CamelGroupwiseStore *)m->store;
1072 CAMEL_SERVICE_REC_LOCK (m->store, connect_lock);
1073 if (!camel_groupwise_store_connected ((CamelGroupwiseStore *)m->store, &m->ex))
1075 /*Get the folder list and save it here*/
1076 groupwise_folders_sync (groupwise_store, &m->ex);
1077 if (camel_exception_is_set (&m->ex))
1079 camel_store_summary_save ((CamelStoreSummary *)groupwise_store->summary);
1081 CAMEL_SERVICE_REC_UNLOCK (m->store, connect_lock);
1085 store_refresh_free(CamelSession *session, CamelSessionThreadMsg *msg)
1087 struct _store_refresh_msg *m = (struct _store_refresh_msg *)msg;
1089 camel_object_unref (m->store);
1090 camel_exception_clear (&m->ex);
1093 static CamelSessionThreadOps store_refresh_ops = {
1094 store_refresh_refresh,
1099 /*** Thread stuff ends ***/
1101 static CamelFolderInfo *
1102 groupwise_get_folder_info (CamelStore *store, const char *top, guint32 flags, CamelException *ex)
1104 CamelGroupwiseStore *groupwise_store = CAMEL_GROUPWISE_STORE (store);
1105 CamelGroupwiseStorePrivate *priv = groupwise_store->priv;
1106 CamelFolderInfo *info = NULL;
1107 char *top_folder = NULL;
1110 top_folder = g_hash_table_lookup (priv->name_hash, top);
1111 /* 'top' is a valid path, but doesnt have a container id
1113 /* if (!top_folder) {
1114 camel_exception_set (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE,
1115 _("You must be working online to complete this operation"));
1120 if (top && groupwise_is_system_folder (top))
1121 return groupwise_build_folder_info (groupwise_store, NULL, top );
1124 * Thanks to Michael, for his cached folders implementation in IMAP
1125 * is used as is here.
1127 if (camel_store_summary_count ((CamelStoreSummary *)groupwise_store->summary) == 0) {
1128 CAMEL_SERVICE_REC_LOCK (store, connect_lock);
1129 if (groupwise_store->list_loaded == 3) {
1130 groupwise_folders_sync (groupwise_store, ex);
1131 groupwise_store->list_loaded -= 1;
1133 if (camel_exception_is_set (ex)) {
1134 camel_store_summary_save ((CamelStoreSummary *) groupwise_store->summary);
1135 CAMEL_SERVICE_REC_UNLOCK (store, connect_lock);
1138 CAMEL_SERVICE_REC_UNLOCK (store, connect_lock);
1139 camel_store_summary_save ((CamelStoreSummary *)groupwise_store->summary);
1143 if ((camel_store_summary_count((CamelStoreSummary *)groupwise_store->summary) > 0) && (groupwise_store->list_loaded > 1)) {
1145 groupwise_store->list_loaded -= 1;
1149 CAMEL_SERVICE_REC_LOCK (store, connect_lock);
1150 if ((groupwise_store->list_loaded == 1) && check_for_connection((CamelService *)store, ex)) {
1152 if (groupwise_connect ((CamelService *)store, ex)) {
1153 g_warning ("Could connect!!!\n");
1155 g_warning ("Could not connect..failure connecting\n");
1157 if (camel_groupwise_store_connected ((CamelGroupwiseStore *)store, ex)) {
1158 if (groupwise_store->current_folder)
1159 CAMEL_FOLDER_CLASS (CAMEL_OBJECT_GET_CLASS (groupwise_store->current_folder))->sync(groupwise_store->current_folder, FALSE, ex);
1160 groupwise_folders_sync (groupwise_store, ex);
1161 if (camel_exception_is_set (ex)) {
1162 CAMEL_SERVICE_REC_UNLOCK (store, connect_lock);
1165 camel_store_summary_touch ((CamelStoreSummary *)groupwise_store->summary);
1166 camel_store_summary_save ((CamelStoreSummary *)groupwise_store->summary);
1169 CAMEL_SERVICE_REC_UNLOCK (store, connect_lock);
1171 /*camel_exception_clear (ex);*/
1173 info = groupwise_get_folder_info_offline (store, top, flags, ex);
1177 /* To create a junk mail folder in case we want it and it isn't there*/
1179 create_junk_folder (CamelStore *store)
1181 CamelGroupwiseStore *groupwise_store = CAMEL_GROUPWISE_STORE (store);
1182 CamelGroupwiseStorePrivate *priv = groupwise_store->priv;
1183 CamelFolderInfo *root = NULL;
1184 char *parent_name, *folder_name, *child_container_id, *parent_id;
1188 folder_name = "Junk Mail";
1190 /* TODO: check for offlining*/
1192 CAMEL_SERVICE_REC_LOCK (store, connect_lock);
1193 status = e_gw_connection_modify_junk_settings (priv->cnc, JUNK_ENABLE, 0, 0, JUNK_PERSISTENCE);
1194 if (status == E_GW_CONNECTION_STATUS_OK) {
1195 root = groupwise_build_folder_info(groupwise_store, parent_name, folder_name);
1196 camel_store_summary_save((CamelStoreSummary *)groupwise_store->summary);
1198 child_container_id = e_gw_connection_get_container_id (priv->cnc, "Junk Mail");
1199 if (!child_container_id)
1200 g_warning("failed to retrieve id for junk folder");
1202 g_hash_table_insert (priv->id_hash, g_strdup(child_container_id), g_strdup(folder_name));
1203 g_hash_table_insert (priv->name_hash, g_strdup(folder_name), g_strdup(child_container_id));
1204 g_hash_table_insert (priv->parent_hash, g_strdup(child_container_id), g_strdup(parent_id));
1205 camel_object_trigger_event (CAMEL_OBJECT (store), "folder_created", root);
1207 CAMEL_SERVICE_REC_UNLOCK (store, connect_lock);
1212 static CamelFolderInfo*
1213 groupwise_create_folder(CamelStore *store,
1214 const char *parent_name,
1215 const char *folder_name,
1218 CamelGroupwiseStore *groupwise_store = CAMEL_GROUPWISE_STORE (store);
1219 CamelGroupwiseStorePrivate *priv = groupwise_store->priv;
1220 CamelFolderInfo *root = NULL;
1221 char *parent_id , *child_container_id;
1224 if (((CamelOfflineStore *) store)->state == CAMEL_OFFLINE_STORE_NETWORK_UNAVAIL) {
1225 camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, _("Cannot create GroupWise folders in offline mode."));
1229 if(parent_name == NULL) {
1231 if (groupwise_is_system_folder (folder_name)) {
1232 camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, NULL);
1237 if (parent_name && (strlen(parent_name) > 0) ) {
1238 if (strcmp (parent_name, "Cabinet") && groupwise_is_system_folder (parent_name)) {
1239 camel_exception_set (ex, CAMEL_EXCEPTION_FOLDER_INVALID_STATE, _("The parent folder is not allowed to contain subfolders"));
1242 parent_id = g_hash_table_lookup (priv->name_hash, parent_name);
1246 if (!E_IS_GW_CONNECTION( priv->cnc)) {
1247 if (!groupwise_connect (CAMEL_SERVICE(store), ex)) {
1248 camel_exception_set (ex, CAMEL_EXCEPTION_SERVICE_CANT_AUTHENTICATE, _("Authentication failed"));
1252 CAMEL_SERVICE_REC_LOCK (store, connect_lock);
1253 status = e_gw_connection_create_folder(priv->cnc,parent_id,folder_name, &child_container_id);
1254 if (status == E_GW_CONNECTION_STATUS_OK) {
1255 root = groupwise_build_folder_info(groupwise_store, parent_name,folder_name);
1256 camel_store_summary_save((CamelStoreSummary *)groupwise_store->summary);
1258 g_hash_table_insert (priv->id_hash, g_strdup(child_container_id), g_strdup(folder_name));
1259 g_hash_table_insert (priv->name_hash, g_strdup(root->full_name), g_strdup(child_container_id));
1260 g_hash_table_insert (priv->parent_hash, g_strdup(child_container_id), g_strdup(parent_id));
1262 camel_object_trigger_event (CAMEL_OBJECT (store), "folder_created", root);
1264 CAMEL_SERVICE_REC_UNLOCK (store, connect_lock);
1269 groupwise_delete_folder(CamelStore *store,
1270 const char *folder_name,
1273 CamelGroupwiseStore *groupwise_store = CAMEL_GROUPWISE_STORE (store);
1274 CamelGroupwiseStorePrivate *priv = groupwise_store->priv;
1275 EGwConnectionStatus status;
1276 const char * container;
1278 CAMEL_SERVICE_REC_LOCK (store, connect_lock);
1280 if (!camel_groupwise_store_connected ((CamelGroupwiseStore *)store, ex)) {
1281 CAMEL_SERVICE_REC_UNLOCK (store, connect_lock);
1285 container = g_hash_table_lookup (priv->name_hash, folder_name);
1287 status = e_gw_connection_remove_item (priv->cnc, container, container);
1289 if (status == E_GW_CONNECTION_STATUS_OK) {
1290 if (groupwise_store->current_folder)
1291 camel_object_unref (groupwise_store->current_folder);
1293 groupwise_forget_folder(groupwise_store,folder_name,ex);
1295 g_hash_table_remove (priv->id_hash, container);
1296 g_hash_table_remove (priv->name_hash, folder_name);
1298 g_hash_table_remove (priv->parent_hash, container);
1300 CAMEL_SERVICE_REC_UNLOCK (store, connect_lock);
1304 groupwise_rename_folder(CamelStore *store,
1305 const char *old_name,
1306 const char *new_name,
1309 CamelGroupwiseStore *groupwise_store = CAMEL_GROUPWISE_STORE (store);
1310 CamelGroupwiseStorePrivate *priv = groupwise_store->priv;
1311 char *oldpath, *newpath, *storepath;
1312 const char *container_id;
1313 char *temp_new = NULL;
1315 if (groupwise_is_system_folder (old_name)) {
1316 camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, _("Cannot rename Groupwise folder `%s' to `%s'"),
1317 old_name, new_name);
1321 CAMEL_SERVICE_REC_LOCK (groupwise_store, connect_lock);
1323 if (!camel_groupwise_store_connected ((CamelGroupwiseStore *)store, ex)) {
1324 CAMEL_SERVICE_REC_UNLOCK (groupwise_store, connect_lock);
1328 container_id = camel_groupwise_store_container_id_lookup (groupwise_store, old_name);
1329 temp_new = strrchr (new_name, '/');
1333 temp_new = (char *)new_name;
1335 if (!container_id || e_gw_connection_rename_folder (priv->cnc, container_id , temp_new) != E_GW_CONNECTION_STATUS_OK)
1337 camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, _("Cannot rename Groupwise folder `%s' to `%s'"),
1338 old_name, new_name);
1339 CAMEL_SERVICE_REC_UNLOCK (groupwise_store, connect_lock);
1343 g_hash_table_replace (priv->id_hash, g_strdup(container_id), g_strdup(temp_new));
1345 g_hash_table_insert (priv->name_hash, g_strdup(new_name), g_strdup(container_id));
1346 g_hash_table_remove (priv->name_hash, old_name);
1347 /*FIXME:Update all the id in the parent_hash*/
1349 storepath = g_strdup_printf ("%s/folders", priv->storage_path);
1350 oldpath = e_path_to_physical (storepath, old_name);
1351 newpath = e_path_to_physical (storepath, new_name);
1354 /*XXX: make sure the summary is also renamed*/
1355 if (g_rename (oldpath, newpath) == -1) {
1356 g_warning ("Could not rename message cache '%s' to '%s': %s: cache reset",
1357 oldpath, newpath, strerror (errno));
1362 CAMEL_SERVICE_REC_UNLOCK (groupwise_store, connect_lock);
1366 groupwise_get_name(CamelService *service, gboolean brief)
1369 return g_strdup_printf(_("GroupWise server %s"), service->url->host);
1371 return g_strdup_printf(_("GroupWise service for %s on %s"),
1372 service->url->user, service->url->host);
1376 camel_groupwise_store_container_id_lookup (CamelGroupwiseStore *gw_store, const char *folder_name)
1378 CamelGroupwiseStorePrivate *priv = gw_store->priv;
1380 return g_hash_table_lookup (priv->name_hash, folder_name);
1384 camel_groupwise_store_folder_lookup (CamelGroupwiseStore *gw_store, const char *container_id)
1386 CamelGroupwiseStorePrivate *priv = gw_store->priv;
1388 return g_hash_table_lookup (priv->id_hash, container_id);
1393 cnc_lookup (CamelGroupwiseStorePrivate *priv)
1399 storage_path_lookup (CamelGroupwiseStorePrivate *priv)
1401 return priv->storage_path;
1405 groupwise_base_url_lookup (CamelGroupwiseStorePrivate *priv)
1407 return priv->base_url;
1410 static CamelFolder *
1411 groupwise_get_trash (CamelStore *store, CamelException *ex)
1413 CamelFolder *folder = camel_store_get_folder(store, "Trash", 0, ex);
1415 char *state = g_build_filename(((CamelGroupwiseStore *)store)->priv->storage_path, "folders", "Trash", "cmeta", NULL);
1417 camel_object_set(folder, NULL, CAMEL_OBJECT_STATE_FILE, state, NULL);
1419 camel_object_state_read(folder);
1427 * Function to check if we are both connected and are _actually_
1428 * online. Based on an equivalient function in IMAP
1431 camel_groupwise_store_connected (CamelGroupwiseStore *store, CamelException *ex)
1433 if (((CamelOfflineStore *) store)->state == CAMEL_OFFLINE_STORE_NETWORK_AVAIL
1434 && camel_service_connect ((CamelService *)store, ex)) {
1437 /*Not online, so return FALSE*/
1442 match_path(const char *path, const char *name)
1452 } else if (p == '%') {
1458 } else if (p == '*') {
1464 return n == 0 && (p == '%' || p == 0);
1467 /* GObject Init and finalise methods */
1469 camel_groupwise_store_class_init (CamelGroupwiseStoreClass *camel_groupwise_store_class)
1471 CamelServiceClass *camel_service_class =
1472 CAMEL_SERVICE_CLASS (camel_groupwise_store_class);
1473 CamelStoreClass *camel_store_class =
1474 CAMEL_STORE_CLASS (camel_groupwise_store_class);
1476 parent_class = CAMEL_OFFLINE_STORE_CLASS (camel_type_get_global_classfuncs (camel_offline_store_get_type ()));
1478 camel_service_class->construct = groupwise_store_construct;
1479 camel_service_class->query_auth_types = groupwise_store_query_auth_types;
1480 camel_service_class->get_name = groupwise_get_name;
1481 camel_service_class->connect = groupwise_connect;
1482 camel_service_class->disconnect = groupwise_disconnect;
1484 camel_store_class->hash_folder_name = groupwise_hash_folder_name;
1485 camel_store_class->compare_folder_name = groupwise_compare_folder_name;
1487 camel_store_class->get_folder = groupwise_get_folder;
1488 camel_store_class->create_folder = groupwise_create_folder;
1489 camel_store_class->delete_folder = groupwise_delete_folder;
1490 camel_store_class->rename_folder = groupwise_rename_folder;
1491 camel_store_class->get_folder_info = groupwise_get_folder_info;
1492 camel_store_class->free_folder_info = camel_store_free_folder_info_full;
1493 camel_store_class->get_trash = groupwise_get_trash;
1497 /*This frees the private structure*/
1499 camel_groupwise_store_finalize (CamelObject *object)
1501 CamelGroupwiseStore *groupwise_store = CAMEL_GROUPWISE_STORE (object);
1502 CamelGroupwiseStorePrivate *priv = groupwise_store->priv;
1504 g_print ("camel_groupwise_store_finalize\n");
1505 if (groupwise_store->summary) {
1506 camel_store_summary_save ((CamelStoreSummary *)groupwise_store->summary);
1507 camel_object_unref (groupwise_store->summary);
1512 g_free (priv->user);
1515 if (priv->server_name) {
1516 g_free (priv->server_name);
1517 priv->server_name = NULL;
1520 g_free (priv->port);
1523 if (priv->use_ssl) {
1524 g_free (priv->use_ssl);
1525 priv->use_ssl = NULL;
1527 if (priv->base_url) {
1528 g_free (priv->base_url);
1529 priv->base_url = NULL;
1532 if (E_IS_GW_CONNECTION (priv->cnc)) {
1533 g_object_unref (priv->cnc);
1537 if (priv->storage_path)
1538 g_free(priv->storage_path);
1540 if(groupwise_store->root_container)
1541 g_free (groupwise_store->root_container);
1544 g_hash_table_destroy (priv->id_hash);
1546 if (priv->name_hash)
1547 g_hash_table_destroy (priv->name_hash);
1549 if (priv->parent_hash)
1550 g_hash_table_destroy (priv->parent_hash);
1552 g_free (groupwise_store->priv);
1553 groupwise_store->priv = NULL;
1559 camel_groupwise_store_init (gpointer object, gpointer klass)
1561 CamelGroupwiseStore *groupwise_store = CAMEL_GROUPWISE_STORE (object);
1562 CamelGroupwiseStorePrivate *priv = g_new0 (CamelGroupwiseStorePrivate, 1);
1564 d("in groupwise store init\n");
1565 priv->server_name = NULL;
1567 priv->use_ssl = NULL;
1570 groupwise_store->priv = priv;
1575 camel_groupwise_store_get_type (void)
1577 static CamelType camel_groupwise_store_type = CAMEL_INVALID_TYPE;
1579 if (camel_groupwise_store_type == CAMEL_INVALID_TYPE) {
1580 camel_groupwise_store_type =
1581 camel_type_register (camel_offline_store_get_type (),
1582 "CamelGroupwiseStore",
1583 sizeof (CamelGroupwiseStore),
1584 sizeof (CamelGroupwiseStoreClass),
1585 (CamelObjectClassInitFunc) camel_groupwise_store_class_init,
1587 (CamelObjectInitFunc) camel_groupwise_store_init,
1588 (CamelObjectFinalizeFunc) camel_groupwise_store_finalize);
1591 return camel_groupwise_store_type;