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