1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2 /*
3 * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
4 *
5 * This library is free software: you can redistribute it and/or modify it
6 * under the terms of the GNU Lesser General Public License as published by
7 * the Free Software Foundation.
8 *
9 * This library is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
12 * for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public License
15 * along with this library. If not, see <http://www.gnu.org/licenses/>.
16 *
17 * Authors: Michael Zucchi <notzed@ximian.com>
18 */
19
20 #include "evolution-data-server-config.h"
21
22 #include <errno.h>
23 #include <stdio.h>
24 #include <string.h>
25 #include <unistd.h>
26 #include <sys/stat.h>
27
28 #include <glib/gi18n-lib.h>
29 #include <glib/gstdio.h>
30
31 #include "camel-local-folder.h"
32 #include "camel-local-store.h"
33
34 #define d(x)
35
36 struct _CamelLocalStorePrivate {
37 gboolean need_summary_check;
38 };
39
40 enum {
41 PROP_0,
42 PROP_NEED_SUMMARY_CHECK
43 };
44
G_DEFINE_TYPE_WITH_PRIVATE(CamelLocalStore,camel_local_store,CAMEL_TYPE_STORE)45 G_DEFINE_TYPE_WITH_PRIVATE (CamelLocalStore, camel_local_store, CAMEL_TYPE_STORE)
46
47 static gint
48 xrename (const gchar *oldp,
49 const gchar *newp,
50 const gchar *prefix,
51 const gchar *suffix,
52 gint missingok,
53 GError **error)
54 {
55 gchar *old, *new;
56 gchar *basename;
57 gint ret = -1;
58 gint err = 0;
59
60 basename = g_strconcat (oldp, suffix, NULL);
61 old = g_build_filename (prefix, basename, NULL);
62 g_free (basename);
63
64 basename = g_strconcat (newp, suffix, NULL);
65 new = g_build_filename (prefix, basename, NULL);
66 g_free (basename);
67
68 d (printf ("renaming %s%s to %s%s\n", oldp, suffix, newp, suffix));
69
70 if (g_rename (old, new) == -1 &&
71 !(errno == ENOENT && missingok)) {
72 err = errno;
73 ret = -1;
74 } else {
75 ret = 0;
76 }
77
78 if (ret == -1) {
79 g_set_error (
80 error, G_IO_ERROR,
81 g_io_error_from_errno (err),
82 _("Could not rename folder %s to %s: %s"),
83 old, new, g_strerror (err));
84 }
85
86 g_free (old);
87 g_free (new);
88 return ret;
89 }
90
91 static void
local_store_set_property(GObject * object,guint property_id,const GValue * value,GParamSpec * pspec)92 local_store_set_property (GObject *object,
93 guint property_id,
94 const GValue *value,
95 GParamSpec *pspec)
96 {
97 switch (property_id) {
98 case PROP_NEED_SUMMARY_CHECK:
99 camel_local_store_set_need_summary_check (
100 CAMEL_LOCAL_STORE (object),
101 g_value_get_boolean (value));
102 return;
103 }
104
105 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
106 }
107
108 static void
local_store_get_property(GObject * object,guint property_id,GValue * value,GParamSpec * pspec)109 local_store_get_property (GObject *object,
110 guint property_id,
111 GValue *value,
112 GParamSpec *pspec)
113 {
114 switch (property_id) {
115 case PROP_NEED_SUMMARY_CHECK:
116 g_value_set_boolean (
117 value,
118 camel_local_store_get_need_summary_check (
119 CAMEL_LOCAL_STORE (object)));
120 return;
121 }
122
123 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
124 }
125
126 static void
local_store_constructed(GObject * object)127 local_store_constructed (GObject *object)
128 {
129 CamelLocalStore *local_store;
130 CamelService *service;
131 const gchar *uid;
132
133 local_store = CAMEL_LOCAL_STORE (object);
134
135 /* Chain up to parent's constructed() method. */
136 G_OBJECT_CLASS (camel_local_store_parent_class)->constructed (object);
137
138 service = CAMEL_SERVICE (object);
139 uid = camel_service_get_uid (service);
140
141 /* XXX This is Evolution-specific policy. */
142 local_store->is_main_store = (g_strcmp0 (uid, "local") == 0);
143 }
144
145 static gchar *
local_store_get_name(CamelService * service,gboolean brief)146 local_store_get_name (CamelService *service,
147 gboolean brief)
148 {
149 CamelLocalSettings *local_settings;
150 CamelSettings *settings;
151 gchar *path;
152 gchar *name;
153
154 settings = camel_service_ref_settings (service);
155
156 local_settings = CAMEL_LOCAL_SETTINGS (settings);
157 path = camel_local_settings_dup_path (local_settings);
158
159 g_object_unref (settings);
160
161 if (brief)
162 name = g_strdup (path);
163 else
164 name = g_strdup_printf (_("Local mail file %s"), path);
165
166 g_free (path);
167
168 return name;
169 }
170
171 static gboolean
local_store_can_refresh_folder(CamelStore * store,CamelFolderInfo * info,GError ** error)172 local_store_can_refresh_folder (CamelStore *store,
173 CamelFolderInfo *info,
174 GError **error)
175 {
176 /* any local folder can be refreshed */
177 return TRUE;
178 }
179
180 static CamelFolder *
local_store_get_folder_sync(CamelStore * store,const gchar * folder_name,CamelStoreGetFolderFlags flags,GCancellable * cancellable,GError ** error)181 local_store_get_folder_sync (CamelStore *store,
182 const gchar *folder_name,
183 CamelStoreGetFolderFlags flags,
184 GCancellable *cancellable,
185 GError **error)
186 {
187 CamelLocalSettings *local_settings;
188 CamelSettings *settings;
189 CamelService *service;
190 CamelFolder *folder = NULL;
191 struct stat st;
192 gchar *path;
193
194 service = CAMEL_SERVICE (store);
195
196 settings= camel_service_ref_settings (service);
197
198 local_settings = CAMEL_LOCAL_SETTINGS (settings);
199 path = camel_local_settings_dup_path (local_settings);
200
201 g_object_unref (settings);
202
203 if (!g_path_is_absolute (path)) {
204 g_set_error (
205 error, CAMEL_STORE_ERROR,
206 CAMEL_STORE_ERROR_NO_FOLDER,
207 _("Store root %s is not an absolute path"), path);
208 goto exit;
209 }
210
211 if (g_stat (path, &st) == 0) {
212 if (!S_ISDIR (st.st_mode)) {
213 g_set_error (
214 error, CAMEL_STORE_ERROR,
215 CAMEL_STORE_ERROR_NO_FOLDER,
216 _("Store root %s is not a regular directory"), path);
217 return NULL;
218 }
219 folder = (CamelFolder *) 0xdeadbeef;
220 goto exit;
221 }
222
223 if (errno != ENOENT
224 || (flags & CAMEL_STORE_FOLDER_CREATE) == 0) {
225 g_set_error (
226 error, G_IO_ERROR,
227 g_io_error_from_errno (errno),
228 _("Cannot get folder: %s: %s"),
229 path, g_strerror (errno));
230 goto exit;
231 }
232
233 /* need to create the dir heirarchy */
234 if (g_mkdir_with_parents (path, 0700) == -1 && errno != EEXIST) {
235 g_set_error (
236 error, G_IO_ERROR,
237 g_io_error_from_errno (errno),
238 _("Cannot get folder: %s: %s"),
239 path, g_strerror (errno));
240 goto exit;
241 }
242
243 folder = (CamelFolder *) 0xdeadbeef;
244
245 exit:
246 g_free (path);
247
248 return folder;
249 }
250
251 static CamelFolderInfo *
local_store_get_folder_info_sync(CamelStore * store,const gchar * top,CamelStoreGetFolderInfoFlags flags,GCancellable * cancellable,GError ** error)252 local_store_get_folder_info_sync (CamelStore *store,
253 const gchar *top,
254 CamelStoreGetFolderInfoFlags flags,
255 GCancellable *cancellable,
256 GError **error)
257 {
258 /* FIXME: This is broken, but it corresponds to what was
259 * there before.
260 */
261
262 d (printf ("-- LOCAL STORE -- get folder info: %s\n", top));
263
264 return NULL;
265 }
266
267 static CamelFolder *
local_store_get_inbox_folder_sync(CamelStore * store,GCancellable * cancellable,GError ** error)268 local_store_get_inbox_folder_sync (CamelStore *store,
269 GCancellable *cancellable,
270 GError **error)
271 {
272 g_set_error (
273 error, CAMEL_STORE_ERROR,
274 CAMEL_STORE_ERROR_NO_FOLDER,
275 _("Local stores do not have an inbox"));
276
277 return NULL;
278 }
279
280 static CamelFolder *
local_store_get_junk_folder_sync(CamelStore * store,GCancellable * cancellable,GError ** error)281 local_store_get_junk_folder_sync (CamelStore *store,
282 GCancellable *cancellable,
283 GError **error)
284 {
285 CamelFolder *folder;
286
287 /* Chain up to parent's get_junk_folder_sync() method. */
288 folder = CAMEL_STORE_CLASS (camel_local_store_parent_class)->
289 get_junk_folder_sync (store, cancellable, error);
290
291 if (folder) {
292 CamelObject *object = CAMEL_OBJECT (folder);
293 gchar *state;
294
295 state = camel_local_store_get_meta_path (
296 CAMEL_LOCAL_STORE (store),
297 CAMEL_VJUNK_NAME, ".cmeta");
298 camel_object_set_state_filename (object, state);
299 g_free (state);
300
301 /* no defaults? */
302 camel_object_state_read (object);
303 }
304
305 return folder;
306 }
307
308 static CamelFolder *
local_store_get_trash_folder_sync(CamelStore * store,GCancellable * cancellable,GError ** error)309 local_store_get_trash_folder_sync (CamelStore *store,
310 GCancellable *cancellable,
311 GError **error)
312 {
313 CamelFolder *folder;
314
315 /* Chain up to parent's get_trash_folder_sync() method. */
316 folder = CAMEL_STORE_CLASS (camel_local_store_parent_class)->
317 get_trash_folder_sync (store, cancellable, error);
318
319 if (folder) {
320 CamelObject *object = CAMEL_OBJECT (folder);
321 gchar *state;
322
323 state = camel_local_store_get_meta_path (
324 CAMEL_LOCAL_STORE (store),
325 CAMEL_VTRASH_NAME, ".cmeta");
326 camel_object_set_state_filename (object, state);
327 g_free (state);
328
329 /* no defaults? */
330 camel_object_state_read (object);
331 }
332
333 return folder;
334 }
335
336 static CamelFolderInfo *
local_store_create_folder_sync(CamelStore * store,const gchar * parent_name,const gchar * folder_name,GCancellable * cancellable,GError ** error)337 local_store_create_folder_sync (CamelStore *store,
338 const gchar *parent_name,
339 const gchar *folder_name,
340 GCancellable *cancellable,
341 GError **error)
342 {
343 CamelLocalSettings *local_settings;
344 CamelSettings *settings;
345 CamelService *service;
346 CamelFolder *folder;
347 CamelFolderInfo *info = NULL;
348 gchar *name = NULL;
349 gchar *path;
350 struct stat st;
351
352 service = CAMEL_SERVICE (store);
353
354 settings = camel_service_ref_settings (service);
355
356 local_settings = CAMEL_LOCAL_SETTINGS (settings);
357 path = camel_local_settings_dup_path (local_settings);
358
359 g_object_unref (settings);
360
361 /* This is a pretty hacky version of create folder, but should basically work */
362
363 if (!g_path_is_absolute (path)) {
364 g_set_error (
365 error, CAMEL_STORE_ERROR,
366 CAMEL_STORE_ERROR_NO_FOLDER,
367 _("Store root %s is not an absolute path"), path);
368 goto exit;
369 }
370
371 if (parent_name && *parent_name)
372 name = g_strdup_printf ("%s/%s/%s", path, parent_name, folder_name);
373 else
374 name = g_strdup_printf ("%s/%s", path, folder_name);
375
376 if (g_stat (name, &st) == 0 || errno != ENOENT) {
377 g_set_error (
378 error, G_IO_ERROR,
379 g_io_error_from_errno (errno),
380 _("Cannot get folder: %s: %s"),
381 name, g_strerror (errno));
382 goto exit;
383 }
384
385 g_free (name);
386
387 if (parent_name && *parent_name)
388 name = g_strdup_printf ("%s/%s", parent_name, folder_name);
389 else
390 name = g_strdup_printf ("%s", folder_name);
391
392 folder = CAMEL_STORE_GET_CLASS (store)->get_folder_sync (
393 store, name, CAMEL_STORE_FOLDER_CREATE, cancellable, error);
394 if (folder) {
395 g_object_unref (folder);
396 info = CAMEL_STORE_GET_CLASS (store)->get_folder_info_sync (
397 store, name, 0, cancellable, error);
398 }
399
400 exit:
401 g_free (name);
402 g_free (path);
403
404 return info;
405 }
406
407 /* default implementation, only delete metadata */
408 static gboolean
local_store_delete_folder_sync(CamelStore * store,const gchar * folder_name,GCancellable * cancellable,GError ** error)409 local_store_delete_folder_sync (CamelStore *store,
410 const gchar *folder_name,
411 GCancellable *cancellable,
412 GError **error)
413 {
414 CamelLocalSettings *local_settings;
415 CamelSettings *settings;
416 CamelService *service;
417 CamelFolderInfo *fi;
418 CamelFolder *lf;
419 gchar *str = NULL;
420 gchar *name;
421 gchar *path;
422 gboolean success = TRUE;
423
424 service = CAMEL_SERVICE (store);
425
426 settings = camel_service_ref_settings (service);
427
428 local_settings = CAMEL_LOCAL_SETTINGS (settings);
429 path = camel_local_settings_dup_path (local_settings);
430
431 g_object_unref (settings);
432
433 /* remove metadata only */
434 name = g_build_filename (path, folder_name, NULL);
435 str = g_strdup_printf ("%s.ibex", name);
436 if (camel_text_index_remove (str) == -1 && errno != ENOENT && errno != ENOTDIR) {
437 g_set_error (
438 error, G_IO_ERROR,
439 g_io_error_from_errno (errno),
440 _("Could not delete folder index file “%s”: %s"),
441 str, g_strerror (errno));
442 success = FALSE;
443 goto exit;
444 }
445
446 g_free (str);
447 str = NULL;
448
449 if ((lf = camel_store_get_folder_sync (store, folder_name, 0, cancellable, NULL))) {
450 CamelObject *object = CAMEL_OBJECT (lf);
451 const gchar *state_filename;
452
453 state_filename = camel_object_get_state_filename (object);
454 str = g_strdup (state_filename);
455
456 camel_object_set_state_filename (object, NULL);
457
458 g_object_unref (lf);
459 }
460
461 if (str == NULL)
462 str = g_strdup_printf ("%s.cmeta", name);
463
464 if (g_unlink (str) == -1 && errno != ENOENT && errno != ENOTDIR) {
465 g_set_error (
466 error, G_IO_ERROR,
467 g_io_error_from_errno (errno),
468 _("Could not delete folder meta file “%s”: %s"),
469 str, g_strerror (errno));
470 success = FALSE;
471 goto exit;
472 }
473
474 fi = camel_folder_info_new ();
475 fi->full_name = g_strdup (folder_name);
476 fi->display_name = g_path_get_basename (folder_name);
477 fi->unread = -1;
478
479 camel_store_folder_deleted (store, fi);
480 camel_folder_info_free (fi);
481
482 exit:
483 g_free (name);
484 g_free (path);
485 g_free (str);
486
487 return success;
488 }
489
490 /* default implementation, rename all */
491 static gboolean
local_store_rename_folder_sync(CamelStore * store,const gchar * old,const gchar * new,GCancellable * cancellable,GError ** error)492 local_store_rename_folder_sync (CamelStore *store,
493 const gchar *old,
494 const gchar *new,
495 GCancellable *cancellable,
496 GError **error)
497 {
498 CamelLocalFolder *folder;
499 CamelLocalSettings *local_settings;
500 CamelSettings *settings;
501 CamelService *service;
502 gchar *old_basename;
503 gchar *new_basename;
504 gchar *newibex;
505 gchar *oldibex;
506 gchar *path;
507 gboolean success = TRUE;
508
509 service = CAMEL_SERVICE (store);
510
511 settings = camel_service_ref_settings (service);
512
513 local_settings = CAMEL_LOCAL_SETTINGS (settings);
514 path = camel_local_settings_dup_path (local_settings);
515
516 g_object_unref (settings);
517
518 old_basename = g_strdup_printf ("%s.ibex", old);
519 new_basename = g_strdup_printf ("%s.ibex", new);
520
521 oldibex = g_build_filename (path, old_basename, NULL);
522 newibex = g_build_filename (path, new_basename, NULL);
523
524 g_free (old_basename);
525 g_free (new_basename);
526
527 /* try to rollback failures, has obvious races */
528
529 d (printf ("local rename folder '%s' '%s'\n", old, new));
530
531 folder = camel_object_bag_get (camel_store_get_folders_bag (store), old);
532 if (folder && folder->index) {
533 if (camel_index_rename (folder->index, newibex) == -1)
534 goto ibex_failed;
535 } else {
536 /* TODO camel_text_index_rename() should find
537 * out if we have an active index itself? */
538 if (camel_text_index_rename (oldibex, newibex) == -1)
539 goto ibex_failed;
540 }
541
542 if (xrename (old, new, path, ".ev-summary", TRUE, error))
543 goto summary_failed;
544
545 if (xrename (old, new, path, ".ev-summary-meta", TRUE, error))
546 goto summary_failed;
547
548 if (xrename (old, new, path, ".cmeta", TRUE, error))
549 goto cmeta_failed;
550
551 if (xrename (old, new, path, "", FALSE, error))
552 goto base_failed;
553
554 g_free (newibex);
555 g_free (oldibex);
556
557 if (folder)
558 g_object_unref (folder);
559
560 goto exit;
561
562 /* The (f)utility of this recovery effort is quesitonable */
563
564 base_failed:
565 xrename (new, old, path, ".cmeta", TRUE, NULL);
566
567 cmeta_failed:
568 xrename (new, old, path, ".ev-summary", TRUE, NULL);
569 xrename (new, old, path, ".ev-summary-meta", TRUE, NULL);
570 summary_failed:
571 if (folder) {
572 if (folder->index)
573 camel_index_rename (folder->index, oldibex);
574 } else
575 camel_text_index_rename (newibex, oldibex);
576 ibex_failed:
577 if (error && !*error)
578 g_set_error (
579 error, G_IO_ERROR,
580 g_io_error_from_errno (errno),
581 _("Could not rename “%s”: %s"),
582 old, g_strerror (errno));
583
584 g_free (newibex);
585 g_free (oldibex);
586
587 if (folder)
588 g_object_unref (folder);
589
590 success = FALSE;
591
592 exit:
593 g_free (path);
594
595 return success;
596 }
597
598 static gchar *
local_store_get_full_path(CamelLocalStore * ls,const gchar * full_name)599 local_store_get_full_path (CamelLocalStore *ls,
600 const gchar *full_name)
601 {
602 CamelLocalSettings *local_settings;
603 CamelSettings *settings;
604 CamelService *service;
605 gchar *filename;
606 gchar *path;
607
608 service = CAMEL_SERVICE (ls);
609
610 settings = camel_service_ref_settings (service);
611
612 local_settings = CAMEL_LOCAL_SETTINGS (settings);
613 path = camel_local_settings_dup_path (local_settings);
614
615 g_object_unref (settings);
616
617 filename = g_build_filename (path, full_name, NULL);
618
619 g_free (path);
620
621 return filename;
622 }
623
624 static gchar *
local_store_get_meta_path(CamelLocalStore * ls,const gchar * full_name,const gchar * ext)625 local_store_get_meta_path (CamelLocalStore *ls,
626 const gchar *full_name,
627 const gchar *ext)
628 {
629 CamelLocalSettings *local_settings;
630 CamelSettings *settings;
631 CamelService *service;
632 gchar *basename;
633 gchar *filename;
634 gchar *path;
635
636 service = CAMEL_SERVICE (ls);
637
638 settings = camel_service_ref_settings (service);
639
640 local_settings = CAMEL_LOCAL_SETTINGS (settings);
641 path = camel_local_settings_dup_path (local_settings);
642
643 g_object_unref (settings);
644
645 basename = g_strconcat (full_name, ext, NULL);
646 filename = g_build_filename (path, basename, NULL);
647 g_free (basename);
648
649 g_free (path);
650
651 return filename;
652 }
653
654 static void
camel_local_store_class_init(CamelLocalStoreClass * class)655 camel_local_store_class_init (CamelLocalStoreClass *class)
656 {
657 GObjectClass *object_class;
658 CamelServiceClass *service_class;
659 CamelStoreClass *store_class;
660
661 object_class = G_OBJECT_CLASS (class);
662 object_class->set_property = local_store_set_property;
663 object_class->get_property = local_store_get_property;
664 object_class->constructed = local_store_constructed;
665
666 service_class = CAMEL_SERVICE_CLASS (class);
667 service_class->settings_type = CAMEL_TYPE_LOCAL_SETTINGS;
668 service_class->get_name = local_store_get_name;
669
670 store_class = CAMEL_STORE_CLASS (class);
671 store_class->can_refresh_folder = local_store_can_refresh_folder;
672 store_class->get_folder_sync = local_store_get_folder_sync;
673 store_class->get_folder_info_sync = local_store_get_folder_info_sync;
674 store_class->get_inbox_folder_sync = local_store_get_inbox_folder_sync;
675 store_class->get_junk_folder_sync = local_store_get_junk_folder_sync;
676 store_class->get_trash_folder_sync = local_store_get_trash_folder_sync;
677 store_class->create_folder_sync = local_store_create_folder_sync;
678 store_class->delete_folder_sync = local_store_delete_folder_sync;
679 store_class->rename_folder_sync = local_store_rename_folder_sync;
680
681 class->get_full_path = local_store_get_full_path;
682 class->get_meta_path = local_store_get_meta_path;
683
684 g_object_class_install_property (
685 object_class,
686 PROP_NEED_SUMMARY_CHECK,
687 g_param_spec_boolean (
688 "need-summary-check",
689 "Need Summary Check",
690 "Whether to check for unexpected file changes",
691 TRUE,
692 G_PARAM_READWRITE |
693 G_PARAM_CONSTRUCT |
694 G_PARAM_EXPLICIT_NOTIFY |
695 G_PARAM_STATIC_STRINGS));
696 }
697
698 static void
camel_local_store_init(CamelLocalStore * local_store)699 camel_local_store_init (CamelLocalStore *local_store)
700 {
701 local_store->priv = camel_local_store_get_instance_private (local_store);
702 }
703
704 /* Returns whether is this store used as 'On This Computer' main store */
705 gboolean
camel_local_store_is_main_store(CamelLocalStore * store)706 camel_local_store_is_main_store (CamelLocalStore *store)
707 {
708 g_return_val_if_fail (store != NULL, FALSE);
709
710 return store->is_main_store;
711 }
712
713 gchar *
camel_local_store_get_full_path(CamelLocalStore * store,const gchar * full_name)714 camel_local_store_get_full_path (CamelLocalStore *store,
715 const gchar *full_name)
716 {
717 CamelLocalStoreClass *class;
718
719 g_return_val_if_fail (CAMEL_IS_LOCAL_STORE (store), NULL);
720 /* XXX Guard against full_name == NULL? */
721
722 class = CAMEL_LOCAL_STORE_GET_CLASS (store);
723 g_return_val_if_fail (class != NULL, NULL);
724 g_return_val_if_fail (class->get_full_path != NULL, NULL);
725
726 return class->get_full_path (store, full_name);
727 }
728
729 gchar *
camel_local_store_get_meta_path(CamelLocalStore * store,const gchar * full_name,const gchar * ext)730 camel_local_store_get_meta_path (CamelLocalStore *store,
731 const gchar *full_name,
732 const gchar *ext)
733 {
734 CamelLocalStoreClass *class;
735
736 g_return_val_if_fail (CAMEL_IS_LOCAL_STORE (store), NULL);
737 /* XXX Guard against full_name == NULL? */
738 /* XXX Guard against ext == NULL? */
739
740 class = CAMEL_LOCAL_STORE_GET_CLASS (store);
741 g_return_val_if_fail (class != NULL, NULL);
742 g_return_val_if_fail (class->get_meta_path != NULL, NULL);
743
744 return class->get_meta_path (store, full_name, ext);
745 }
746
747 guint32
camel_local_store_get_folder_type_by_full_name(CamelLocalStore * store,const gchar * full_name)748 camel_local_store_get_folder_type_by_full_name (CamelLocalStore *store,
749 const gchar *full_name)
750 {
751 g_return_val_if_fail (store != NULL, 0);
752 g_return_val_if_fail (full_name != NULL, 0);
753
754 if (!camel_local_store_is_main_store (store))
755 return CAMEL_FOLDER_TYPE_NORMAL;
756
757 if (g_ascii_strcasecmp (full_name, "Inbox") == 0)
758 return CAMEL_FOLDER_TYPE_INBOX;
759 else if (g_ascii_strcasecmp (full_name, "Outbox") == 0)
760 return CAMEL_FOLDER_TYPE_OUTBOX;
761 else if (g_ascii_strcasecmp (full_name, "Sent") == 0)
762 return CAMEL_FOLDER_TYPE_SENT;
763
764 return CAMEL_FOLDER_TYPE_NORMAL;
765 }
766
767 /**
768 * camel_local_store_get_need_summary_check:
769 * @store: a #CamelLocalStore
770 *
771 * Returns whether local mail files for @store should be check for
772 * consistency and the summary database synchronized with them. This
773 * is necessary to handle another mail application altering the files,
774 * such as local mail delivery using fetchmail.
775 *
776 * Returns: whether to check for changes in local mail files
777 *
778 * Since: 3.2
779 **/
780 gboolean
camel_local_store_get_need_summary_check(CamelLocalStore * store)781 camel_local_store_get_need_summary_check (CamelLocalStore *store)
782 {
783 g_return_val_if_fail (CAMEL_IS_LOCAL_STORE (store), FALSE);
784
785 return store->priv->need_summary_check;
786 }
787
788 /**
789 * camel_local_store_set_need_summary_check:
790 * @store: a #CamelLocalStore
791 * @need_summary_check: whether to check for changes in local mail files
792 *
793 * Sets whether local mail files for @store should be checked for
794 * consistency and the summary database synchronized with them. This
795 * is necessary to handle another mail application altering the files,
796 * such as local mail delivery using fetchmail.
797 *
798 * Since: 3.2
799 **/
800 void
camel_local_store_set_need_summary_check(CamelLocalStore * store,gboolean need_summary_check)801 camel_local_store_set_need_summary_check (CamelLocalStore *store,
802 gboolean need_summary_check)
803 {
804 g_return_if_fail (CAMEL_IS_LOCAL_STORE (store));
805
806 if (store->priv->need_summary_check == need_summary_check)
807 return;
808
809 store->priv->need_summary_check = need_summary_check;
810
811 g_object_notify (G_OBJECT (store), "need-summary-check");
812 }
813