* So, now I think I finally got all changes from Arne and myself together.
[modest] / src / modest-account-mgr.c
1 /* modest-account-mgr.c */
2
3 /* insert (c)/licensing information) */
4
5 #include <string.h>
6 #include "modest-account-mgr.h"
7
8 /* 'private'/'protected' functions */
9 static void    modest_account_mgr_class_init    (ModestAccountMgrClass *klass);
10 static void    modest_account_mgr_init          (ModestAccountMgr *obj);
11 static void    modest_account_mgr_finalize      (GObject *obj);
12
13 static gchar*   get_account_keyname (const gchar *accname, const gchar *name);
14 static gchar*   get_server_account_keyname (const gchar *accname, const gchar *name);
15
16 /* list my signals */
17 enum {
18         /* MY_SIGNAL_1, */
19         /* MY_SIGNAL_2, */
20         LAST_SIGNAL
21 };
22
23 typedef struct _ModestAccountMgrPrivate ModestAccountMgrPrivate;
24 struct _ModestAccountMgrPrivate {
25         ModestConf *modest_conf;
26 };
27 #define MODEST_ACCOUNT_MGR_GET_PRIVATE(o)      (G_TYPE_INSTANCE_GET_PRIVATE((o), \
28                                                 MODEST_TYPE_ACCOUNT_MGR, \
29                                                 ModestAccountMgrPrivate))
30 /* globals */
31 static GObjectClass *parent_class = NULL;
32
33 /* uncomment the following if you have defined any signals */
34 /* static guint signals[LAST_SIGNAL] = {0}; */
35
36 GType
37 modest_account_mgr_get_type (void)
38 {
39         static GType my_type = 0;
40         if (!my_type) {
41                 static const GTypeInfo my_info = {
42                         sizeof(ModestAccountMgrClass),
43                         NULL,           /* base init */
44                         NULL,           /* base finalize */
45                         (GClassInitFunc) modest_account_mgr_class_init,
46                         NULL,           /* class finalize */
47                         NULL,           /* class data */
48                         sizeof(ModestAccountMgr),
49                         1,              /* n_preallocs */
50                         (GInstanceInitFunc) modest_account_mgr_init,
51                 };
52
53                 my_type = g_type_register_static (G_TYPE_OBJECT,
54                                                   "ModestAccountMgr",
55                                                   &my_info, 0);
56         }
57         return my_type;
58 }
59
60 static void
61 modest_account_mgr_class_init (ModestAccountMgrClass *klass)
62 {
63         GObjectClass *gobject_class;
64         gobject_class = (GObjectClass*) klass;
65
66         parent_class            = g_type_class_peek_parent (klass);
67         gobject_class->finalize = modest_account_mgr_finalize;
68
69         g_type_class_add_private (gobject_class, sizeof(ModestAccountMgrPrivate));
70
71         /* signal definitions go here, e.g.: */
72 /*      signals[MY_SIGNAL_1] = */
73 /*              g_signal_new ("my_signal_1",....); */
74 /*      signals[MY_SIGNAL_2] = */
75 /*              g_signal_new ("my_signal_2",....); */
76 /*      etc. */
77 }
78
79
80 static void
81 modest_account_mgr_init (ModestAccountMgr *obj)
82 {
83         ModestAccountMgrPrivate *priv = MODEST_ACCOUNT_MGR_GET_PRIVATE(obj);
84         priv->modest_conf = NULL;
85 }
86
87 static void
88 modest_account_mgr_finalize (GObject *obj)
89 {
90         ModestAccountMgr *self = MODEST_ACCOUNT_MGR(obj);
91         ModestAccountMgrPrivate *priv = MODEST_ACCOUNT_MGR_GET_PRIVATE(self);
92
93         g_object_unref (G_OBJECT(priv->modest_conf));
94         priv->modest_conf = NULL;
95 }
96
97 GObject*
98 modest_account_mgr_new (ModestConf *conf)
99 {
100         GObject *obj;
101         ModestAccountMgrPrivate *priv;
102
103         g_return_val_if_fail (conf, NULL);
104
105         obj  = G_OBJECT(g_object_new(MODEST_TYPE_ACCOUNT_MGR, NULL));
106         priv = MODEST_ACCOUNT_MGR_GET_PRIVATE(obj);
107
108         /*
109          * increase the ref count on the modest_conf. Normally, the
110          * ModestConf should outlive the ModestAccountMgr though
111          */
112         g_object_ref(G_OBJECT(priv->modest_conf = conf));
113         return obj;
114 }
115
116
117
118 gboolean
119 modest_account_mgr_add_account (ModestAccountMgr *self, const gchar* name,
120                                 const gchar *store_account,
121                                 const gchar *transport_account,
122                                 GError **err)
123 {
124         ModestAccountMgrPrivate *priv;
125         gchar *key;
126         gboolean retval;
127
128         g_return_val_if_fail (self, FALSE);
129         g_return_val_if_fail (name, FALSE);
130
131         if (modest_account_mgr_account_exists (self, name, err)) {
132                 g_warning ("account already exists");
133                 //return FALSE;
134         }
135         /*
136          * we create the account by adding an account 'dir', with the name <name>,
137          * and in that the 'display_name' string key
138          */
139         priv = MODEST_ACCOUNT_MGR_GET_PRIVATE(self);
140
141         key = get_account_keyname (name, MODEST_ACCOUNT_DISPLAY_NAME);
142         modest_conf_set_string (priv->modest_conf, key, name, err);
143         g_free (key);
144
145         if (store_account) {
146                 key = get_account_keyname (name, MODEST_ACCOUNT_STORE_ACCOUNT);
147                 modest_conf_set_string (priv->modest_conf, key, store_account, err);
148                 g_free (key);
149         }
150
151         if (transport_account) {
152                 key = get_account_keyname (name, MODEST_ACCOUNT_TRANSPORT_ACCOUNT);
153                 modest_conf_set_string (priv->modest_conf, key, transport_account, err);
154                 g_free (key);
155         }
156
157         return TRUE; /* TODO: error handling */
158 }
159
160
161 gboolean
162 modest_account_mgr_remove_account (ModestAccountMgr *self, const gchar* name,
163                            GError **err)
164 {
165         ModestAccountMgrPrivate *priv;
166         gchar *key;
167         gboolean retval;
168
169         g_return_val_if_fail (self, FALSE);
170         g_return_val_if_fail (name, FALSE);
171
172         if (!modest_account_mgr_account_exists (self, name, err)) {
173                 g_warning ("account doest not exist");
174                 return FALSE;
175         }
176
177         priv = MODEST_ACCOUNT_MGR_GET_PRIVATE(self);
178         key = get_account_keyname (name, NULL);
179
180         retval = modest_conf_remove_key (priv->modest_conf, key, NULL);
181
182         g_free (key);
183         return retval;
184 }
185
186
187 static const gchar*
188 null_means_empty(const gchar* str)
189 {
190         return str ? str : "";
191 }
192
193
194 gboolean
195 modest_account_mgr_add_server_account    (ModestAccountMgr *self,
196                                           const gchar *name,
197                                           const gchar *hostname,
198                                           const gchar *username,
199                                           const gchar *password,
200                                           const gchar *proto)
201 {
202         ModestAccountMgrPrivate *priv;
203         gchar *acckey, *key;
204
205         g_return_val_if_fail (self, FALSE);
206         g_return_val_if_fail (name, FALSE);
207
208         /* TODO: check already exists */
209
210         priv = MODEST_ACCOUNT_MGR_GET_PRIVATE(self);
211         acckey = g_strconcat (MODEST_SERVER_ACCOUNT_NAMESPACE, "/",
212                               name, NULL);
213
214         if (modest_conf_key_exists(priv->modest_conf, acckey, NULL)) {
215                 g_warning ("server account %s already exists", name);
216                 g_free (acckey);
217                 return FALSE;
218         }
219
220         /* hostname */
221         key = g_strconcat (acckey, "/", MODEST_ACCOUNT_HOSTNAME, NULL);
222         modest_conf_set_string (priv->modest_conf, key,
223                                 null_means_empty(hostname), NULL);
224         g_free (key);
225
226         /* username */
227         key = g_strconcat (acckey, "/", MODEST_ACCOUNT_USERNAME, NULL);
228         modest_conf_set_string (priv->modest_conf, key,
229                                 null_means_empty(username), NULL);
230         g_free (key);
231
232         /* password */
233         if (password)
234         {
235                 key = g_strconcat (acckey, "/", MODEST_ACCOUNT_PASSWORD, NULL);
236                 modest_conf_set_string (priv->modest_conf, key,
237                                         null_means_empty(password), NULL);
238                 g_free (key);
239         }
240
241         /* proto */
242         key = g_strconcat (acckey, "/", MODEST_ACCOUNT_PROTO, NULL);
243         modest_conf_set_string (priv->modest_conf, key,
244                                 null_means_empty(proto),
245                                 NULL);
246         g_free (key);
247
248         return TRUE; /* FIXME: better error checking */
249 }
250
251 gboolean
252 modest_account_mgr_remove_server_account    (ModestAccountMgr *self,
253                                              const gchar *name,
254                                              GError **err)
255 {
256         ModestAccountMgrPrivate *priv;
257         gchar *acckey, *key;
258         gboolean retval;
259
260         g_return_val_if_fail (self, FALSE);
261         g_return_val_if_fail (name, FALSE);
262
263         priv = MODEST_ACCOUNT_MGR_GET_PRIVATE(self);
264
265         acckey = g_strconcat (MODEST_SERVER_ACCOUNT_NAMESPACE, "/",
266                               name, NULL);
267
268         if (!modest_conf_key_exists(priv->modest_conf, acckey, NULL)) {
269                 g_warning ("server account %s does not exist exist", name);
270                 g_free (acckey);
271                 return FALSE;
272         }
273
274         retval = modest_conf_remove_key (priv->modest_conf, acckey, NULL);
275         g_free (acckey);
276
277         return retval;
278 }
279
280
281 /* strip the first /n/ character from each element */
282 /* caller must make sure all elements are strings with
283  * length >= n, and also that data can be freed.
284  */
285 static GSList*
286 strip_prefix_from_elements (GSList *lst, guint n)
287 {
288         GSList *cursor = lst;
289         while (cursor) {
290                 gchar *str = (gchar*)cursor->data;
291                 cursor->data = g_strdup (str + n);
292                 g_free (str);
293                 cursor = cursor->next;
294         }
295         return lst;
296 }
297
298
299
300 GSList*
301 modest_account_mgr_server_account_names   (ModestAccountMgr *self,
302                                            const gchar*    account_name,
303                                            ModestProtoType type,
304                                            const gchar*    proto,
305                                            gboolean only_enabled)
306 {
307         GSList *accounts;
308         GSList *cursor;
309         ModestAccountMgrPrivate *priv;
310         const size_t prefix_len =
311                 strlen (MODEST_SERVER_ACCOUNT_NAMESPACE "/");
312
313         g_return_val_if_fail (self, NULL);
314
315         priv = MODEST_ACCOUNT_MGR_GET_PRIVATE(self);
316         accounts = modest_conf_list_subkeys (priv->modest_conf,
317                                              MODEST_SERVER_ACCOUNT_NAMESPACE,
318                                              NULL);
319
320         /* no restrictions, return everything */
321         if (type == MODEST_PROTO_TYPE_ANY && !proto)
322                 return strip_prefix_from_elements (accounts,prefix_len);
323
324         /* otherwise, filter out the none-matching ones */
325         cursor = accounts;
326         while (cursor) {
327                 gchar *keyspace, *proto_key, *acc_proto;
328
329                 keyspace  = (gchar*) cursor->data;
330                 proto_key = g_strconcat (keyspace, "/", MODEST_ACCOUNT_PROTO, NULL);
331                 acc_proto = modest_conf_get_string (priv->modest_conf, proto_key,
332                                                     NULL);
333                 g_free (proto_key);
334
335                 if ((!acc_proto) ||                              /* proto not defined? */
336                     (type != MODEST_PROTO_TYPE_ANY &&            /* proto type ...     */
337                      modest_proto_type (acc_proto) != type) ||   /* ... matches?       */
338                     (proto && strcmp(proto,acc_proto) != 0)) {   /* proto matches?     */
339                         /* no match: remove from the list */
340                         GSList *nxt = cursor->next;
341                         g_free (acc_proto);
342                         accounts = g_slist_delete_link (accounts, cursor);
343                         cursor = nxt;
344                 } else
345                         cursor = cursor->next;
346         }
347
348         return strip_prefix_from_elements (accounts, prefix_len);
349 }
350
351
352
353 GSList*
354 modest_account_mgr_account_names  (ModestAccountMgr *self, GError **err)
355 {
356         GSList *accounts, *cursor;
357         ModestAccountMgrPrivate *priv;
358         const size_t prefix_len =
359                 strlen (MODEST_ACCOUNT_NAMESPACE "/");
360
361
362         g_return_val_if_fail (self, NULL);
363
364         priv = MODEST_ACCOUNT_MGR_GET_PRIVATE(self);
365
366         accounts = modest_conf_list_subkeys (priv->modest_conf,
367                                              MODEST_ACCOUNT_NAMESPACE,
368                                              err);
369         return strip_prefix_from_elements (accounts, prefix_len);
370 }
371
372
373
374 static gchar*
375 get_account_string (ModestAccountMgr *self, const gchar *name,
376                     const gchar *key, gboolean server_account,
377                     GError **err)
378 {
379         ModestAccountMgrPrivate *priv;
380
381         gchar *keyname;
382         gchar * retval;
383
384         g_return_val_if_fail (self, NULL);
385         g_return_val_if_fail (name, NULL);
386         g_return_val_if_fail (key, NULL);
387
388         if (server_account)
389                 keyname = get_server_account_keyname (name, key);
390         else
391                 keyname = get_account_keyname (name, key);
392
393         priv = MODEST_ACCOUNT_MGR_GET_PRIVATE(self);
394         retval = modest_conf_get_string (priv->modest_conf,keyname,err);
395         g_free (keyname);
396
397         return retval;
398 }
399
400
401 gchar*
402 modest_account_mgr_get_server_account_string (ModestAccountMgr *self, const gchar *name,
403                                            const gchar *key, GError **err)
404 {
405         return get_account_string (self, name, key, TRUE, err);
406 }
407
408 gchar*
409 modest_account_mgr_get_account_string (ModestAccountMgr *self, const gchar *name,
410                                     const gchar *key, GError **err)
411 {
412         return get_account_string (self, name, key, FALSE, err);
413 }
414
415
416
417 static gint
418 get_account_int (ModestAccountMgr *self, const gchar *name,
419                  const gchar *key, gboolean server_account,
420                  GError **err)
421 {
422         ModestAccountMgrPrivate *priv;
423
424         gchar *keyname;
425         gint retval;
426
427         g_return_val_if_fail (self, -1);
428         g_return_val_if_fail (name, -1);
429         g_return_val_if_fail (key, -1);
430
431         if (server_account)
432                 keyname = get_server_account_keyname (name, key);
433         else
434                 keyname = get_account_keyname (name, key);
435
436         priv = MODEST_ACCOUNT_MGR_GET_PRIVATE(self);
437         retval = modest_conf_get_int (priv->modest_conf,keyname,err);
438         g_free (keyname);
439
440         return retval;
441 }
442
443
444 gint
445 modest_account_mgr_get_server_account_int (ModestAccountMgr *self, const gchar *name,
446                                            const gchar *key, GError **err)
447 {
448         return get_account_int (self, name, key, TRUE, err);
449 }
450
451 gint
452 modest_account_mgr_get_account_int (ModestAccountMgr *self, const gchar *name,
453                                     const gchar *key, GError **err)
454 {
455         return get_account_int (self, name, key, FALSE, err);
456 }
457
458
459
460 static gboolean
461 get_account_bool (ModestAccountMgr *self, const gchar *name,
462                   const gchar *key, gboolean server_account,
463                   GError **err)
464 {
465         ModestAccountMgrPrivate *priv;
466
467         gchar *keyname;
468         gboolean retval;
469
470         g_return_val_if_fail (self, -1);
471         g_return_val_if_fail (name, -1);
472         g_return_val_if_fail (key, -1);
473
474         if (server_account)
475                 keyname = get_server_account_keyname (name, key);
476         else
477                 keyname = get_account_keyname (name, key);
478
479         priv = MODEST_ACCOUNT_MGR_GET_PRIVATE(self);
480         retval = modest_conf_get_int (priv->modest_conf,keyname,err);
481         g_free (keyname);
482
483         return retval;
484 }
485
486
487
488 gint
489 modest_account_mgr_get_server_account_bool (ModestAccountMgr *self, const gchar *name,
490                                            const gchar *key, GError **err)
491 {
492         return get_account_bool (self, name, key, TRUE, err);
493 }
494
495 gint
496 modest_account_mgr_get_account_bool (ModestAccountMgr *self, const gchar *name,
497                                     const gchar *key, GError **err)
498 {
499         return get_account_bool (self, name, key, FALSE, err);
500 }
501
502
503
504
505
506 static gboolean
507 set_account_string  (ModestAccountMgr *self, const gchar *name,
508                      const gchar *key, const gchar* val, gboolean server_account,
509                      GError **err)
510 {
511         ModestAccountMgrPrivate *priv;
512
513         gchar *keyname;
514         gboolean retval;
515
516         g_return_val_if_fail (self, FALSE);
517         g_return_val_if_fail (name, FALSE);
518         g_return_val_if_fail (key, FALSE);
519
520         if (server_account)
521                 keyname = get_server_account_keyname (name, key);
522         else
523                 keyname = get_account_keyname (name, key);
524
525         priv = MODEST_ACCOUNT_MGR_GET_PRIVATE(self);
526
527         retval = modest_conf_set_string (priv->modest_conf,keyname,val,err);
528
529         g_free (keyname);
530         return retval;
531 }
532
533
534
535
536
537 gboolean
538 modest_account_mgr_set_server_account_string  (ModestAccountMgr *self, const gchar *name,
539                                                const gchar *key, const gchar* val,
540                                                GError **err)
541 {
542         return set_account_string (self, name, key, val, TRUE, err);
543 }
544
545
546
547 gboolean
548 modest_account_mgr_set_account_string  (ModestAccountMgr *self, const gchar *name,
549                                         const gchar *key, const gchar* val,
550                                         GError **err)
551 {
552         return set_account_string (self, name, key, val, FALSE, err);
553 }
554
555
556 static gboolean
557 set_account_int  (ModestAccountMgr *self, const gchar *name,
558                   const gchar *key, gboolean server_account, int val,
559                   GError **err)
560 {
561         ModestAccountMgrPrivate *priv;
562
563         gchar *keyname;
564         gboolean retval;
565
566         g_return_val_if_fail (self, FALSE);
567         g_return_val_if_fail (name, FALSE);
568         g_return_val_if_fail (key, FALSE);
569
570         if (server_account)
571                 keyname = get_server_account_keyname (name, key);
572         else
573                 keyname = get_account_keyname (name, key);
574
575         priv = MODEST_ACCOUNT_MGR_GET_PRIVATE(self);
576
577         retval = modest_conf_set_int (priv->modest_conf,keyname,val,err);
578
579         g_free (keyname);
580         return retval;
581 }
582
583
584
585 gboolean
586 modest_account_mgr_set_server_account_int (ModestAccountMgr *self, const gchar *name,
587                                            const gchar *key, int val,
588                                            GError **err)
589 {
590         return set_account_int (self, name, key, val, TRUE, err);
591 }
592
593
594 gboolean
595 modest_account_mgr_set_account_int  (ModestAccountMgr *self, const gchar *name,
596                                      const gchar *key, int val,
597                                      GError **err)
598 {
599         return set_account_int (self, name, key, val, FALSE, err);
600 }
601
602
603
604
605 static gboolean
606 set_account_bool  (ModestAccountMgr *self, const gchar *name,
607                    const gchar *key, gboolean server_account, gboolean val,
608                    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
626         retval = modest_conf_set_bool (priv->modest_conf,keyname,val,err);
627
628         g_free (keyname);
629         return retval;
630 }
631
632
633 gboolean
634 modest_account_mgr_set_server_account_bool  (ModestAccountMgr *self, const gchar *name,
635                                              const gchar *key, gboolean val,
636                                              GError **err)
637 {
638         return set_account_bool (self, name, key, val, TRUE, err);
639 }
640
641
642
643 gboolean
644 modest_account_mgr_set_account_bool  (ModestAccountMgr *self, const gchar *name,
645                                         const gchar *key, gboolean val,
646                                         GError **err)
647 {
648         return set_account_bool (self, name, key, val, FALSE, err);
649 }
650
651
652
653
654
655 gboolean
656 account_exists (ModestAccountMgr *self, const gchar *name, gboolean server_account,
657                 GError **err)
658 {
659         ModestAccountMgrPrivate *priv;
660
661         gchar *keyname;
662         gboolean retval;
663
664         g_return_val_if_fail (self, FALSE);
665         g_return_val_if_fail (name, FALSE);
666
667         if (server_account)
668                 keyname = get_account_keyname (name, NULL);
669         else
670                 keyname = get_server_account_keyname (name, NULL);
671
672         priv = MODEST_ACCOUNT_MGR_GET_PRIVATE(self);
673         retval = modest_conf_key_exists (priv->modest_conf,keyname,err);
674
675         g_free (keyname);
676         return retval;
677 }
678
679
680 gboolean
681 modest_account_mgr_server_account_exists (ModestAccountMgr *self, const gchar *name,
682                                    GError **err)
683 {
684         return account_exists (self, name, TRUE, err);
685 }
686
687
688
689 gboolean
690 modest_account_mgr_account_exists (ModestAccountMgr *self, const gchar *name,
691                                    GError **err)
692 {
693         return account_exists (self, name, FALSE, err);
694 }
695
696
697
698 /* must be freed by caller */
699 static gchar*
700 get_account_keyname (const gchar *accname, const gchar *name)
701 {
702         if (name)
703                 return g_strconcat
704                         (MODEST_ACCOUNT_NAMESPACE, "/",
705                          accname, "/", name, NULL);
706         else
707                 return g_strconcat
708                         (MODEST_ACCOUNT_NAMESPACE, "/",
709                          accname, NULL);
710 }
711
712
713 /* must be freed by caller */
714 static gchar*
715 get_server_account_keyname (const gchar *accname, const gchar *name)
716 {
717         if (name)
718                 return g_strconcat
719                         (MODEST_SERVER_ACCOUNT_NAMESPACE, "/",
720                          accname, "/", name, NULL);
721         else
722                 return g_strconcat
723                         (MODEST_SERVER_ACCOUNT_NAMESPACE, "/",
724                          accname, NULL);
725 }