Rename camel_service_get_settings().
[platform/upstream/evolution-data-server.git] / camel / providers / local / camel-spool-folder.c
1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8; fill-column: 160 -*-
2  *
3  * Authors: Michael Zucchi <notzed@ximian.com>
4  *
5  * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of version 2 of the GNU Lesser General Public
9  * License as published by the Free Software Foundation.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
19  * USA
20  */
21
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25
26 #include <dirent.h>
27 #include <errno.h>
28 #include <fcntl.h>
29 #include <stdlib.h>
30 #include <string.h>
31 #include <unistd.h>
32 #include <sys/stat.h>
33 #include <sys/types.h>
34
35 #include <glib/gi18n-lib.h>
36
37 #include "camel-spool-folder.h"
38 #include "camel-spool-settings.h"
39 #include "camel-spool-store.h"
40 #include "camel-spool-summary.h"
41
42 #define d(x) /*(printf("%s(%d): ", __FILE__, __LINE__),(x))*/
43
44 G_DEFINE_TYPE (CamelSpoolFolder, camel_spool_folder, CAMEL_TYPE_MBOX_FOLDER)
45
46 static CamelLocalSummary *
47 spool_folder_create_summary (CamelLocalFolder *lf,
48                              const gchar *folder,
49                              CamelIndex *index)
50 {
51         return (CamelLocalSummary *) camel_spool_summary_new (
52                 CAMEL_FOLDER (lf), folder);
53 }
54
55 static gint
56 spool_folder_lock (CamelLocalFolder *lf,
57                    CamelLockType type,
58                    GError **error)
59 {
60         gint retry = 0;
61         CamelMboxFolder *mf = (CamelMboxFolder *) lf;
62         CamelSpoolFolder *sf = (CamelSpoolFolder *) lf;
63         GError *local_error = NULL;
64
65         mf->lockfd = open (lf->folder_path, O_RDWR | O_LARGEFILE, 0);
66         if (mf->lockfd == -1) {
67                 g_set_error (
68                         error, G_IO_ERROR,
69                         g_io_error_from_errno (errno),
70                         _("Cannot create folder lock on %s: %s"),
71                         lf->folder_path, g_strerror (errno));
72                 return -1;
73         }
74
75         while (retry < CAMEL_LOCK_RETRY) {
76                 if (retry > 0)
77                         sleep (CAMEL_LOCK_DELAY);
78
79                 g_clear_error (&local_error);
80
81                 if (camel_lock_fcntl (mf->lockfd, type, &local_error) == 0) {
82                         if (camel_lock_flock (mf->lockfd, type, &local_error) == 0) {
83                                 if ((sf->lockid = camel_lock_helper_lock (lf->folder_path, &local_error)) != -1)
84                                         return 0;
85                                 camel_unlock_flock (mf->lockfd);
86                         }
87                         camel_unlock_fcntl (mf->lockfd);
88                 }
89                 retry++;
90         }
91
92         close (mf->lockfd);
93         mf->lockfd = -1;
94
95         if (local_error != NULL)
96                 g_propagate_error (error, local_error);
97
98         return -1;
99 }
100
101 static void
102 spool_folder_unlock (CamelLocalFolder *lf)
103 {
104         CamelMboxFolder *mf = (CamelMboxFolder *) lf;
105         CamelSpoolFolder *sf = (CamelSpoolFolder *) lf;
106
107         camel_lock_helper_unlock (sf->lockid);
108         sf->lockid = -1;
109         camel_unlock_flock (mf->lockfd);
110         camel_unlock_fcntl (mf->lockfd);
111
112         close (mf->lockfd);
113         mf->lockfd = -1;
114 }
115
116 static void
117 camel_spool_folder_class_init (CamelSpoolFolderClass *class)
118 {
119         CamelLocalFolderClass *local_folder_class;
120
121         local_folder_class = CAMEL_LOCAL_FOLDER_CLASS (class);
122         local_folder_class->create_summary = spool_folder_create_summary;
123         local_folder_class->lock = spool_folder_lock;
124         local_folder_class->unlock = spool_folder_unlock;
125 }
126
127 static void
128 camel_spool_folder_init (CamelSpoolFolder *spool_folder)
129 {
130         spool_folder->lockid = -1;
131 }
132
133 CamelFolder *
134 camel_spool_folder_new (CamelStore *parent_store,
135                         const gchar *full_name,
136                         guint32 flags,
137                         GCancellable *cancellable,
138                         GError **error)
139 {
140         CamelFolder *folder;
141         CamelService *service;
142         CamelSettings *settings;
143         gboolean filter_inbox;
144         gboolean use_xstatus_headers;
145         gchar *basename;
146
147         service = CAMEL_SERVICE (parent_store);
148
149         settings = camel_service_ref_settings (service);
150
151         filter_inbox = camel_store_settings_get_filter_inbox (
152                 CAMEL_STORE_SETTINGS (settings));
153
154         use_xstatus_headers = camel_spool_settings_get_use_xstatus_headers (
155                 CAMEL_SPOOL_SETTINGS (settings));
156
157         g_object_unref (settings);
158
159         basename = g_path_get_basename (full_name);
160
161         folder = g_object_new (
162                 CAMEL_TYPE_SPOOL_FOLDER,
163                 "display-name", basename, "full-name", full_name,
164                 "parent-store", parent_store, NULL);
165
166         if (filter_inbox && strcmp (full_name, "INBOX") == 0)
167                 folder->folder_flags |= CAMEL_FOLDER_FILTER_RECENT;
168         flags &= ~CAMEL_STORE_FOLDER_BODY_INDEX;
169
170         folder = (CamelFolder *) camel_local_folder_construct (
171                 (CamelLocalFolder *) folder, flags, cancellable, error);
172
173         if (folder != NULL && use_xstatus_headers)
174                 camel_mbox_summary_xstatus (
175                         CAMEL_MBOX_SUMMARY (folder->summary), TRUE);
176
177         g_free (basename);
178
179         return folder;
180 }
181