Remove libogs dependency in fremantle (fixes NB#108071)
[modest] / src / modest-account-mgr-helpers.c
1 /* Copyright (c) 2006, Nokia Corporation
2  * All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are
6  * met:
7  *
8  * * Redistributions of source code must retain the above copyright
9  *   notice, this list of conditions and the following disclaimer.
10  * * Redistributions in binary form must reproduce the above copyright
11  *   notice, this list of conditions and the following disclaimer in the
12  *   documentation and/or other materials provided with the distribution.
13  * * Neither the name of the Nokia Corporation nor the names of its
14  *   contributors may be used to endorse or promote products derived from
15  *   this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
18  * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
20  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
21  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  */
29
30 #include <modest-account-mgr-helpers.h>
31 #include <modest-account-mgr-priv.h>
32 #include <tny-simple-list.h>
33 #include <modest-runtime.h>
34 #include <modest-defs.h>
35 #include <string.h>
36 #include <strings.h>
37
38 static const gchar * null_means_empty (const gchar * str);
39
40 static const gchar *
41 null_means_empty (const gchar * str)
42 {
43         return str ? str : "";
44 }
45
46 gboolean
47 modest_account_mgr_set_enabled (ModestAccountMgr *self, const gchar* name,
48                                         gboolean enabled)
49 {
50         return modest_account_mgr_set_bool (self, name, MODEST_ACCOUNT_ENABLED, enabled,FALSE);
51 }
52
53
54 gboolean
55 modest_account_mgr_get_enabled (ModestAccountMgr *self, const gchar* name)
56 {
57         return modest_account_mgr_get_bool (self, name, MODEST_ACCOUNT_ENABLED, FALSE);
58 }
59
60 gboolean modest_account_mgr_set_signature (ModestAccountMgr *self, const gchar* name, 
61         const gchar* signature, gboolean use_signature)
62 {
63         gboolean result = modest_account_mgr_set_bool (self, name, MODEST_ACCOUNT_USE_SIGNATURE, 
64                 use_signature, FALSE);
65         result = result && modest_account_mgr_set_string (self, name, MODEST_ACCOUNT_SIGNATURE, 
66                                                           null_means_empty (signature), FALSE);
67         return result;
68 }
69
70 gchar* 
71 modest_account_mgr_get_signature (ModestAccountMgr *self, 
72                                   const gchar* name, 
73                                   gboolean* use_signature)
74 {
75         *use_signature = 
76                 modest_account_mgr_get_bool (self, name, MODEST_ACCOUNT_USE_SIGNATURE, FALSE);
77         
78         return modest_account_mgr_get_string (self, name, MODEST_ACCOUNT_SIGNATURE, FALSE);
79 }
80
81 ModestProtocolType modest_account_mgr_get_store_protocol (ModestAccountMgr *self, const gchar* name)
82 {
83        ModestProtocolType result = MODEST_PROTOCOLS_STORE_POP; /* Arbitrary default */
84        
85        gchar *server_account_name = modest_account_mgr_get_string (self, name,
86                                                                    MODEST_ACCOUNT_STORE_ACCOUNT,
87                                                                    FALSE);
88        if (server_account_name) {
89                ModestServerAccountSettings* server_settings = 
90                        modest_account_mgr_load_server_settings (self, server_account_name, FALSE);
91                result = modest_server_account_settings_get_protocol (server_settings);
92                
93                g_object_unref (server_settings);
94                
95                g_free (server_account_name);
96        }
97        
98        return result;
99 }
100
101
102 gboolean 
103 modest_account_mgr_set_connection_specific_smtp (ModestAccountMgr *self, 
104                                                  const gchar* connection_id, 
105                                                  const gchar* server_account_name)
106 {
107         modest_account_mgr_remove_connection_specific_smtp (self, connection_id);
108         
109         ModestConf *conf = MODEST_ACCOUNT_MGR_GET_PRIVATE (self)->modest_conf;
110
111         gboolean result = TRUE;
112         GError *err = NULL;
113         GSList *list = modest_conf_get_list (conf, MODEST_CONF_CONNECTION_SPECIFIC_SMTP_LIST,
114                                                     MODEST_CONF_VALUE_STRING, &err);
115         if (err) {
116                 g_printerr ("modest: %s: error getting list: %s.\n", __FUNCTION__, err->message);
117                 g_error_free (err);
118                 err = NULL;
119                 result = FALSE;
120         } else {        
121                 /* The server account is in the item after the connection name: */
122                 list = g_slist_append (list, g_strdup (connection_id));
123                 list = g_slist_append (list, g_strdup (server_account_name));
124         
125                 /* Reset the changed list: */
126                 modest_conf_set_list (conf, MODEST_CONF_CONNECTION_SPECIFIC_SMTP_LIST, list,
127                                                     MODEST_CONF_VALUE_STRING, &err);
128                 if (err) {
129                         g_printerr ("modest: %s: error setting list: %s.\n", __FUNCTION__, err->message);
130                         g_error_free (err);
131                         result = FALSE;
132                 }
133         }
134                                 
135         /* Free the list */
136         if (list) {
137                 g_slist_foreach (list, (GFunc) g_free, NULL);
138                 g_slist_free (list);
139         }
140         
141         return result;
142 }
143
144 /**
145  * modest_account_mgr_remove_connection_specific_smtp
146  * @self: a ModestAccountMgr instance
147  * @name: the account name
148  * @connection_id: A libconic IAP connection id
149  * 
150  * Disassacoiate a server account to use with the specific connection for this account.
151  *
152  * Returns: TRUE if it worked, FALSE otherwise
153  */                              
154 gboolean 
155 modest_account_mgr_remove_connection_specific_smtp (ModestAccountMgr *self, 
156                                                     const gchar* connection_id)
157 {
158         ModestAccountMgrPrivate *priv = MODEST_ACCOUNT_MGR_GET_PRIVATE (self);
159         
160         gboolean result = TRUE;
161         GError *err = NULL;
162         GSList *list = modest_conf_get_list (priv->modest_conf, 
163                                              MODEST_CONF_CONNECTION_SPECIFIC_SMTP_LIST,
164                                              MODEST_CONF_VALUE_STRING, &err);
165         if (err) {
166                 g_printerr ("modest: %s: error getting list: %s.\n", __FUNCTION__, err->message);
167                 g_error_free (err);
168                 err = NULL;
169                 result = FALSE;
170         }
171
172         if (!list)
173                 return FALSE;
174                 
175         /* The server account is in the item after the connection name: */
176         GSList *list_connection = g_slist_find_custom (list, connection_id, (GCompareFunc)strcmp);
177         if (list_connection) {
178                 GSList *account_node = g_slist_next (list_connection);
179                 /* remove both items: */
180                 list = g_slist_delete_link(list, list_connection);
181                 list = g_slist_delete_link(list, account_node);
182         }
183         
184         /* Reset the changed list: */
185         modest_conf_set_list (priv->modest_conf, MODEST_CONF_CONNECTION_SPECIFIC_SMTP_LIST, list,
186                                                     MODEST_CONF_VALUE_STRING, &err);
187         if (err) {
188                 g_printerr ("modest: %s: error setting list: %s.\n", __FUNCTION__, err->message);
189                 g_error_free (err);
190                 result = FALSE;
191         }
192                                 
193         /* Free the list */
194         if (list) {
195                 g_slist_foreach (list, (GFunc) g_free, NULL);
196                 g_slist_free (list);
197         }
198         
199         return result;
200 }
201
202
203 gboolean modest_account_mgr_get_use_connection_specific_smtp (ModestAccountMgr *self, const gchar* account_name)
204 {
205         return modest_account_mgr_get_bool (self, account_name, 
206                 MODEST_ACCOUNT_USE_CONNECTION_SPECIFIC_SMTP, FALSE);
207 }
208
209 gboolean modest_account_mgr_set_use_connection_specific_smtp (ModestAccountMgr *self, const gchar* account_name, 
210         gboolean new_value)
211 {
212         return modest_account_mgr_set_bool (self, account_name, MODEST_ACCOUNT_USE_CONNECTION_SPECIFIC_SMTP, 
213                 new_value, FALSE);
214 }
215
216 /**
217  * modest_account_mgr_get_connection_specific_smtp
218  * @self: a ModestAccountMgr instance
219  * @connection_id: A libconic IAP connection id
220  * 
221  * Retrieve a server account to use with this specific connection for this account.
222  *
223  * Returns: a server account name to use for this connection, or NULL if none is specified.
224  */                      
225 gchar* modest_account_mgr_get_connection_specific_smtp (ModestAccountMgr *self,  const gchar* connection_id)
226 {
227         gchar *result = NULL;
228         
229         ModestAccountMgrPrivate *priv = MODEST_ACCOUNT_MGR_GET_PRIVATE (self);
230         
231         GError *err = NULL;
232         GSList *list = modest_conf_get_list (priv->modest_conf, MODEST_CONF_CONNECTION_SPECIFIC_SMTP_LIST,
233                                                     MODEST_CONF_VALUE_STRING, &err);
234         if (err) {
235                 g_printerr ("modest: %s: error getting list: %s.\n", __FUNCTION__, err->message);
236                 g_error_free (err);
237                 err = NULL;
238         }
239
240         if (!list)
241                 return NULL;
242
243         /* The server account is in the item after the connection name: */
244         GSList *iter = list;
245         while (iter) {
246                 const gchar* this_connection_id = (const gchar*)(iter->data);
247                 if (strcmp (this_connection_id, connection_id) == 0) {
248                         iter = g_slist_next (iter);
249                         
250                         if (iter) {
251                                 const gchar* account_name = (const gchar*)(iter->data);
252                                 if (account_name) {
253                                         result = g_strdup (account_name);
254                                         break;
255                                 }
256                         }
257                 }
258                 
259                 /* Skip 2 to go to the next connection in the list: */
260                 iter = g_slist_next (iter);
261                 if (iter)
262                         iter = g_slist_next (iter);
263         }
264                 
265         /* Free the list */
266         if (list) {
267                 g_slist_foreach (list, (GFunc) g_free, NULL);
268                 g_slist_free (list);
269         }
270         
271         return result;
272 }
273                                          
274 gchar*
275 modest_account_mgr_get_server_account_username (ModestAccountMgr *self, const gchar* account_name)
276 {
277         return modest_account_mgr_get_string (self, account_name, MODEST_ACCOUNT_USERNAME, 
278                 TRUE /* server account */);
279 }
280
281 void
282 modest_account_mgr_set_server_account_username (ModestAccountMgr *self, const gchar* account_name, 
283         const gchar* username)
284 {
285         /* Note that this won't work properly as long as the gconf cache is broken 
286          * in Maemo Bora: */
287         gchar *existing_username = modest_account_mgr_get_server_account_username(self, 
288                 account_name);
289         
290         modest_account_mgr_set_string (self, account_name, MODEST_ACCOUNT_USERNAME, 
291                 username, TRUE /* server account */);
292                 
293         /* We don't know anything about new usernames: */
294         if (strcmp (existing_username, username) != 0)
295                 modest_account_mgr_set_server_account_username_has_succeeded (self, account_name, FALSE);
296                 
297         g_free (existing_username);
298 }
299
300 gboolean
301 modest_account_mgr_get_server_account_username_has_succeeded (ModestAccountMgr *self, const gchar* account_name)
302 {
303         return modest_account_mgr_get_bool (self, account_name, MODEST_ACCOUNT_USERNAME_HAS_SUCCEEDED, 
304                                             TRUE /* server account */);
305 }
306
307 void
308 modest_account_mgr_set_server_account_username_has_succeeded (ModestAccountMgr *self, 
309                                                   const gchar* account_name, 
310                                                   gboolean succeeded)
311 {
312         modest_account_mgr_set_bool (self, account_name, MODEST_ACCOUNT_USERNAME_HAS_SUCCEEDED, 
313                                      succeeded, TRUE /* server account */);
314 }
315
316 gchar*
317 modest_account_mgr_get_server_account_password (ModestAccountMgr *self, const gchar* account_name)
318 {
319         return modest_account_mgr_get_string (self, account_name, MODEST_ACCOUNT_PASSWORD, 
320                 TRUE /* server account */);     
321 }
322
323 gboolean
324 modest_account_mgr_get_server_account_has_password (ModestAccountMgr *self, const gchar* account_name)
325 {
326         gboolean result = FALSE;
327         gchar *password = modest_account_mgr_get_string (self, account_name, MODEST_ACCOUNT_PASSWORD, 
328                 TRUE /* server account */);
329         if (password && strlen (password)) {
330                 result = TRUE;
331         
332                 /* Clean password */
333                 bzero (password, strlen (password));
334         }
335
336         g_free (password);
337         return result;
338 }
339                          
340         
341 gchar*
342 modest_account_mgr_get_server_account_hostname (ModestAccountMgr *self, 
343                                                 const gchar* account_name)
344 {
345         return modest_account_mgr_get_string (self, 
346                                               account_name, 
347                                               MODEST_ACCOUNT_HOSTNAME, 
348                                               TRUE /* server account */);
349 }
350  
351 void
352 modest_account_mgr_set_server_account_hostname (ModestAccountMgr *self, 
353                                                 const gchar *server_account_name,
354                                                 const gchar *hostname)
355 {
356         modest_account_mgr_set_string (self, 
357                                        server_account_name,
358                                        MODEST_ACCOUNT_HOSTNAME, 
359                                        hostname, 
360                                        TRUE /* server account */);
361 }
362
363
364
365 ModestProtocolType
366 modest_account_mgr_get_server_account_secure_auth (ModestAccountMgr *self, 
367         const gchar* account_name)
368 {
369         ModestProtocolRegistry *protocol_registry;
370         ModestProtocolType result = MODEST_PROTOCOLS_AUTH_NONE;
371         gchar* value;
372
373         protocol_registry = modest_runtime_get_protocol_registry ();
374         value = modest_account_mgr_get_string (self, account_name, MODEST_ACCOUNT_AUTH_MECH, 
375                                                TRUE /* server account */);
376         if (value) {
377                 ModestProtocol *protocol;
378
379                 protocol = modest_protocol_registry_get_protocol_by_name (protocol_registry, MODEST_PROTOCOL_REGISTRY_AUTH_PROTOCOLS, value);
380                 g_free (value);
381
382                 if (protocol)
383                         result = modest_protocol_get_type_id (protocol);
384                         
385         }
386         
387         return result;
388 }
389
390
391 void
392 modest_account_mgr_set_server_account_secure_auth (ModestAccountMgr *self, 
393         const gchar* account_name, ModestProtocolType secure_auth)
394 {
395         const gchar* str_value;
396         ModestProtocolRegistry *protocol_registry;
397         ModestProtocol *protocol;
398
399         /* Get the conf string for the protocol: */
400         protocol_registry = modest_runtime_get_protocol_registry ();
401         protocol = modest_protocol_registry_get_protocol_by_type (protocol_registry, secure_auth);
402         str_value = modest_protocol_get_name (protocol);
403         
404         /* Set it in the configuration: */
405         modest_account_mgr_set_string (self, account_name, MODEST_ACCOUNT_AUTH_MECH, str_value, TRUE);
406 }
407
408 ModestProtocolType
409 modest_account_mgr_get_server_account_security (ModestAccountMgr *self, 
410         const gchar* account_name)
411 {
412         ModestProtocolType result = MODEST_PROTOCOLS_CONNECTION_NONE;
413         gchar* value;
414
415         value = modest_account_mgr_get_string (self, account_name, MODEST_ACCOUNT_SECURITY, 
416                                                TRUE /* server account */);
417         if (value) {
418                 ModestProtocolRegistry *protocol_registry;
419                 ModestProtocol *protocol;
420
421                 protocol_registry = modest_runtime_get_protocol_registry ();
422                 protocol = modest_protocol_registry_get_protocol_by_name (protocol_registry,
423                                                                           MODEST_PROTOCOL_REGISTRY_CONNECTION_PROTOCOLS,
424                                                                           value);
425                 g_free (value);
426
427                 if (protocol)
428                         result = modest_protocol_get_type_id (protocol);
429         }
430         
431         return result;
432 }
433
434 void
435 modest_account_mgr_set_server_account_security (ModestAccountMgr *self, 
436                                                 const gchar* account_name, 
437                                                 ModestProtocolType security)
438 {
439         const gchar* str_value;
440         ModestProtocolRegistry *protocol_registry;
441         ModestProtocol *protocol;
442
443         /* Get the conf string for the protocol type: */
444         protocol_registry = modest_runtime_get_protocol_registry ();
445         protocol = modest_protocol_registry_get_protocol_by_type (protocol_registry, security);
446         str_value = modest_protocol_get_name (protocol);
447         
448         /* Set it in the configuration: */
449         modest_account_mgr_set_string (self, account_name, MODEST_ACCOUNT_SECURITY, str_value, TRUE);
450 }
451
452 ModestServerAccountSettings *
453 modest_account_mgr_load_server_settings (ModestAccountMgr *self, const gchar* name, gboolean is_transport_and_not_store)
454 {
455         ModestServerAccountSettings *settings = NULL;
456         ModestProtocol *protocol;
457         ModestProtocolRegistry *registry;
458         gchar *hostname, *username, *pwd, *uri, *proto, *auth, *sec;
459
460         if (!modest_account_mgr_account_exists (self, name, TRUE)) {
461                 g_message ("%s account %s does not exist", __FUNCTION__, name);
462                 return NULL;
463         }
464
465         registry = modest_runtime_get_protocol_registry ();
466         settings = modest_server_account_settings_new ();
467
468         modest_server_account_settings_set_account_name (settings, name);
469
470         proto = modest_account_mgr_get_string (self, name, MODEST_ACCOUNT_PROTO, TRUE);
471         if (proto) {
472                 gchar *tag = NULL;
473                 if (is_transport_and_not_store) {
474                         tag = MODEST_PROTOCOL_REGISTRY_TRANSPORT_PROTOCOLS;
475                 } else {
476                         tag = MODEST_PROTOCOL_REGISTRY_STORE_PROTOCOLS;
477                 }
478                 protocol = modest_protocol_registry_get_protocol_by_name (registry, tag, proto);
479
480                 modest_server_account_settings_set_protocol (settings,
481                                                              modest_protocol_get_type_id (protocol));
482                 g_free (proto);
483         } else {
484                 goto on_error;
485         }
486
487         modest_server_account_settings_set_port (settings,
488                                                  modest_account_mgr_get_int (self, name, MODEST_ACCOUNT_PORT, TRUE));
489
490         auth = modest_account_mgr_get_string (self, name, MODEST_ACCOUNT_AUTH_MECH, TRUE);
491         if (auth) {
492                 protocol = modest_protocol_registry_get_protocol_by_name (registry, MODEST_PROTOCOL_REGISTRY_AUTH_PROTOCOLS, auth);
493                 modest_server_account_settings_set_auth_protocol (settings,
494                                                                   modest_protocol_get_type_id (protocol));
495                 g_free (auth);
496         } else {
497                 modest_server_account_settings_set_auth_protocol (settings, MODEST_PROTOCOLS_AUTH_NONE);
498         }
499
500         sec = modest_account_mgr_get_string (self, name, MODEST_ACCOUNT_SECURITY, TRUE);
501         if (sec) {
502                 protocol = modest_protocol_registry_get_protocol_by_name (registry, MODEST_PROTOCOL_REGISTRY_CONNECTION_PROTOCOLS, sec);
503                 modest_server_account_settings_set_security_protocol (settings,
504                                                                       modest_protocol_get_type_id (protocol));
505                 g_free (sec);
506         } else {
507                 modest_server_account_settings_set_security_protocol (settings,
508                                                                       MODEST_PROTOCOLS_CONNECTION_NONE);
509         }
510
511         /* Username, password and URI. Note that the URI could include
512            the former two, so in this case there is no need to have
513            them */
514         username = modest_account_mgr_get_string (self, name,
515                                                   MODEST_ACCOUNT_USERNAME,TRUE);
516         if (username)
517                 modest_server_account_settings_set_username (settings, username);
518
519         pwd = modest_account_mgr_get_string (self, name,
520                                              MODEST_ACCOUNT_PASSWORD, TRUE);
521         if (pwd) {
522                 modest_server_account_settings_set_password (settings, pwd);
523                 g_free (pwd);
524         }
525
526         uri = modest_account_mgr_get_string (self, name,
527                                              MODEST_ACCOUNT_URI, TRUE);
528         if (uri)
529                 modest_server_account_settings_set_uri (settings, uri);
530
531         hostname = modest_account_mgr_get_string (self, name,
532                                                   MODEST_ACCOUNT_HOSTNAME,TRUE);
533         if (hostname)
534                 modest_server_account_settings_set_hostname (settings, hostname);
535
536         if (!uri) {
537                 if (!username || !hostname) {
538                         g_free (username);
539                         g_free (hostname);
540                         goto on_error;
541                 }
542         }
543
544         g_free (username);
545         g_free (hostname);
546         g_free (uri);
547
548         return settings;
549
550  on_error:
551         if (settings)
552                 g_object_unref (settings);
553         return NULL;
554 }
555
556 gboolean 
557 modest_account_mgr_save_server_settings (ModestAccountMgr *self,
558                                          ModestServerAccountSettings *settings)
559 {
560         gboolean has_errors = FALSE;
561         const gchar *account_name;
562         const gchar *protocol_name;
563         const gchar *uri;
564         ModestProtocolRegistry *protocol_registry;
565         ModestProtocol *protocol;
566         
567         g_return_val_if_fail (MODEST_IS_SERVER_ACCOUNT_SETTINGS (settings), FALSE);
568         protocol_registry = modest_runtime_get_protocol_registry ();
569         account_name = modest_server_account_settings_get_account_name (settings);
570
571         /* if we don't have a valid account name we cannot save */
572         g_return_val_if_fail (account_name, FALSE);
573
574         protocol = modest_protocol_registry_get_protocol_by_type (protocol_registry,
575                                                                   modest_server_account_settings_get_protocol (settings));
576         protocol_name = modest_protocol_get_name (protocol);
577         uri = modest_server_account_settings_get_uri (settings);
578         if (!uri) {
579                 const gchar *hostname;
580                 const gchar *username;
581                 const gchar *password;
582                 gint port;
583                 const gchar *auth_protocol_name;
584                 const gchar *security_name;
585
586                 hostname = null_means_empty (modest_server_account_settings_get_hostname (settings));
587                 username = null_means_empty (modest_server_account_settings_get_username (settings));
588                 password = null_means_empty (modest_server_account_settings_get_password (settings));
589                 port = modest_server_account_settings_get_port (settings);
590                 protocol = modest_protocol_registry_get_protocol_by_type (protocol_registry,
591                                                                           modest_server_account_settings_get_auth_protocol (settings));
592                 auth_protocol_name = modest_protocol_get_name (protocol);
593                 protocol = modest_protocol_registry_get_protocol_by_type (protocol_registry,
594                                                                           modest_server_account_settings_get_security_protocol (settings));
595                 security_name = modest_protocol_get_name (protocol);
596
597                 has_errors = !modest_account_mgr_set_string (self, account_name, MODEST_ACCOUNT_HOSTNAME, 
598                                                             hostname, TRUE);
599                 if (!has_errors)
600                         (has_errors = !modest_account_mgr_set_string (self, account_name, MODEST_ACCOUNT_USERNAME,
601                                                                            username, TRUE));
602                 if (!has_errors)
603                         (has_errors = !modest_account_mgr_set_string (self, account_name, MODEST_ACCOUNT_PASSWORD,
604                                                                            password, TRUE));
605                 if (!has_errors)
606                         (has_errors = !modest_account_mgr_set_string (self, account_name, MODEST_ACCOUNT_PROTO,
607                                                                            protocol_name, TRUE));
608                 if (!has_errors)
609                         (has_errors = !modest_account_mgr_set_int (self, account_name, MODEST_ACCOUNT_PORT,
610                                                                         port, TRUE));
611                 if (!has_errors)
612                         (has_errors = !modest_account_mgr_set_string (self, account_name, 
613                                                                            MODEST_ACCOUNT_AUTH_MECH,
614                                                                            auth_protocol_name, TRUE));          
615                 if (!has_errors)
616                         (has_errors = !modest_account_mgr_set_string (self, account_name, MODEST_ACCOUNT_SECURITY,
617                                                                            security_name,
618                                                                            TRUE));
619         } else {
620                 const gchar *uri = modest_server_account_settings_get_uri (settings);
621                 has_errors = !modest_account_mgr_set_string (self, account_name, MODEST_ACCOUNT_URI,
622                                                             uri, TRUE);
623                 if (!has_errors)
624                         (has_errors = !modest_account_mgr_set_string (self, account_name, MODEST_ACCOUNT_PROTO,
625                                                                            protocol_name, TRUE));
626         }
627
628         return !has_errors;
629
630 }
631
632
633 ModestAccountSettings *
634 modest_account_mgr_load_account_settings (ModestAccountMgr *self, 
635                                           const gchar* name)
636 {
637         ModestAccountSettings *settings;
638         gchar *string;
639         gchar *server_account;
640         gchar *default_account;
641         gboolean use_signature = FALSE;
642         
643         g_return_val_if_fail (self, NULL);
644         g_return_val_if_fail (name, NULL);
645         
646         if (!modest_account_mgr_account_exists (self, name, FALSE)) {
647                 /* For instance, maybe you are mistakenly checking for a server account name? */
648                 g_warning ("%s: Account %s does not exist.", __FUNCTION__, name);
649                 return NULL;
650         }
651         
652         settings = modest_account_settings_new ();
653
654         modest_account_settings_set_account_name (settings, name);
655
656         string = modest_account_mgr_get_string (self, name,
657                                                 MODEST_ACCOUNT_DISPLAY_NAME,
658                                                 FALSE);
659         modest_account_settings_set_display_name (settings, string);
660         g_free (string);
661
662         string = modest_account_mgr_get_string (self, name,
663                                                 MODEST_ACCOUNT_FULLNAME,
664                                                 FALSE);
665         modest_account_settings_set_fullname (settings, string);
666         g_free (string);
667
668         string = modest_account_mgr_get_string (self, name,
669                                                 MODEST_ACCOUNT_EMAIL,
670                                                 FALSE);
671         modest_account_settings_set_email_address (settings, string);
672         g_free (string);
673
674         modest_account_settings_set_enabled (settings, modest_account_mgr_get_enabled (self, name));
675         modest_account_settings_set_retrieve_type (settings, modest_account_mgr_get_retrieve_type (self, name));
676         modest_account_settings_set_retrieve_limit (settings, modest_account_mgr_get_retrieve_limit (self, name));
677
678         default_account    = modest_account_mgr_get_default_account (self);
679         modest_account_settings_set_is_default (settings,
680                                                 (default_account && strcmp (default_account, name) == 0));
681         g_free (default_account);
682
683         string = modest_account_mgr_get_signature (self, name, &use_signature);
684         modest_account_settings_set_use_signature (settings, use_signature);
685         modest_account_settings_set_signature (settings, string);
686         g_free (string);
687
688         modest_account_settings_set_leave_messages_on_server 
689                 (settings, modest_account_mgr_get_leave_on_server (self, name));
690         modest_account_settings_set_use_connection_specific_smtp 
691                 (settings, modest_account_mgr_get_use_connection_specific_smtp (self, name));
692
693         /* store */
694         server_account     = modest_account_mgr_get_string (self, name,
695                                                             MODEST_ACCOUNT_STORE_ACCOUNT,
696                                                             FALSE);
697         if (server_account) {
698                 ModestServerAccountSettings *store_settings;
699                 store_settings = modest_account_mgr_load_server_settings (self, server_account, FALSE);
700                 g_free (server_account);
701
702                 /* It could happen that the account data is corrupted
703                    so it's not loaded properly */
704                 if (store_settings) {
705                         modest_account_settings_set_store_settings (settings,
706                                                                     store_settings);
707                         g_object_unref (store_settings);
708                 } else {
709                         g_message ("%s can not load server settings. Account corrupted?", __FUNCTION__);
710                         g_object_unref (settings);
711                         return NULL;
712                 }
713         }
714
715         /* transport */
716         server_account = modest_account_mgr_get_string (self, name,
717                                                         MODEST_ACCOUNT_TRANSPORT_ACCOUNT,
718                                                         FALSE);
719         if (server_account) {
720                 ModestServerAccountSettings *transport_settings;
721                 transport_settings = modest_account_mgr_load_server_settings (self, server_account, TRUE);
722                 g_free (server_account);
723
724                 if (transport_settings) {
725                         modest_account_settings_set_transport_settings (settings, transport_settings);
726                         g_object_unref (transport_settings);
727                 } else {
728                         g_message ("%s can not load server settings. Account corrupted?", __FUNCTION__);
729                         g_object_unref (settings);
730                         return NULL;
731                 }
732         }
733
734         return settings;
735 }
736
737 void
738 modest_account_mgr_save_account_settings (ModestAccountMgr *mgr,
739                                           ModestAccountSettings *settings)
740 {
741         const gchar *account_name;
742         ModestServerAccountSettings *store_settings;
743         ModestServerAccountSettings *transport_settings;
744
745         g_return_if_fail (MODEST_IS_ACCOUNT_MGR (mgr));
746         g_return_if_fail (MODEST_IS_ACCOUNT_SETTINGS (settings));
747
748         account_name = modest_account_settings_get_account_name (settings);
749         g_return_if_fail (account_name != NULL);
750
751         modest_account_mgr_set_display_name (mgr, account_name,
752                                              modest_account_settings_get_display_name (settings));
753         modest_account_mgr_set_user_fullname (mgr, account_name,
754                                               modest_account_settings_get_fullname (settings));
755         modest_account_mgr_set_user_email (mgr, account_name,
756                                            modest_account_settings_get_email_address (settings));
757         modest_account_mgr_set_retrieve_type (mgr, account_name,
758                                               modest_account_settings_get_retrieve_type (settings));
759         modest_account_mgr_set_retrieve_limit (mgr, account_name,
760                                                modest_account_settings_get_retrieve_limit (settings));
761         modest_account_mgr_set_leave_on_server (mgr, account_name,
762                                                 modest_account_settings_get_leave_messages_on_server (settings));
763         modest_account_mgr_set_signature (mgr, account_name,
764                                           modest_account_settings_get_signature (settings),
765                                           modest_account_settings_get_use_signature (settings));
766         modest_account_mgr_set_use_connection_specific_smtp 
767                 (mgr, account_name,
768                  modest_account_settings_get_use_connection_specific_smtp (settings));
769
770         store_settings = modest_account_settings_get_store_settings (settings);
771         if (store_settings) {
772                 const gchar *store_account_name;
773                 store_account_name = modest_server_account_settings_get_account_name (store_settings);
774                 if (store_account_name)
775                         modest_account_mgr_set_string (mgr, account_name, MODEST_ACCOUNT_STORE_ACCOUNT, 
776                                                        store_account_name, FALSE);
777                 modest_account_mgr_save_server_settings (mgr, store_settings);
778                 g_object_unref (store_settings);
779         }
780
781         transport_settings = modest_account_settings_get_transport_settings (settings);
782         if (transport_settings) {
783                 const gchar *transport_account_name;
784                 transport_account_name = modest_server_account_settings_get_account_name (transport_settings);
785                 if (transport_account_name)
786                         modest_account_mgr_set_string (mgr, account_name, MODEST_ACCOUNT_TRANSPORT_ACCOUNT, 
787                                                        transport_account_name, FALSE);
788                 modest_account_mgr_save_server_settings (mgr, transport_settings);
789                 g_object_unref (transport_settings);
790         }
791         modest_account_mgr_set_enabled (mgr, account_name, TRUE);
792 }
793
794
795 gint 
796 on_accounts_list_sort_by_title(gconstpointer a, gconstpointer b)
797 {
798         return g_utf8_collate((const gchar*)a, (const gchar*)b);
799 }
800
801 /** Get the first one, alphabetically, by title. */
802 gchar* 
803 modest_account_mgr_get_first_account_name (ModestAccountMgr *self)
804 {
805         const gchar* account_name = NULL;
806         GSList *account_names = modest_account_mgr_account_names (self, TRUE /* only enabled */);
807
808         /* Return TRUE if there is no account */
809         if (!account_names)
810                 return NULL;
811
812         /* Get the first one, alphabetically, by title: */
813         /* gchar *old_default = modest_account_mgr_get_default_account (self); */
814         GSList* list_sorted = g_slist_sort (account_names, on_accounts_list_sort_by_title);
815
816         GSList* iter = list_sorted;
817         gboolean found = FALSE;
818         while (iter && !found) {
819                 account_name = (const gchar*)list_sorted->data;
820
821                 if (account_name)
822                         found = TRUE;
823
824                 if (!found)
825                         iter = g_slist_next (iter);
826         }
827
828         gchar* result = NULL;
829         if (account_name)
830                 result = g_strdup (account_name);
831                 
832         modest_account_mgr_free_account_names (account_names);
833         account_names = NULL;
834
835         return result;
836 }
837
838 gboolean
839 modest_account_mgr_set_first_account_as_default (ModestAccountMgr *self)
840 {
841         gboolean result = FALSE;
842         
843         gchar* account_name = modest_account_mgr_get_first_account_name(self);
844         if (account_name) {
845                 result = modest_account_mgr_set_default_account (self, account_name);
846                 g_free (account_name);
847         }
848         else
849                 result = TRUE; /* If there are no accounts then it's not a failure. */
850
851         return result;
852 }
853
854 gchar*
855 modest_account_mgr_get_from_string (ModestAccountMgr *self, const gchar* name)
856 {
857         gchar *fullname, *email, *from;
858         
859         g_return_val_if_fail (self, NULL);
860         g_return_val_if_fail (name, NULL);
861
862         fullname      = modest_account_mgr_get_string (self, name,MODEST_ACCOUNT_FULLNAME,
863                                                        FALSE);
864         email         = modest_account_mgr_get_string (self, name, MODEST_ACCOUNT_EMAIL,
865                                                        FALSE);
866         from = g_strdup_printf ("%s <%s>",
867                                 fullname ? fullname : "",
868                                 email    ? email    : "");
869         g_free (fullname);
870         g_free (email);
871
872         return from;
873 }
874
875 /* Add a number to the end of the text, or increment a number that is already there.
876  */
877 static gchar*
878 util_increment_name (const gchar* text)
879 {
880         g_return_val_if_fail (text, NULL);
881
882         /* Get the end character,
883          * also doing a UTF-8 validation which is required for using g_utf8_prev_char().
884          */
885         const gchar* end = NULL;
886         if (!g_utf8_validate (text, -1, &end))
887                 return NULL;
888   
889         if (!end)
890                 return NULL;
891                 
892         --end; /* Go to before the null-termination. */
893                 
894         /* Look at each UTF-8 characer, starting at the end: */
895         const gchar* p = end;
896         const gchar* alpha_end = NULL;
897         while (p)
898         {       
899                 /* Stop when we reach the first character that is not a numeric digit: */
900                 const gunichar ch = g_utf8_get_char (p);
901                 if (!g_unichar_isdigit (ch)) {
902                         alpha_end = p;
903                         break;
904                 }
905                 
906                 p = g_utf8_find_prev_char (text, p);    
907         }
908         
909         if(!alpha_end) {
910                 /* The text must consist completely of numeric digits. */
911                 alpha_end = text;
912         }
913         else
914                 ++alpha_end;
915         
916         /* Intepret and increment the number, if any: */
917         gint num = atol (alpha_end);
918         ++num;
919         
920         /* Get the name part: */
921         gint name_len = alpha_end - text;
922         gchar *name_without_number = g_malloc(name_len + 1);
923         memcpy (name_without_number, text, name_len);
924         name_without_number[name_len] = 0;\
925         
926     /* Concatenate the text part and the new number: */ 
927         gchar *result = g_strdup_printf("%s%d", name_without_number, num);
928         g_free (name_without_number);
929         
930         return result;  
931 }
932
933 gchar*
934 modest_account_mgr_get_unused_account_name (ModestAccountMgr *self, const gchar* starting_name,
935         gboolean server_account)
936 {
937         gchar *account_name = g_strdup (starting_name);
938
939         while (modest_account_mgr_account_exists (self, 
940                 account_name, server_account /*  server_account */)) {
941                         
942                 gchar * account_name2 = util_increment_name (account_name);
943                 g_free (account_name);
944                 account_name = account_name2;
945         }
946         
947         return account_name;
948 }
949
950 gchar*
951 modest_account_mgr_get_unused_account_display_name (ModestAccountMgr *self, const gchar* starting_name)
952 {
953         gchar *account_name = g_strdup (starting_name);
954
955         while (modest_account_mgr_account_with_display_name_exists (self, account_name)) {
956                         
957                 gchar * account_name2 = util_increment_name (account_name);
958                 g_free (account_name);
959                 account_name = account_name2;
960         }
961         
962         return account_name;
963 }
964
965 void 
966 modest_account_mgr_set_leave_on_server (ModestAccountMgr *self, 
967                                         const gchar *account_name, 
968                                         gboolean leave_on_server)
969 {
970         modest_account_mgr_set_bool (self, 
971                                      account_name,
972                                      MODEST_ACCOUNT_LEAVE_ON_SERVER, 
973                                      leave_on_server, 
974                                      FALSE);
975 }
976
977 gboolean 
978 modest_account_mgr_get_leave_on_server (ModestAccountMgr *self, 
979                                         const gchar* account_name)
980 {
981         return modest_account_mgr_get_bool (self, 
982                                             account_name,
983                                             MODEST_ACCOUNT_LEAVE_ON_SERVER, 
984                                             FALSE);
985 }
986
987 gint 
988 modest_account_mgr_get_last_updated (ModestAccountMgr *self, 
989                                      const gchar* account_name)
990 {
991         return modest_account_mgr_get_int (modest_runtime_get_account_mgr (), 
992                                            account_name, 
993                                            MODEST_ACCOUNT_LAST_UPDATED, 
994                                            TRUE);
995 }
996
997 void 
998 modest_account_mgr_set_last_updated (ModestAccountMgr *self, 
999                                      const gchar* account_name,
1000                                      gint time)
1001 {
1002         modest_account_mgr_set_int (self, 
1003                                     account_name, 
1004                                     MODEST_ACCOUNT_LAST_UPDATED, 
1005                                     time, 
1006                                     TRUE);
1007
1008         /* TODO: notify about changes */
1009 }
1010
1011 gint  
1012 modest_account_mgr_get_retrieve_limit (ModestAccountMgr *self, 
1013                                        const gchar* account_name)
1014 {
1015         return modest_account_mgr_get_int (self, 
1016                                            account_name,
1017                                            MODEST_ACCOUNT_LIMIT_RETRIEVE, 
1018                                            FALSE);
1019 }
1020
1021 void  
1022 modest_account_mgr_set_retrieve_limit (ModestAccountMgr *self, 
1023                                        const gchar* account_name,
1024                                        gint limit_retrieve)
1025 {
1026         modest_account_mgr_set_int (self, 
1027                                     account_name,
1028                                     MODEST_ACCOUNT_LIMIT_RETRIEVE, 
1029                                     limit_retrieve, 
1030                                     FALSE /* not server account */);
1031 }
1032
1033 gint  
1034 modest_account_mgr_get_server_account_port (ModestAccountMgr *self, 
1035                                             const gchar* account_name)
1036 {
1037         return modest_account_mgr_get_int (self, 
1038                                            account_name,
1039                                            MODEST_ACCOUNT_PORT, 
1040                                            TRUE);
1041 }
1042
1043 void
1044 modest_account_mgr_set_server_account_port (ModestAccountMgr *self, 
1045                                             const gchar *account_name,
1046                                             gint port_num)
1047 {
1048         modest_account_mgr_set_int (self, 
1049                                     account_name,
1050                                     MODEST_ACCOUNT_PORT, 
1051                                     port_num, TRUE /* server account */);
1052 }
1053
1054 gchar* 
1055 modest_account_mgr_get_server_account_name (ModestAccountMgr *self, 
1056                                             const gchar *account_name,
1057                                             TnyAccountType account_type)
1058 {
1059         return modest_account_mgr_get_string (self, 
1060                                               account_name,
1061                                               (account_type == TNY_ACCOUNT_TYPE_STORE) ?
1062                                               MODEST_ACCOUNT_STORE_ACCOUNT :
1063                                               MODEST_ACCOUNT_TRANSPORT_ACCOUNT, 
1064                                               FALSE);
1065 }
1066
1067 static const gchar *
1068 get_retrieve_type_name (ModestAccountRetrieveType retrieve_type)
1069 {
1070         switch(retrieve_type) {
1071         case MODEST_ACCOUNT_RETRIEVE_HEADERS_ONLY:
1072                 return MODEST_ACCOUNT_RETRIEVE_VALUE_HEADERS_ONLY;
1073                 break;
1074         case MODEST_ACCOUNT_RETRIEVE_MESSAGES:
1075                 return MODEST_ACCOUNT_RETRIEVE_VALUE_MESSAGES;
1076                 break;
1077         case MODEST_ACCOUNT_RETRIEVE_MESSAGES_AND_ATTACHMENTS:
1078                 return MODEST_ACCOUNT_RETRIEVE_VALUE_MESSAGES_AND_ATTACHMENTS;
1079                 break;
1080         default:
1081                 return MODEST_ACCOUNT_RETRIEVE_VALUE_HEADERS_ONLY;
1082         };
1083 }
1084
1085 static ModestAccountRetrieveType
1086 get_retrieve_type (const gchar *name)
1087 {
1088         if (!name || name[0] == 0)
1089                 return MODEST_ACCOUNT_RETRIEVE_HEADERS_ONLY;
1090         if (strcmp (name, MODEST_ACCOUNT_RETRIEVE_VALUE_MESSAGES) == 0) {
1091                 return MODEST_ACCOUNT_RETRIEVE_MESSAGES;
1092         } else if (strcmp (name, MODEST_ACCOUNT_RETRIEVE_VALUE_MESSAGES_AND_ATTACHMENTS) == 0) {
1093                 return MODEST_ACCOUNT_RETRIEVE_MESSAGES_AND_ATTACHMENTS;
1094         } else {
1095                 /* we fall back to headers only */
1096                 return MODEST_ACCOUNT_RETRIEVE_HEADERS_ONLY;
1097         }
1098 }
1099
1100 ModestAccountRetrieveType
1101 modest_account_mgr_get_retrieve_type (ModestAccountMgr *self, 
1102                                       const gchar *account_name)
1103 {
1104         gchar *string;
1105         ModestAccountRetrieveType result;
1106
1107         string =  modest_account_mgr_get_string (self, 
1108                                                  account_name,
1109                                                  MODEST_ACCOUNT_RETRIEVE, 
1110                                                  FALSE /* not server account */);
1111         result = get_retrieve_type (string);
1112         g_free (string);
1113
1114         return result;
1115 }
1116
1117 void 
1118 modest_account_mgr_set_retrieve_type (ModestAccountMgr *self, 
1119                                       const gchar *account_name,
1120                                       ModestAccountRetrieveType retrieve_type)
1121 {
1122         modest_account_mgr_set_string (self, 
1123                                        account_name,
1124                                        MODEST_ACCOUNT_RETRIEVE, 
1125                                        get_retrieve_type_name (retrieve_type), 
1126                                        FALSE /* not server account */);
1127 }
1128
1129
1130 void
1131 modest_account_mgr_set_user_fullname (ModestAccountMgr *self, 
1132                                       const gchar *account_name,
1133                                       const gchar *fullname)
1134 {
1135         modest_account_mgr_set_string (self, 
1136                                        account_name,
1137                                        MODEST_ACCOUNT_FULLNAME, 
1138                                        fullname, 
1139                                        FALSE /* not server account */);
1140 }
1141
1142 void
1143 modest_account_mgr_set_user_email (ModestAccountMgr *self, 
1144                                    const gchar *account_name,
1145                                    const gchar *email)
1146 {
1147         modest_account_mgr_set_string (self, 
1148                                        account_name,
1149                                        MODEST_ACCOUNT_EMAIL, 
1150                                        email, 
1151                                        FALSE /* not server account */);
1152 }