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