* added licensing boilerplate to source files
[modest] / src / modest-account-mgr.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 /* modest-account-mgr.c */
31
32
33 #include <string.h>
34 #include "modest-marshal.h"
35 #include "modest-account-keys.h"
36 #include "modest-account-mgr.h"
37
38 /* 'private'/'protected' functions */
39 static void modest_account_mgr_class_init (ModestAccountMgrClass * klass);
40 static void modest_account_mgr_init (ModestAccountMgr * obj);
41 static void modest_account_mgr_finalize (GObject * obj);
42
43 static gchar *get_account_keyname (const gchar * accname, const gchar * name);
44 static gchar *get_server_account_keyname (const gchar * accname,
45                                           const gchar * name);
46
47 /* list my signals */
48 enum {
49         ACCOUNT_CHANGE_SIGNAL,
50         ACCOUNT_REMOVE_SIGNAL,
51         ACCOUNT_ADD_SIGNAL,
52         LAST_SIGNAL
53 };
54
55 typedef struct _ModestAccountMgrPrivate ModestAccountMgrPrivate;
56 struct _ModestAccountMgrPrivate {
57         ModestConf *modest_conf;
58         GSList *current_accounts;
59 };
60
61 #define MODEST_ACCOUNT_MGR_GET_PRIVATE(o)      (G_TYPE_INSTANCE_GET_PRIVATE((o), \
62                                                 MODEST_TYPE_ACCOUNT_MGR, \
63                                                 ModestAccountMgrPrivate))
64 /* globals */
65 static GObjectClass *parent_class = NULL;
66
67 static guint signals[LAST_SIGNAL] = {0};
68
69
70 static GSList *
71 delete_account_from_list (GSList *list, const gchar *name)
72 {
73         GSList *iter, *result;
74
75         iter = list;
76         result = list;
77         while (iter) {
78                 if (!strcmp (name, iter->data)) {
79                         result = g_slist_delete_link (list, iter);
80                         break;
81                 }
82
83                 iter = g_slist_next (iter);
84         }
85         return result;
86 }
87
88 static GSList *
89 find_account_in_list (GSList *list, const gchar *name)
90 {
91         GSList *iter, *result;
92
93         iter = list;
94         result = list;
95         while (iter) {
96                 if (!strcmp (name, iter->data)) {
97                         return iter;
98                         break;
99                 }
100
101                 iter = g_slist_next (iter);
102         }
103         return NULL;
104 }
105
106 /* Map configuration changes to account changes.
107  * Doing this here makes sure all changes are available and external changes
108  * are covered as well. */
109
110 static void
111 modest_account_mgr_check_change (ModestConf *conf, const gchar *key,
112                                  const gchar *new_value, gpointer user_data)
113 {
114         ModestAccountMgr *amgr = user_data;
115         ModestAccountMgrPrivate *priv = MODEST_ACCOUNT_MGR_GET_PRIVATE (amgr);
116
117         if ((strlen (key) > strlen (MODEST_SERVER_ACCOUNT_NAMESPACE "/")
118              && g_str_has_prefix (key, MODEST_SERVER_ACCOUNT_NAMESPACE))) {
119                 gchar *subkey = g_strdup(key + strlen (MODEST_SERVER_ACCOUNT_NAMESPACE "/"));
120
121                 if (! strstr (subkey, "/")) { /* no more '/' means an account was modified */
122                         if (!new_value) {
123                                 priv->current_accounts =
124                                         delete_account_from_list (priv->current_accounts, subkey);
125
126                                 g_signal_emit (amgr, signals[ACCOUNT_REMOVE_SIGNAL], 0, subkey);
127                         }
128                 }
129                 else {
130                         gchar *param;
131
132                         param = strstr (subkey, "/");
133                         param [0] = 0;
134                         param++;
135
136                         /* that's the second case for a new account */
137                         if (!find_account_in_list (priv->current_accounts, subkey) && strstr (param, MODEST_ACCOUNT_PROTO)) {
138                                 priv->current_accounts =
139                                         g_slist_prepend (priv->current_accounts, g_strdup (subkey));
140                                 g_signal_emit (amgr, signals[ACCOUNT_ADD_SIGNAL], 0, subkey);
141                         }
142
143                         g_signal_emit (amgr, signals[ACCOUNT_CHANGE_SIGNAL], 0, subkey, param, new_value);
144                 }
145
146                 g_free (subkey);
147         }
148 }
149
150
151 GType
152 modest_account_mgr_get_type (void)
153 {
154         static GType my_type = 0;
155
156         if (!my_type) {
157                 static const GTypeInfo my_info = {
158                         sizeof (ModestAccountMgrClass),
159                         NULL,   /* base init */
160                         NULL,   /* base finalize */
161                         (GClassInitFunc) modest_account_mgr_class_init,
162                         NULL,   /* class finalize */
163                         NULL,   /* class data */
164                         sizeof (ModestAccountMgr),
165                         1,      /* n_preallocs */
166                         (GInstanceInitFunc) modest_account_mgr_init,
167                 };
168
169                 my_type = g_type_register_static (G_TYPE_OBJECT,
170                                                   "ModestAccountMgr",
171                                                   &my_info, 0);
172         }
173         return my_type;
174 }
175
176 static void
177 modest_account_mgr_class_init (ModestAccountMgrClass * klass)
178 {
179         GObjectClass *gobject_class;
180         GType paramtypes[3] = {G_TYPE_POINTER, G_TYPE_POINTER, G_TYPE_POINTER};
181
182         gobject_class = (GObjectClass *) klass;
183
184         parent_class = g_type_class_peek_parent (klass);
185         gobject_class->finalize = modest_account_mgr_finalize;
186
187         g_type_class_add_private (gobject_class,
188                                   sizeof (ModestAccountMgrPrivate));
189
190         /* signal definitions */
191         signals[ACCOUNT_ADD_SIGNAL] =
192                 g_signal_newv ("account-add",
193                                G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
194                                NULL, NULL, NULL,
195                                g_cclosure_marshal_VOID__POINTER,
196                                G_TYPE_NONE, 1, paramtypes);
197
198         signals[ACCOUNT_REMOVE_SIGNAL] =
199                 g_signal_newv ("account-remove",
200                                G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
201                                NULL, NULL, NULL,
202                                g_cclosure_marshal_VOID__POINTER,
203                                G_TYPE_NONE, 1, paramtypes);
204         signals[ACCOUNT_CHANGE_SIGNAL] =
205                 g_signal_newv ("account-change",
206                                G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
207                                NULL, NULL, NULL,
208                                modest_marshal_VOID__POINTER_POINTER_POINTER,
209                                G_TYPE_NONE, 3, paramtypes);
210 }
211
212
213 static void
214 modest_account_mgr_init (ModestAccountMgr * obj)
215 {
216         ModestAccountMgrPrivate *priv = MODEST_ACCOUNT_MGR_GET_PRIVATE (obj);
217
218         priv->modest_conf = NULL;
219 }
220
221 static void
222 modest_account_mgr_finalize (GObject * obj)
223 {
224         ModestAccountMgr *self = MODEST_ACCOUNT_MGR (obj);
225         ModestAccountMgrPrivate *priv = MODEST_ACCOUNT_MGR_GET_PRIVATE (self);
226
227         if (priv->modest_conf) {
228                 g_object_unref (G_OBJECT(priv->modest_conf));
229                 priv->modest_conf = NULL;
230         }
231 }
232
233 GObject *
234 modest_account_mgr_new (ModestConf * conf)
235 {
236         GObject *obj;
237         ModestAccountMgrPrivate *priv;
238
239         g_return_val_if_fail (conf, NULL);
240
241         obj = G_OBJECT (g_object_new (MODEST_TYPE_ACCOUNT_MGR, NULL));
242         priv = MODEST_ACCOUNT_MGR_GET_PRIVATE (obj);
243
244         /*
245          * increase the ref count on the modest_conf. Normally, the
246          * ModestConf should outlive the ModestAccountMgr though
247          */
248         g_object_ref (G_OBJECT (priv->modest_conf = conf));
249
250         priv->current_accounts = modest_account_mgr_account_names (MODEST_ACCOUNT_MGR(obj), NULL);
251
252         g_signal_connect (G_OBJECT (conf), "key-changed",
253                           G_CALLBACK (modest_account_mgr_check_change), obj);
254         return obj;
255 }
256
257
258 gboolean
259 modest_account_mgr_add_account (ModestAccountMgr * self, const gchar * name,
260                                 const gchar * store_account,
261                                 const gchar * transport_account,
262                                 GError ** err)
263 {
264         ModestAccountMgrPrivate *priv;
265         gchar *key;
266
267         g_return_val_if_fail (self, FALSE);
268         g_return_val_if_fail (name, FALSE);
269
270         if (modest_account_mgr_account_exists (self, name, err)) {
271                 g_warning ("account already exists");
272                 //return FALSE;
273         }
274         /*
275          * we create the account by adding an account 'dir', with the name <name>,
276          * and in that the 'display_name' string key
277          */
278         priv = MODEST_ACCOUNT_MGR_GET_PRIVATE (self);
279
280         key = get_account_keyname (name, MODEST_ACCOUNT_DISPLAY_NAME);
281         modest_conf_set_string (priv->modest_conf, key, name, err);
282         g_free (key);
283
284         if (store_account) {
285                 key = get_account_keyname (name,
286                                            MODEST_ACCOUNT_STORE_ACCOUNT);
287                 modest_conf_set_string (priv->modest_conf, key, store_account,
288                                         err);
289                 g_free (key);
290         }
291
292         if (transport_account) {
293                 key = get_account_keyname (name,
294                                            MODEST_ACCOUNT_TRANSPORT_ACCOUNT);
295                 modest_conf_set_string (priv->modest_conf, key,
296                                         transport_account, err);
297                 g_free (key);
298         }
299
300         return TRUE;            /* TODO: error handling */
301 }
302
303
304 gboolean
305 modest_account_mgr_remove_account (ModestAccountMgr * self,
306                                    const gchar * name, GError ** err)
307 {
308         ModestAccountMgrPrivate *priv;
309         gchar *key;
310         gboolean retval;
311
312         g_return_val_if_fail (self, FALSE);
313         g_return_val_if_fail (name, FALSE);
314
315         if (!modest_account_mgr_account_exists (self, name, err)) {
316                 g_warning ("account doest not exist");
317                 return FALSE;
318         }
319
320         priv = MODEST_ACCOUNT_MGR_GET_PRIVATE (self);
321         key = get_account_keyname (name, NULL);
322
323         retval = modest_conf_remove_key (priv->modest_conf, key, NULL);
324
325         g_free (key);
326         return retval;
327 }
328
329
330 static const gchar *
331 null_means_empty (const gchar * str)
332 {
333         return str ? str : "";
334 }
335
336
337 gboolean
338 modest_account_mgr_add_server_account (ModestAccountMgr * self,
339                                        const gchar * name,
340                                        const gchar * hostname,
341                                        const gchar * username,
342                                        const gchar * password,
343                                        const gchar * proto)
344 {
345         ModestAccountMgrPrivate *priv;
346         gchar *acckey, *key;
347
348         g_return_val_if_fail (self, FALSE);
349         g_return_val_if_fail (name, FALSE);
350
351         /* TODO: check already exists */
352
353         priv = MODEST_ACCOUNT_MGR_GET_PRIVATE (self);
354         acckey = g_strconcat (MODEST_SERVER_ACCOUNT_NAMESPACE, "/",
355                               name, NULL);
356
357         if (modest_conf_key_exists (priv->modest_conf, acckey, NULL)) {
358                 g_warning ("server account %s already exists", name);
359                 //g_free (acckey);
360                 //return FALSE;
361         }
362
363         /* hostname */
364         key = g_strconcat (acckey, "/", MODEST_ACCOUNT_HOSTNAME, NULL);
365         modest_conf_set_string (priv->modest_conf, key,
366                                 null_means_empty (hostname), NULL);
367         g_free (key);
368
369         /* username */
370         key = g_strconcat (acckey, "/", MODEST_ACCOUNT_USERNAME, NULL);
371         modest_conf_set_string (priv->modest_conf, key,
372                                 null_means_empty (username), NULL);
373         g_free (key);
374
375         /* password */
376         if (password) {
377                 key = g_strconcat (acckey, "/", MODEST_ACCOUNT_PASSWORD,
378                                    NULL);
379                 modest_conf_set_string (priv->modest_conf, key,
380                                         null_means_empty (password), NULL);
381                 g_free (key);
382         }
383
384         /* proto */
385         key = g_strconcat (acckey, "/", MODEST_ACCOUNT_PROTO, NULL);
386         modest_conf_set_string (priv->modest_conf, key,
387                                 null_means_empty (proto), NULL);
388         g_free (key);
389         g_free (acckey);
390
391         return TRUE;            /* FIXME: better error checking */
392 }
393
394 gboolean
395 modest_account_mgr_remove_server_account (ModestAccountMgr * self,
396                                           const gchar * name, GError ** err)
397 {
398         ModestAccountMgrPrivate *priv;
399         gchar *acckey;
400         gboolean retval;
401
402         g_return_val_if_fail (self, FALSE);
403         g_return_val_if_fail (name, FALSE);
404
405         priv = MODEST_ACCOUNT_MGR_GET_PRIVATE (self);
406
407         acckey = g_strconcat (MODEST_SERVER_ACCOUNT_NAMESPACE, "/",
408                               name, NULL);
409
410         if (!modest_conf_key_exists (priv->modest_conf, acckey, NULL)) {
411                 g_warning ("server account %s does not exist exist", name);
412                 g_free (acckey);
413                 return FALSE;
414         }
415
416         retval = modest_conf_remove_key (priv->modest_conf, acckey, NULL);
417         g_free (acckey);
418
419         return retval;
420 }
421
422
423 /* strip the first /n/ character from each element */
424 /* caller must make sure all elements are strings with
425  * length >= n, and also that data can be freed.
426  */
427 static GSList *
428 strip_prefix_from_elements (GSList * lst, guint n)
429 {
430         GSList *cursor = lst;
431
432         while (cursor) {
433                 gchar *str = (gchar *) cursor->data;
434
435                 cursor->data = g_strdup (str + n);
436                 g_free (str);
437                 cursor = cursor->next;
438         }
439         return lst;
440 }
441
442
443 GSList *
444 modest_account_mgr_server_account_names (ModestAccountMgr * self,
445                                          const gchar * account_name,
446                                          ModestProtoType type,
447                                          const gchar * proto,
448                                          gboolean only_enabled)
449 {
450         GSList *accounts;
451         GSList *cursor;
452         ModestAccountMgrPrivate *priv;
453         const size_t prefix_len =
454                 strlen (MODEST_SERVER_ACCOUNT_NAMESPACE "/");
455
456         g_return_val_if_fail (self, NULL);
457
458         priv = MODEST_ACCOUNT_MGR_GET_PRIVATE (self);
459         accounts = modest_conf_list_subkeys (priv->modest_conf,
460                                              MODEST_SERVER_ACCOUNT_NAMESPACE,
461                                              NULL);
462
463         /* no restrictions, return everything */
464         if (type == MODEST_PROTO_TYPE_ANY && !proto)
465                 return strip_prefix_from_elements (accounts, prefix_len);
466
467         /* otherwise, filter out the none-matching ones */
468         cursor = accounts;
469         while (cursor) {
470                 gchar *keyspace, *proto_key, *acc_proto;
471
472                 keyspace = (gchar *) cursor->data;
473                 proto_key =
474                         g_strconcat (keyspace, "/", MODEST_ACCOUNT_PROTO,
475                                      NULL);
476                 acc_proto =
477                         modest_conf_get_string (priv->modest_conf, proto_key,
478                                                 NULL);
479                 g_free (proto_key);
480
481                 if ((!acc_proto) ||     /* proto not defined? */
482                     (type != MODEST_PROTO_TYPE_ANY &&   /* proto type ...     */
483                      modest_proto_type (acc_proto) != type) ||  /* ... matches?       */
484                     (proto && strcmp (proto, acc_proto) != 0)) {        /* proto matches?     */
485                         /* no match: remove from the list */
486                         GSList *nxt = cursor->next;
487
488                         g_free (acc_proto);
489                         accounts = g_slist_delete_link (accounts, cursor);
490                         cursor = nxt;
491                 } else
492                         cursor = cursor->next;
493         }
494
495         return strip_prefix_from_elements (accounts, prefix_len);
496 }
497
498
499 GSList *
500 modest_account_mgr_account_names (ModestAccountMgr * self, GError ** err)
501 {
502         GSList *accounts;
503         ModestAccountMgrPrivate *priv;
504         const size_t prefix_len = strlen (MODEST_ACCOUNT_NAMESPACE "/");
505
506
507         g_return_val_if_fail (self, NULL);
508
509         priv = MODEST_ACCOUNT_MGR_GET_PRIVATE (self);
510
511         accounts = modest_conf_list_subkeys (priv->modest_conf,
512                                              MODEST_ACCOUNT_NAMESPACE, err);
513         return strip_prefix_from_elements (accounts, prefix_len);
514 }
515
516
517 static gchar *
518 get_account_string (ModestAccountMgr * self, const gchar * name,
519                     const gchar * key, gboolean server_account, GError ** err) {
520
521         ModestAccountMgrPrivate *priv;
522
523         gchar *keyname;
524         gchar *retval;
525
526         g_return_val_if_fail (self, NULL);
527         g_return_val_if_fail (name, NULL);
528         g_return_val_if_fail (key, NULL);
529
530         if (server_account)
531                 keyname = get_server_account_keyname (name, key);
532         else
533                 keyname = get_account_keyname (name, key);
534
535         priv = MODEST_ACCOUNT_MGR_GET_PRIVATE (self);
536         retval = modest_conf_get_string (priv->modest_conf, keyname, err);
537         g_free (keyname);
538
539         return retval;
540 }
541
542
543 gchar *
544 modest_account_mgr_get_server_account_string (ModestAccountMgr * self,
545                                               const gchar * name,
546                                               const gchar * key,
547                                               GError ** err)
548 {
549         return get_account_string (self, name, key, TRUE, err);
550 }
551
552
553 gchar *
554 modest_account_mgr_get_account_string (ModestAccountMgr * self,
555                                        const gchar * name, const gchar * key,
556                                        GError ** err)
557 {
558         return get_account_string (self, name, key, FALSE, err);
559 }
560
561
562 static gint
563 get_account_int (ModestAccountMgr * self, const gchar * name,
564                  const gchar * key, gboolean server_account, GError ** err)
565 {
566         ModestAccountMgrPrivate *priv;
567
568         gchar *keyname;
569         gint retval;
570
571         g_return_val_if_fail (self, -1);
572         g_return_val_if_fail (name, -1);
573         g_return_val_if_fail (key, -1);
574
575         if (server_account)
576                 keyname = get_server_account_keyname (name, key);
577         else
578                 keyname = get_account_keyname (name, key);
579
580         priv = MODEST_ACCOUNT_MGR_GET_PRIVATE (self);
581         retval = modest_conf_get_int (priv->modest_conf, keyname, err);
582         g_free (keyname);
583
584         return retval;
585 }
586
587
588 gint
589 modest_account_mgr_get_server_account_int (ModestAccountMgr * self,
590                                            const gchar * name,
591                                            const gchar * key, GError ** err)
592 {
593         return get_account_int (self, name, key, TRUE, err);
594 }
595
596
597 gint
598 modest_account_mgr_get_account_int (ModestAccountMgr * self,
599                                     const gchar * name, const gchar * key,
600                                     GError ** err)
601 {
602         return get_account_int (self, name, key, FALSE, err);
603 }
604
605
606 static gboolean
607 get_account_bool (ModestAccountMgr * self, const gchar * name,
608                   const gchar * key, gboolean server_account, GError ** err)
609 {
610         ModestAccountMgrPrivate *priv;
611
612         gchar *keyname;
613         gboolean retval;
614
615         g_return_val_if_fail (self, FALSE);
616         g_return_val_if_fail (name, FALSE);
617         g_return_val_if_fail (key, FALSE);
618
619         if (server_account)
620                 keyname = get_server_account_keyname (name, key);
621         else
622                 keyname = get_account_keyname (name, key);
623
624         priv = MODEST_ACCOUNT_MGR_GET_PRIVATE (self);
625         retval = modest_conf_get_bool (priv->modest_conf, keyname, err);
626         g_free (keyname);
627
628         return retval;
629 }
630
631
632 gint
633 modest_account_mgr_get_server_account_bool (ModestAccountMgr * self,
634                                             const gchar * name,
635                                             const gchar * key, GError ** err)
636 {
637         return get_account_bool (self, name, key, TRUE, err);
638 }
639
640
641 gint
642 modest_account_mgr_get_account_bool (ModestAccountMgr * self,
643                                      const gchar * name, const gchar * key,
644                                      GError ** err)
645 {
646         return get_account_bool (self, name, key, FALSE, err);
647 }
648
649
650 static gboolean
651 set_account_string (ModestAccountMgr * self, const gchar * name,
652                     const gchar * key, const gchar * val,
653                     gboolean server_account, GError ** err)
654 {
655         ModestAccountMgrPrivate *priv;
656
657         gchar *keyname;
658         gboolean retval;
659
660         g_return_val_if_fail (self, FALSE);
661         g_return_val_if_fail (name, FALSE);
662         g_return_val_if_fail (key, FALSE);
663
664         if (server_account)
665                 keyname = get_server_account_keyname (name, key);
666         else
667                 keyname = get_account_keyname (name, key);
668
669         priv = MODEST_ACCOUNT_MGR_GET_PRIVATE (self);
670
671         retval = modest_conf_set_string (priv->modest_conf, keyname, val,
672                                          err);
673
674         g_free (keyname);
675         return retval;
676 }
677
678
679 gboolean
680 modest_account_mgr_set_server_account_string (ModestAccountMgr * self,
681                                               const gchar * name,
682                                               const gchar * key,
683                                               const gchar * val,
684                                               GError ** err)
685 {
686         return set_account_string (self, name, key, val, TRUE, err);
687 }
688
689
690 gboolean
691 modest_account_mgr_set_account_string (ModestAccountMgr * self,
692                                        const gchar * name, const gchar * key,
693                                        const gchar * val, GError ** err)
694 {
695         return set_account_string (self, name, key, val, FALSE, err);
696 }
697
698
699 static gboolean
700 set_account_int (ModestAccountMgr * self, const gchar * name,
701                  const gchar * key, gboolean server_account, int val,
702                  GError ** err)
703 {
704         ModestAccountMgrPrivate *priv;
705
706         gchar *keyname;
707         gboolean retval;
708
709         g_return_val_if_fail (self, FALSE);
710         g_return_val_if_fail (name, FALSE);
711         g_return_val_if_fail (key, FALSE);
712
713         if (server_account)
714                 keyname = get_server_account_keyname (name, key);
715         else
716                 keyname = get_account_keyname (name, key);
717
718         priv = MODEST_ACCOUNT_MGR_GET_PRIVATE (self);
719
720         retval = modest_conf_set_int (priv->modest_conf, keyname, val, err);
721
722         g_free (keyname);
723         return retval;
724 }
725
726
727 gboolean
728 modest_account_mgr_set_server_account_int (ModestAccountMgr * self,
729                                            const gchar * name,
730                                            const gchar * key, int val,
731                                            GError ** err)
732 {
733         return set_account_int (self, name, key, val, TRUE, err);
734 }
735
736
737 gboolean
738 modest_account_mgr_set_account_int (ModestAccountMgr * self,
739                                     const gchar * name, const gchar * key,
740                                     int val, GError ** err)
741 {
742         return set_account_int (self, name, key, val, FALSE, err);
743 }
744
745
746 static gboolean
747 set_account_bool (ModestAccountMgr * self, const gchar * name,
748                   const gchar * key, gboolean server_account, gboolean val,
749                   GError ** err)
750 {
751         ModestAccountMgrPrivate *priv;
752
753         gchar *keyname;
754         gboolean retval;
755
756         g_return_val_if_fail (self, FALSE);
757         g_return_val_if_fail (name, FALSE);
758         g_return_val_if_fail (key, FALSE);
759
760         if (server_account)
761                 keyname = get_server_account_keyname (name, key);
762         else
763                 keyname = get_account_keyname (name, key);
764
765         priv = MODEST_ACCOUNT_MGR_GET_PRIVATE (self);
766
767         retval = modest_conf_set_bool (priv->modest_conf, keyname, val, err);
768
769         g_free (keyname);
770         return retval;
771 }
772
773
774 gboolean
775 modest_account_mgr_set_server_account_bool (ModestAccountMgr * self,
776                                             const gchar * name,
777                                             const gchar * key, gboolean val,
778                                             GError ** err)
779 {
780         return set_account_bool (self, name, key, val, TRUE, err);
781 }
782
783
784 gboolean
785 modest_account_mgr_set_account_bool (ModestAccountMgr * self,
786                                      const gchar * name, const gchar * key,
787                                      gboolean val, GError ** err)
788 {
789         return set_account_bool (self, name, key, val, FALSE, err);
790 }
791
792
793 gboolean
794 account_exists (ModestAccountMgr * self, const gchar * name,
795                 gboolean server_account, GError ** err)
796 {
797         ModestAccountMgrPrivate *priv;
798
799         gchar *keyname;
800         gboolean retval;
801
802         g_return_val_if_fail (self, FALSE);
803         g_return_val_if_fail (name, FALSE);
804
805         if (server_account)
806                 keyname = get_server_account_keyname (name, NULL);
807         else
808                 keyname = get_account_keyname (name, NULL);
809
810         priv = MODEST_ACCOUNT_MGR_GET_PRIVATE (self);
811         retval = modest_conf_key_exists (priv->modest_conf, keyname, err);
812
813         g_free (keyname);
814         return retval;
815 }
816
817
818 gboolean
819 modest_account_mgr_server_account_exists (ModestAccountMgr * self,
820                                           const gchar * name, GError ** err)
821 {
822         return account_exists (self, name, TRUE, err);
823 }
824
825
826 gboolean
827 modest_account_mgr_account_exists (ModestAccountMgr * self,
828                                    const gchar * name, GError ** err)
829 {
830         return account_exists (self, name, FALSE, err);
831 }
832
833
834 /* must be freed by caller */
835 static gchar *
836 get_account_keyname (const gchar * accname, const gchar * name)
837 {
838         if (name)
839                 return g_strconcat
840                         (MODEST_ACCOUNT_NAMESPACE, "/",
841                          accname, "/", name, NULL);
842         else
843                 return g_strconcat
844                         (MODEST_ACCOUNT_NAMESPACE, "/", accname, NULL);
845 }
846
847
848 /* must be freed by caller */
849 static gchar *
850 get_server_account_keyname (const gchar * accname, const gchar * name)
851 {
852         if (name)
853                 return g_strconcat
854                         (MODEST_SERVER_ACCOUNT_NAMESPACE, "/",
855                          accname, "/", name, NULL);
856         else
857                 return g_strconcat
858                         (MODEST_SERVER_ACCOUNT_NAMESPACE, "/", accname, NULL);
859 }