Fix FSF address (Tobias Mueller, #470445)
[platform/upstream/evolution-data-server.git] / servers / exchange / storage / exchange-esource.c
1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2
3 /* Copyright (C) 2001-2004 Novell, Inc.
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of version 2 of the GNU Lesser General Public
7  * License as published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this program; if not, write to the
16  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17  * Boston, MA 02110-1301, USA.
18  */
19
20 #ifdef HAVE_CONFIG_H
21 #include <config.h>
22 #endif
23
24 #include "exchange-esource.h"
25
26 #include <libedataserver/e-source.h>
27 #include <libedataserver/e-source-list.h>
28 #include <libedataserver/e-source-group.h>
29
30 #include <stdlib.h>
31 #include <string.h>
32
33 static gboolean is_offline (void);
34
35 void
36 add_folder_esource (ExchangeAccount *account, 
37                     FolderType folder_type, 
38                     const char *folder_name, 
39                     const char *physical_uri)
40 {
41         ESource *source = NULL;
42         ESourceGroup *source_group = NULL;
43         char *relative_uri = NULL;
44         GSList *ids;
45         GConfClient *client;
46         gboolean is_contacts_folder = TRUE, group_new = FALSE, source_new = FALSE;
47         const char *offline = NULL;
48         char *username, *useremail, *authtype = NULL;
49         int mode;
50         ESourceList *source_list = NULL;
51         gboolean offline_flag, update_selection = TRUE, foriegn_folder;
52
53         client = gconf_client_get_default ();
54
55         /* decode the flag */
56         foriegn_folder = folder_type & FORIEGN_FOLDER_FLAG;
57
58         /* Unset the flag */
59         folder_type = folder_type & ~FORIEGN_FOLDER_FLAG;
60         
61         if (folder_type == EXCHANGE_CONTACTS_FOLDER) {
62                 source_list = e_source_list_new_for_gconf ( client, 
63                                                         CONF_KEY_CONTACTS);
64                 /* Modify the URI handling of Contacts to the same way as calendar and tasks */
65                 if (!g_str_has_prefix (physical_uri, "gal://")) {
66                         relative_uri = g_strdup (physical_uri + strlen (EXCHANGE_URI_PREFIX));
67                 }
68         }
69         else if (folder_type == EXCHANGE_CALENDAR_FOLDER) {
70                 source_list = e_source_list_new_for_gconf ( client, 
71                                                         CONF_KEY_CAL);
72                 relative_uri = g_strdup (physical_uri + strlen (EXCHANGE_URI_PREFIX));
73                 is_contacts_folder = FALSE;
74         }
75         else if (folder_type == EXCHANGE_TASKS_FOLDER) {
76                 source_list = e_source_list_new_for_gconf ( client,
77                                                         CONF_KEY_TASKS);
78                 relative_uri = g_strdup (physical_uri + strlen (EXCHANGE_URI_PREFIX));
79                 is_contacts_folder = FALSE;
80         }
81
82         exchange_account_is_offline_sync_set (account, &mode);
83         username = exchange_account_get_username (account);
84         useremail = exchange_account_get_email_id (account);
85         authtype = exchange_account_get_authtype (account);
86
87         if ((source_group = e_source_list_peek_group_by_name (source_list, 
88                                         account->account_name)) == NULL) {
89                 source_group = e_source_group_new (account->account_name, 
90                                                    EXCHANGE_URI_PREFIX);
91                 if (!e_source_list_add_group (source_list, source_group, -1)) {
92                         g_object_unref (source_list);
93                         g_object_unref (source_group);
94                         g_object_unref (client);
95                         g_free (relative_uri);
96                         return;
97                 }
98                 if (is_contacts_folder && g_str_has_prefix (physical_uri, "gal://")) {
99                         source = e_source_new_with_absolute_uri (folder_name,
100                                                                  physical_uri);
101                         e_source_set_property (source, "completion", "true");
102                 }
103                 else {
104                         source = e_source_new (folder_name, relative_uri);
105                 }
106
107                 if (mode == OFFLINE_MODE) {
108                         /* If account is marked for offline sync during account
109                          * creation, mark all the folders for offline sync 
110                          */
111                         e_source_set_property (source, "offline_sync", "1");
112                 }
113                 
114                 if (foriegn_folder && (folder_type != EXCHANGE_CONTACTS_FOLDER)) {
115                         e_source_set_property (source, "alarm", "never");
116                         e_source_set_property (source, "subscriber", useremail);
117                 }
118
119                 e_source_set_property (source, "username", username);
120                 e_source_set_property (source, "auth-domain", "Exchange");
121                 if (authtype)
122                         e_source_set_property (source, "auth-type", authtype);
123                 if (is_contacts_folder)
124                         e_source_set_property (source, "auth", "plain/password");
125                 else
126                         e_source_set_property (source, "auth", "1");
127                 e_source_group_add_source (source_group, source, -1);
128                 e_source_list_sync (source_list, NULL);
129                 group_new = source_new = TRUE;
130         }
131         else {
132                 /* source group already exists*/
133                 if((source = e_source_group_peek_source_by_name (source_group, 
134                                                         folder_name)) == NULL) {
135                         printf("old group, new source\n");
136                         if (is_contacts_folder && g_str_has_prefix (physical_uri, "gal://")) {
137                                 source = e_source_new_with_absolute_uri (
138                                                 folder_name, physical_uri);
139                                 e_source_set_property (source, "completion", "true");
140                         }
141                         else {
142                                 source = e_source_new (folder_name, relative_uri);
143                         }
144
145                         if (mode == OFFLINE_MODE)
146                                 e_source_set_property (source, "offline_sync", "1");
147
148                         e_source_set_property (source, "username", username);
149                         e_source_set_property (source, "auth-domain", "Exchange");
150                         if (authtype)
151                                 e_source_set_property (source, "auth-type", authtype);
152                         if (is_contacts_folder)
153                                 e_source_set_property (source, "auth", "plain/password");
154                         else
155                                 e_source_set_property (source, "auth", "1");
156
157                         if (foriegn_folder && (folder_type != EXCHANGE_CONTACTS_FOLDER)) {
158                                 e_source_set_property (source, "alarm", "never");
159                                 e_source_set_property (source, "subscriber", useremail);
160                         }
161
162                         e_source_group_add_source (source_group, source, -1);
163                         source_new = TRUE;
164                         e_source_list_sync (source_list, NULL);
165                 } else {
166                         update_selection = FALSE;
167                         /* source group and source both already exist */
168                         offline = e_source_get_property (source, "offline_sync");
169                         if (!offline) {
170                                 /* Folder doesn't have any offline property set */
171                                 if (mode == OFFLINE_MODE) {
172                                         e_source_set_property (source, "offline_sync", "1");
173                                         e_source_list_sync (source_list, NULL);
174                                 }
175                         }
176                 }
177         }
178
179         offline_flag = is_offline ();
180         if (source && !is_contacts_folder && update_selection) {
181
182                 /* Select the folder created */
183                 if (folder_type == EXCHANGE_CALENDAR_FOLDER && !offline_flag) {
184                         ids = gconf_client_get_list (client,
185                                              CONF_KEY_SELECTED_CAL_SOURCES, 
186                                              GCONF_VALUE_STRING, NULL);
187                         ids = g_slist_append (ids, 
188                                         g_strdup (e_source_peek_uid (source)));
189                         gconf_client_set_list (client,
190                                        CONF_KEY_SELECTED_CAL_SOURCES, 
191                                        GCONF_VALUE_STRING, ids, NULL);
192                         g_slist_foreach (ids, (GFunc) g_free, NULL);
193                         g_slist_free (ids);
194                 }
195                 else if (folder_type == EXCHANGE_TASKS_FOLDER && !offline_flag) {
196                         ids = gconf_client_get_list (client, 
197                                              CONF_KEY_SELECTED_TASKS_SOURCES, 
198                                              GCONF_VALUE_STRING, NULL);
199
200                         ids = g_slist_append (ids, 
201                                         g_strdup (e_source_peek_uid (source)));
202                         gconf_client_set_list (client,  
203                                        CONF_KEY_SELECTED_TASKS_SOURCES, 
204                                        GCONF_VALUE_STRING, ids, NULL);
205                         g_slist_foreach (ids, (GFunc) g_free, NULL);
206                         g_slist_free (ids);
207                 }
208         }
209
210         g_free (relative_uri);
211         g_free (authtype);
212
213         if (source_new) 
214                 g_object_unref (source);
215         if (group_new)
216                 g_object_unref (source_group);
217         g_object_unref (source_list);
218         g_object_unref (client);
219 }
220
221 void 
222 remove_folder_esource (ExchangeAccount *account, 
223                        FolderType folder_type, 
224                        const char *physical_uri)
225 {
226         ESourceGroup *group;
227         ESource *source;
228         GSList *groups;
229         GSList *sources;
230         gboolean found_group, is_contacts_folder = TRUE;
231         char *read_uri = NULL;
232         const char *source_uid;
233         GSList *ids, *temp_ids, *node_to_be_deleted;
234         GConfClient *client;
235         ESourceList *source_list = NULL;
236
237         client = gconf_client_get_default ();
238
239         /* Remove ESource for a given folder */
240         if (folder_type == EXCHANGE_CONTACTS_FOLDER) {
241                 source_list = e_source_list_new_for_gconf ( client, 
242                                                         CONF_KEY_CONTACTS);
243         }
244         else if (folder_type == EXCHANGE_CALENDAR_FOLDER) {
245                 source_list = e_source_list_new_for_gconf ( client, 
246                                                         CONF_KEY_CAL);
247                 is_contacts_folder = FALSE;
248         }
249         else if (folder_type == EXCHANGE_TASKS_FOLDER) {
250                 source_list = e_source_list_new_for_gconf ( client,
251                                                         CONF_KEY_TASKS);
252                 is_contacts_folder = FALSE;
253         }
254         
255         groups = e_source_list_peek_groups (source_list);
256         found_group = FALSE;
257
258         for ( ; groups != NULL && !found_group; groups = g_slist_next (groups)) {
259                 group = E_SOURCE_GROUP (groups->data);
260
261                 if (strcmp (e_source_group_peek_name (group), account->account_name) == 0
262                     &&
263                    strcmp (e_source_group_peek_base_uri (group), EXCHANGE_URI_PREFIX) == 0) {
264
265                         sources = e_source_group_peek_sources (group);
266
267                         for( ; sources != NULL; sources = g_slist_next (sources)) {
268                                 
269                                 source = E_SOURCE (sources->data);
270                                 read_uri = e_source_get_uri (source);
271
272                                 if (strcmp (read_uri, physical_uri) == 0) { 
273
274                                         source_uid = e_source_peek_uid (source);
275                                         /* Folder Deleted - Remove only the source */
276                                         /*
277                                         e_source_group_remove_source_by_uid (
278                                                                 group, 
279                                                                 source_uid);
280                                         */
281                                         e_source_group_remove_source (
282                                                                 group,
283                                                                 source);
284                                         e_source_list_sync (source_list, NULL);
285                                         if (!is_contacts_folder) {
286                                                 /* Remove from the selected folders */
287                                                 if (folder_type == EXCHANGE_CALENDAR_FOLDER) {
288                                                         ids = gconf_client_get_list (
289                                                                         client, 
290                                                                         CONF_KEY_SELECTED_CAL_SOURCES, 
291                                                                         GCONF_VALUE_STRING, NULL);
292                                                         if (ids) {
293                                                                 node_to_be_deleted = g_slist_find_custom (ids, 
294                                                                                         source_uid, 
295                                                                                         (GCompareFunc) strcmp);
296                                                                 if (node_to_be_deleted) {
297                                                                         g_free (node_to_be_deleted->data);
298                                                                         ids = g_slist_delete_link (ids, 
299                                                                                         node_to_be_deleted);
300                                                                 }
301                                                         }
302                                                         temp_ids  = ids;
303                                                         for (; temp_ids != NULL; temp_ids = g_slist_next (temp_ids))
304                                                         g_free (temp_ids->data);
305                                                         g_slist_free (ids);
306                                                 }
307                                                 else if (folder_type == EXCHANGE_TASKS_FOLDER) {
308                                                         ids = gconf_client_get_list (client, 
309                                                                         CONF_KEY_SELECTED_TASKS_SOURCES, 
310                                                                         GCONF_VALUE_STRING, NULL);
311                                                         if (ids) {
312                                                                 node_to_be_deleted = g_slist_find_custom (ids, 
313                                                                                         source_uid, 
314                                                                                         (GCompareFunc) strcmp);
315                                                                 if (node_to_be_deleted) {
316                                                                         g_free (node_to_be_deleted->data);
317                                                                         ids = g_slist_delete_link (ids, 
318                                                                                         node_to_be_deleted);
319                                                                 }
320                                                         }
321                                                         temp_ids  = ids;
322                                                         for (; temp_ids != NULL; temp_ids = g_slist_next (temp_ids))
323                                                                 g_free (temp_ids->data);
324                                                         g_slist_free (ids);
325                                                 }
326                                         }
327                                         found_group = TRUE;
328                                         break;
329                                 }
330                                 g_free (read_uri);
331                         }
332                 }
333         }
334         g_object_unref (source_list);
335         g_object_unref (client);
336 }
337
338 static gboolean 
339 is_offline (void) 
340 {
341         GConfClient *client;
342         GConfValue *value;
343         gboolean offline = FALSE;
344
345         client = gconf_client_get_default ();
346         value = gconf_client_get (client,
347                                         "/apps/evolution/shell/start_offline", NULL);
348         if (value)
349                 offline = gconf_value_get_bool (value);
350
351         g_object_unref (client);
352         gconf_value_free (value);
353         return offline;
354 }