* added function to register password_request method with modest_tny_account_store
[modest] / src / modest-tny-account-store.c
1 /* modest-tny-account-store.c */
2
3 /* insert (c)/licensing information) */
4
5 #include <string.h>
6
7 #include <tny-account-iface.h>
8 #include <tny-account-store-iface.h>
9 #include <tny-store-account-iface.h>
10 #include <tny-transport-account-iface.h>
11 #include <tny-device-iface.h>
12 #include <tny-device.h>
13 #include <tny-account-store.h>
14
15 #include <tny-store-account.h>
16 #include <tny-transport-account.h>
17
18 #include "modest-account-mgr.h"
19 #include "modest-tny-account-store.h"
20
21 /* 'private'/'protected' functions */
22 static void modest_tny_account_store_class_init   (ModestTnyAccountStoreClass *klass);
23 static void modest_tny_account_store_init         (ModestTnyAccountStore *obj);
24 static void modest_tny_account_store_finalize     (GObject *obj);
25
26 /* implementations for tny-account-store-iface */
27 static void    modest_tny_account_store_iface_init              (gpointer g_iface, gpointer iface_data);
28
29 static void    modest_tny_account_store_add_store_account       (TnyAccountStoreIface *self,
30                                                                TnyStoreAccountIface *account);
31 static void    modest_tny_account_store_add_transport_account   (TnyAccountStoreIface *self,
32                                                                        TnyTransportAccountIface *account);
33 static const GList*  modest_tny_account_store_get_store_accounts      (TnyAccountStoreIface *iface);
34 static const GList*  modest_tny_account_store_get_transport_accounts  (TnyAccountStoreIface *iface);
35
36 /* list my signals */
37 enum {
38         PASSWORD_REQUESTED_SIGNAL,
39         LAST_SIGNAL
40 };
41
42 /* Password Status */
43 enum {
44         PW_NOT_INVALID,
45         PW_INVALID
46 };
47
48 static const gchar *transport_protocols[] = { "smtp", NULL };
49
50 typedef struct _ModestTnyAccountStorePrivate ModestTnyAccountStorePrivate;
51 struct _ModestTnyAccountStorePrivate {
52
53         GMutex *store_lock;
54         GMutex *transport_lock;
55         GList *store_accounts;
56         GList *transport_accounts;
57         gchar *cache_dir;
58
59         TnySessionCamel *tny_session_camel;
60         TnyDeviceIface  *device;
61
62         ModestAccountMgr *modest_acc_mgr;
63         gint pw_invalid;
64         ModestTnyGetPassFunc get_pass_func;
65 };
66 #define MODEST_TNY_ACCOUNT_STORE_GET_PRIVATE(o)      (G_TYPE_INSTANCE_GET_PRIVATE((o), \
67                                                       MODEST_TYPE_TNY_ACCOUNT_STORE, \
68                                                       ModestTnyAccountStorePrivate))
69 /* globals */
70 static GObjectClass *parent_class = NULL;
71
72 static guint signals[LAST_SIGNAL] = {0};
73
74 GType
75 modest_tny_account_store_get_type (void)
76 {
77         static GType my_type = 0;
78         if (!my_type) {
79                 static const GTypeInfo my_info = {
80                         sizeof(ModestTnyAccountStoreClass),
81                         NULL,           /* base init */
82                         NULL,           /* base finalize */
83                         (GClassInitFunc) modest_tny_account_store_class_init,
84                         NULL,           /* class finalize */
85                         NULL,           /* class data */
86                         sizeof(ModestTnyAccountStore),
87                         1,              /* n_preallocs */
88                         (GInstanceInitFunc) modest_tny_account_store_init,
89                 };
90
91                 static const GInterfaceInfo iface_info = {
92                         (GInterfaceInitFunc) modest_tny_account_store_iface_init,
93                         NULL,         /* interface_finalize */
94                         NULL          /* interface_data */
95                 };
96                 /* hack hack */
97                 my_type = g_type_register_static (TNY_TYPE_ACCOUNT_STORE,
98                                                   "ModestTnyAccountStore", &my_info, 0);
99
100                 g_type_add_interface_static (my_type, TNY_TYPE_ACCOUNT_STORE_IFACE,
101                                              &iface_info);
102         }
103         return my_type;
104 }
105
106 static void
107 modest_tny_account_store_class_init (ModestTnyAccountStoreClass *klass)
108 {
109         GObjectClass *gobject_class;
110         gobject_class = (GObjectClass*) klass;
111
112         parent_class            = g_type_class_peek_parent (klass);
113         gobject_class->finalize = modest_tny_account_store_finalize;
114
115         g_type_class_add_private (gobject_class,
116                                   sizeof(ModestTnyAccountStorePrivate));
117
118         signals[PASSWORD_REQUESTED_SIGNAL] =
119                 g_signal_new ("password_requested",
120                               G_TYPE_FROM_CLASS (gobject_class),
121                               G_SIGNAL_RUN_FIRST,
122                               G_STRUCT_OFFSET(ModestTnyAccountStoreClass, password_requested),
123                               NULL, NULL,
124                               g_cclosure_marshal_VOID__POINTER,
125                               G_TYPE_NONE, 1, G_TYPE_POINTER);
126 }
127
128 static void
129 modest_tny_account_store_init (ModestTnyAccountStore *obj)
130 {
131         ModestTnyAccountStorePrivate *priv =
132                 MODEST_TNY_ACCOUNT_STORE_GET_PRIVATE(obj);
133
134         priv->modest_acc_mgr         = NULL;
135         priv->device                 = NULL;
136
137         priv->store_lock             = NULL;
138         priv->transport_lock         = NULL;
139         priv->store_accounts         = NULL;
140         priv->transport_accounts     = NULL;
141         priv->cache_dir              = NULL;
142
143         priv->tny_session_camel      = NULL;
144         /* Meaning: if not indicated otherwise, we have valid password data */
145         priv->pw_invalid             = PW_NOT_INVALID;
146         priv->get_pass_func          = NULL;
147 }
148
149
150 static void
151 free_gobject (GObject *obj, gpointer user_data)
152 {
153         if (obj)
154                 g_object_unref (obj);
155 }
156
157
158 static GList*
159 free_gobject_list (GList *list)
160 {
161         if (list) {
162                 g_list_foreach (list, (GFunc)free_gobject, NULL);
163                 g_list_free (list);
164         }
165         return NULL;
166 }
167
168 static gchar*
169 get_password (TnyAccountIface *account,
170               const gchar *prompt,
171               gboolean *cancel) {
172
173         const gchar *key;
174         const TnyAccountStoreIface *account_store;
175         ModestTnyAccountStore *self;
176         ModestTnyAccountStorePrivate *priv;
177         gchar *retval;
178
179         g_return_val_if_fail (account, NULL);
180
181         key = tny_account_iface_get_id (account);
182         account_store = tny_account_iface_get_account_store(account);
183
184         self = MODEST_TNY_ACCOUNT_STORE (account_store);
185         priv = MODEST_TNY_ACCOUNT_STORE_GET_PRIVATE(self);
186
187         if (priv->pw_invalid==PW_NOT_INVALID) {
188                 retval = modest_account_mgr_get_server_account_string (priv->modest_acc_mgr,
189                                                                        key,
190                                                                        MODEST_ACCOUNT_PASSWORD,
191                                                                        NULL);
192         } else {
193                 retval = priv->get_pass_func(account, prompt, cancel);
194                 if (!*cancel)
195                 {
196                         priv->pw_invalid=PW_NOT_INVALID;
197                         modest_account_mgr_set_server_account_string(priv->modest_acc_mgr,
198                                                                      key,
199                                                                      MODEST_ACCOUNT_PASSWORD,
200                                                                      retval,
201                                                                      NULL);
202                 }
203         }
204         return retval;
205 }
206
207
208 static void
209 forget_password (TnyAccountIface *account) {
210
211         ModestTnyAccountStore *self;
212         ModestTnyAccountStorePrivate *priv;
213         const TnyAccountStoreIface *account_store;
214
215         account_store = tny_account_iface_get_account_store(account);
216         self = MODEST_TNY_ACCOUNT_STORE (account_store);
217         priv = MODEST_TNY_ACCOUNT_STORE_GET_PRIVATE(self);
218
219         priv->pw_invalid=PW_INVALID;
220 }
221
222
223 static TnyAccountIface*
224 tny_account_from_key (ModestTnyAccountStore *self, const gchar *key,
225                       gboolean is_store)
226 {
227         TnyAccountIface *tny_account;
228         ModestTnyAccountStorePrivate *priv;
229         gchar *val;
230
231         g_return_val_if_fail (self, NULL);
232         g_return_val_if_fail (key, NULL);
233
234         priv = MODEST_TNY_ACCOUNT_STORE_GET_PRIVATE(self);
235
236         /* is it a store or a transport? */
237         if (is_store)
238                 tny_account = TNY_ACCOUNT_IFACE(tny_store_account_new ());
239         else
240                 tny_account = TNY_ACCOUNT_IFACE(tny_transport_account_new ());
241
242         if (!tny_account) {
243                 g_warning ("failed to create new tny %s account",
244                            is_store ? "store" : "transport");
245                 return NULL;
246         }
247
248         tny_account_iface_set_account_store (TNY_ACCOUNT_IFACE(tny_account),
249                                              TNY_ACCOUNT_STORE_IFACE(self));
250         /* id */
251         tny_account_iface_set_id (tny_account, key);
252         tny_account_iface_set_name (tny_account, key);
253
254         /* proto */
255         val = modest_account_mgr_get_server_account_string (priv->modest_acc_mgr, key,
256                                                             MODEST_ACCOUNT_PROTO, NULL);
257         if (val) {
258                 tny_account_iface_set_proto (tny_account, val);
259                 g_free (val);
260         } else {
261                 g_warning ("protocol not defined for %s", key);
262                 g_object_unref (G_OBJECT(tny_account));
263                 return NULL;
264         }
265
266         /* hostname */
267         val = modest_account_mgr_get_server_account_string (priv->modest_acc_mgr, key,
268                                                             MODEST_ACCOUNT_HOSTNAME,
269                                                             NULL);
270         if (val) {
271                 tny_account_iface_set_hostname (tny_account, val);
272                 g_free (val);
273         }
274
275
276         /* username */
277         val = modest_account_mgr_get_server_account_string (priv->modest_acc_mgr, key,
278                                                             MODEST_ACCOUNT_USERNAME,
279                                                             NULL);
280         if (val) {
281                 tny_account_iface_set_user (tny_account, val);
282                 g_free (val);
283         }
284
285         tny_account_iface_set_pass_func (tny_account, get_password);
286         tny_account_iface_set_forget_pass_func (tny_account, forget_password);
287
288         return tny_account;
289 }
290
291
292 static GList*
293 tny_accounts_from_server_accounts (ModestTnyAccountStore *self, GSList *accounts,
294                                    gboolean is_store)
295 {
296         GSList *cursor = accounts;
297         GList *tny_accounts = NULL;
298
299         g_return_val_if_fail (self, NULL);
300
301         while (cursor) {
302                 TnyAccountIface *tny_account;
303                 tny_account = tny_account_from_key (self, (gchar*)cursor->data,
304                                                     is_store);
305                 if (!tny_account) {
306                         g_warning ("could not create tnyaccount for %s",
307                                    (gchar*)cursor->data);
308                 } else {
309                         tny_accounts =
310                                 g_list_append (tny_accounts, tny_account);
311                 }
312                 cursor = cursor->next;
313         }
314
315         return tny_accounts;
316 }
317
318
319 static void
320 manager_new_account (ModestAccountMgr *modest_acc_mgr, gchar *name, gpointer data)
321 {
322         ModestTnyAccountStore *self = data;
323         ModestTnyAccountStorePrivate *priv = MODEST_TNY_ACCOUNT_STORE_GET_PRIVATE(self);
324         TnyAccountIface *new_account;
325         gchar *proto;
326         gint i = 0;
327         gboolean is_store = TRUE;
328
329         g_print ("new account signal %s\n", name);
330
331         proto = modest_account_mgr_get_server_account_string (priv->modest_acc_mgr, name,
332                                                             MODEST_ACCOUNT_PROTO, NULL);
333         if (!proto) {
334                 g_printerr ("Cannot add account: unknown type.");
335                 return;
336         }
337
338         while (transport_protocols [i]) {
339                 if (!strcmp (transport_protocols [i], proto)) {
340                         is_store = FALSE;
341                         break;
342                 }
343                 i++;
344         }
345
346         /* fill account lists */
347         if (!priv->store_accounts)
348                 modest_tny_account_store_get_store_accounts (TNY_ACCOUNT_STORE_IFACE(self));
349         if (!priv->transport_accounts)
350                 modest_tny_account_store_get_transport_accounts (TNY_ACCOUNT_STORE_IFACE(self));
351
352
353         if (is_store) {
354                         new_account = tny_account_from_key (self, name, is_store);
355                         g_mutex_lock (priv->store_lock);
356                         priv->store_accounts = g_list_append (priv->store_accounts, new_account);
357                         g_mutex_unlock (priv->store_lock);
358         } else {
359                         new_account = tny_account_from_key (self, name, is_store);
360                         g_mutex_lock (priv->transport_lock);
361                         priv->transport_accounts = g_list_append (priv->transport_accounts, new_account);
362                         g_mutex_unlock (priv->transport_lock);
363         }
364         g_signal_emit (self,
365                 tny_account_store_iface_signals [TNY_ACCOUNT_STORE_IFACE_ACCOUNT_INSERTED], 0, new_account);
366 }
367
368
369 static void
370 manager_remove_account (ModestAccountMgr *modest_acc_mgr, gchar *name, gpointer data)
371 {
372         g_print ("remove account signal %s\n", name);
373 }
374
375
376 static void
377 manager_change_account (ModestAccountMgr *modest_acc_mgr, gchar *accountname,
378         gchar *key, gchar* value, gpointer data)
379 {
380         ModestTnyAccountStore *self = data;
381         ModestTnyAccountStorePrivate *priv = MODEST_TNY_ACCOUNT_STORE_GET_PRIVATE(self);
382         GList *iter;
383         TnyAccountIface *account = NULL;
384
385         g_print ("account change signal: account: %s key: %s value: %s\n", accountname, key, value);
386
387         /* fill account lists */
388         if (!priv->store_accounts)
389                 modest_tny_account_store_get_store_accounts (TNY_ACCOUNT_STORE_IFACE(self));
390         if (!priv->transport_accounts)
391                 modest_tny_account_store_get_transport_accounts (TNY_ACCOUNT_STORE_IFACE(self));
392
393         for (iter = priv->store_accounts; iter; iter = iter->next) {
394                 TnyAccountIface *acc = iter->data;
395                 if (!strcmp (tny_account_iface_get_name (acc), accountname)) {
396                         account = acc;
397                         break;
398                 }
399         }
400
401         if (!account)
402                 for (iter = priv->transport_accounts; iter; iter = iter->next) {
403                         TnyAccountIface *acc = iter->data;
404                         if (!strcmp (tny_account_iface_get_name (acc), accountname)) {
405                                 account = acc;
406                                 break;
407                         }
408                 }
409
410         if (!account) {
411                 g_printerr ("Couldn't find account - returning without applying changes.");
412                 return;
413         }
414
415         g_mutex_lock (priv->store_lock);
416         g_mutex_lock (priv->transport_lock);
417
418         if (!strcmp (key, MODEST_ACCOUNT_HOSTNAME))
419                 tny_account_iface_set_hostname (account, value);
420         if (!strcmp (key, MODEST_ACCOUNT_USERNAME))
421                 tny_account_iface_set_user (account, value);
422
423         g_mutex_unlock (priv->transport_lock);
424         g_mutex_unlock (priv->store_lock);
425
426         /* TODO: handle protocol and password changes */
427         g_signal_emit (self,
428                 tny_account_store_iface_signals [TNY_ACCOUNT_STORE_IFACE_ACCOUNTS_RELOADED], 0);
429 }
430
431
432 static void
433 modest_tny_account_store_finalize (GObject *obj)
434 {
435         ModestTnyAccountStore *self = MODEST_TNY_ACCOUNT_STORE(obj);
436         ModestTnyAccountStorePrivate *priv =
437                 MODEST_TNY_ACCOUNT_STORE_GET_PRIVATE(self);
438
439         g_signal_handlers_disconnect_by_func (G_OBJECT (priv->modest_acc_mgr),
440                 G_CALLBACK(manager_new_account), NULL);
441         g_signal_handlers_disconnect_by_func (G_OBJECT (priv->modest_acc_mgr),
442                 G_CALLBACK(manager_remove_account), NULL);
443         g_signal_handlers_disconnect_by_func (G_OBJECT (priv->modest_acc_mgr),
444                 G_CALLBACK(manager_change_account), NULL);
445
446         if (priv->modest_acc_mgr) {
447                 g_object_unref (G_OBJECT(priv->modest_acc_mgr));
448                 priv->modest_acc_mgr = NULL;
449         }
450
451         if (priv->tny_session_camel) {
452                 g_object_unref (G_OBJECT(priv->tny_session_camel));
453                 priv->tny_session_camel = NULL;
454         }
455
456         if (priv->device) {
457                 g_object_unref (G_OBJECT(priv->device));
458                 priv->device = NULL;
459         }
460
461         g_mutex_lock (priv->store_lock);
462         priv->store_accounts     = free_gobject_list (priv->store_accounts);
463         g_mutex_unlock (priv->store_lock);
464
465         g_mutex_lock (priv->transport_lock);
466         priv->transport_accounts = free_gobject_list (priv->store_accounts);
467         g_mutex_unlock (priv->transport_lock);
468
469
470         g_mutex_free (priv->store_lock);
471         g_mutex_free (priv->transport_lock);
472
473         g_free (priv->cache_dir);
474         priv->cache_dir = NULL;
475
476 }
477
478
479 GObject*
480 modest_tny_account_store_new (ModestAccountMgr *modest_acc_mgr) {
481
482         GObject *obj;
483         ModestTnyAccountStorePrivate *priv;
484
485         g_return_val_if_fail (modest_acc_mgr, NULL);
486
487         obj  = G_OBJECT(g_object_new(MODEST_TYPE_TNY_ACCOUNT_STORE, NULL));
488
489         priv = MODEST_TNY_ACCOUNT_STORE_GET_PRIVATE(obj);
490
491         g_object_ref(G_OBJECT(modest_acc_mgr));
492         priv->modest_acc_mgr = modest_acc_mgr;
493
494         priv->store_lock = g_mutex_new ();
495         priv->transport_lock = g_mutex_new ();
496
497         priv->device = (TnyDeviceIface*)tny_device_new();
498         if (!priv->device) {
499                 g_warning ("Cannot create Device instance");
500                 g_object_unref (obj);
501                 return NULL;
502         }
503         priv->tny_session_camel = tny_session_camel_new
504                 (TNY_ACCOUNT_STORE_IFACE(obj));
505         if (!priv->tny_session_camel) {
506                 g_warning ("Cannot create TnySessionCamel instance");
507                 g_object_unref (obj);
508                 return NULL;
509         }
510
511         g_signal_connect (G_OBJECT (modest_acc_mgr), "account-add",
512                 G_CALLBACK(manager_new_account), obj);
513         g_signal_connect (G_OBJECT (modest_acc_mgr), "account-remove",
514                 G_CALLBACK(manager_remove_account), obj);
515         g_signal_connect (G_OBJECT (modest_acc_mgr), "account-change",
516                 G_CALLBACK(manager_change_account), obj);
517
518         return obj;
519 }
520
521
522 static gboolean
523 add_account  (TnyAccountStoreIface *self, TnyAccountIface *account) {
524
525         TnyAccountIface       *account_iface;
526         ModestTnyAccountStore *account_store;
527         ModestTnyAccountStorePrivate *priv;
528
529         const gchar *account_name;
530         const gchar *hostname, *username, *proto;
531
532         g_return_val_if_fail (self, FALSE);
533         g_return_val_if_fail (account, FALSE);
534
535         account_iface  = TNY_ACCOUNT_IFACE(account);
536         account_store  = MODEST_TNY_ACCOUNT_STORE(self);
537         priv           = MODEST_TNY_ACCOUNT_STORE_GET_PRIVATE(self);
538
539         account_name   = tny_account_iface_get_id(account_iface);
540         if (!account_name) {
541                 g_warning ("failed to retrieve account name");
542                 return FALSE;
543         }
544
545         hostname =  tny_account_iface_get_hostname(account_iface);
546         username =  tny_account_iface_get_user(account_iface);
547         proto    =  tny_account_iface_get_proto(account_iface);
548
549         return modest_account_mgr_add_server_account (priv->modest_acc_mgr,
550                                                       account_name,
551                                                       hostname, username, NULL,
552                                                       proto);
553 }
554
555
556 static void
557 modest_tny_account_store_add_store_account  (TnyAccountStoreIface *self,
558                                              TnyStoreAccountIface *account)
559 {
560         if (!add_account (self, TNY_ACCOUNT_IFACE(account)))
561                 g_warning ("failed to add store account");
562 }
563
564
565 static void
566 modest_tny_account_store_add_transport_account  (TnyAccountStoreIface *self,
567                                                  TnyTransportAccountIface *account)
568 {
569         if (!add_account (self, TNY_ACCOUNT_IFACE(account)))
570                 g_warning ("failed to add transport account");
571 }
572
573
574 static const GList*
575 modest_tny_account_store_get_store_accounts  (TnyAccountStoreIface *iface)
576 {
577         ModestTnyAccountStore        *self;
578         ModestTnyAccountStorePrivate *priv;
579         GSList                       *accounts;
580
581         g_return_val_if_fail (iface, NULL);
582
583         self = MODEST_TNY_ACCOUNT_STORE(iface);
584         priv = MODEST_TNY_ACCOUNT_STORE_GET_PRIVATE(self);
585
586         if (!priv->store_accounts) {
587                 accounts =
588                         modest_account_mgr_server_account_names (priv->modest_acc_mgr,
589                                                                  NULL,
590                                                                  MODEST_PROTO_TYPE_STORE,
591                                                                  NULL, FALSE);
592
593                 g_mutex_lock (priv->store_lock);
594                 priv->store_accounts = tny_accounts_from_server_accounts (self, accounts, TRUE);
595                 g_mutex_unlock (priv->store_lock);
596                 g_slist_free (accounts);
597         }
598
599         return priv->store_accounts;
600 }
601
602
603 static const GList*
604 modest_tny_account_store_get_transport_accounts (TnyAccountStoreIface *iface)
605 {
606         ModestTnyAccountStore        *self;
607         ModestTnyAccountStorePrivate *priv;
608         GSList                       *accounts;
609
610         g_return_val_if_fail (iface, NULL);
611
612         self = MODEST_TNY_ACCOUNT_STORE(iface);
613         priv = MODEST_TNY_ACCOUNT_STORE_GET_PRIVATE(self);
614
615
616         if (!priv->transport_accounts) {
617                 accounts =
618                         modest_account_mgr_server_account_names (priv->modest_acc_mgr,
619                                                                  NULL,
620                                                                  MODEST_PROTO_TYPE_TRANSPORT,
621                                                                  NULL, FALSE);
622                 g_mutex_lock (priv->transport_lock);
623                 priv->transport_accounts = tny_accounts_from_server_accounts (self, accounts, FALSE);
624                 g_mutex_unlock (priv->transport_lock);
625                 g_slist_free (accounts);
626         }
627
628
629         return priv->transport_accounts;
630 }
631
632
633 ModestAccountMgr
634 *modest_tny_account_store_get_accout_mgr(ModestTnyAccountStore *self)
635 {
636         ModestTnyAccountStorePrivate *priv;
637         g_return_val_if_fail (self, NULL);
638
639         priv = MODEST_TNY_ACCOUNT_STORE_GET_PRIVATE(self);
640
641         return priv->modest_acc_mgr;
642 }
643
644
645 TnySessionCamel*
646 tny_account_store_get_session (TnyAccountStore *self)
647 {
648         ModestTnyAccountStorePrivate *priv;
649         g_return_val_if_fail (self, NULL);
650
651         priv = MODEST_TNY_ACCOUNT_STORE_GET_PRIVATE(self);
652
653         return priv->tny_session_camel;
654 }
655
656
657 /**
658  * modest_tny_account_store_get_cache_dir:
659  * @self: self a TnyAccountStoreIface instance
660  *
661  * returns the pathname of the cache directory
662  *
663  * Returns: a string with the value of the pathname
664  * to the cache directory or NULL if the environment variable $HOME is
665  * not set. string should _not_ be freed by caller
666  */
667 static const gchar*
668 modest_tny_account_store_get_cache_dir (TnyAccountStoreIface *self)
669 {
670         ModestTnyAccountStorePrivate *priv;
671         priv = MODEST_TNY_ACCOUNT_STORE_GET_PRIVATE(self);
672
673         if (!priv->cache_dir) {
674                 if (g_getenv("HOME") != NULL)
675                         priv->cache_dir = g_strconcat(g_getenv("HOME"),
676                                                       "/.modest/cache/", NULL);
677         }
678         return priv->cache_dir;
679 }
680
681
682 static const TnyDeviceIface*
683 modest_tny_account_store_get_device (TnyAccountStoreIface *self)
684 {
685         ModestTnyAccountStorePrivate *priv;
686
687         priv = MODEST_TNY_ACCOUNT_STORE_GET_PRIVATE (self);
688
689         return priv->device;
690 }
691
692
693 static void
694 modest_tny_account_store_iface_init (gpointer g_iface, gpointer iface_data)
695 {
696         TnyAccountStoreIfaceClass *klass;
697
698         g_return_if_fail (g_iface);
699
700         klass = (TnyAccountStoreIfaceClass *)g_iface;
701
702         klass->add_store_account_func      =
703                 modest_tny_account_store_add_store_account;
704         klass->get_store_accounts_func     =
705                 modest_tny_account_store_get_store_accounts;
706         klass->add_transport_account_func  =
707                 modest_tny_account_store_add_transport_account;
708         klass->get_transport_accounts_func =
709                 modest_tny_account_store_get_transport_accounts;
710         klass->get_cache_dir_func =
711                 modest_tny_account_store_get_cache_dir;
712         klass->get_device_func =
713                 modest_tny_account_store_get_device;
714 }
715
716 void
717 modest_tny_account_store_set_get_pass_func (ModestTnyAccountStore *self, ModestTnyGetPassFunc func) {
718
719         ModestTnyAccountStorePrivate *priv = MODEST_TNY_ACCOUNT_STORE_GET_PRIVATE(self);
720
721         priv->get_pass_func=func;
722 }
723