summaryrefslogtreecommitdiffabout
path: root/kmicromail/libetpan/generic/maildirdriver_cached_message.c
Unidiff
Diffstat (limited to 'kmicromail/libetpan/generic/maildirdriver_cached_message.c') (more/less context) (ignore whitespace changes)
-rw-r--r--kmicromail/libetpan/generic/maildirdriver_cached_message.c88
1 files changed, 87 insertions, 1 deletions
diff --git a/kmicromail/libetpan/generic/maildirdriver_cached_message.c b/kmicromail/libetpan/generic/maildirdriver_cached_message.c
index 51866aa..34de351 100644
--- a/kmicromail/libetpan/generic/maildirdriver_cached_message.c
+++ b/kmicromail/libetpan/generic/maildirdriver_cached_message.c
@@ -18,88 +18,93 @@
18 * 18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE. 29 * SUCH DAMAGE.
30 */ 30 */
31 31
32/* 32/*
33 * $Id$ 33 * $Id$
34 */ 34 */
35 35
36#include "maildirdriver_message.h" 36#include "maildirdriver_message.h"
37 37
38#include "mailmessage_tools.h" 38#include "mailmessage_tools.h"
39#include "maildirdriver.h" 39#include "maildirdriver.h"
40#include "maildir.h" 40#include "maildir.h"
41#include "generic_cache.h" 41#include "generic_cache.h"
42#include "mail_cache_db.h"
43#include "maildirdriver_tools.h"
42 44
43#include <unistd.h> 45#include <unistd.h>
44#include <sys/mman.h> 46#include <sys/mman.h>
45#include <sys/types.h> 47#include <sys/types.h>
46#include <sys/stat.h> 48#include <sys/stat.h>
47#include <fcntl.h> 49#include <fcntl.h>
48#include <string.h> 50#include <string.h>
49#include <stdlib.h> 51#include <stdlib.h>
50 52
53static int get_flags(mailmessage * msg_info,
54 struct mail_flags ** result);
55
51static int prefetch(mailmessage * msg_info); 56static int prefetch(mailmessage * msg_info);
52 57
53static void prefetch_free(struct generic_message_t * msg); 58static void prefetch_free(struct generic_message_t * msg);
54 59
55static int initialize(mailmessage * msg_info); 60static int initialize(mailmessage * msg_info);
56 61
57static void check(mailmessage * msg_info); 62static void check(mailmessage * msg_info);
58 63
59static mailmessage_driver local_maildir_cached_message_driver = { 64static mailmessage_driver local_maildir_cached_message_driver = {
60 .msg_name = "maildir-cached", 65 .msg_name = "maildir-cached",
61 66
62 .msg_initialize = initialize, 67 .msg_initialize = initialize,
63 .msg_uninitialize = mailmessage_generic_uninitialize, 68 .msg_uninitialize = mailmessage_generic_uninitialize,
64 69
65 .msg_flush = mailmessage_generic_flush, 70 .msg_flush = mailmessage_generic_flush,
66 .msg_check = check, 71 .msg_check = check,
67 72
68 .msg_fetch_result_free = mailmessage_generic_fetch_result_free, 73 .msg_fetch_result_free = mailmessage_generic_fetch_result_free,
69 74
70 .msg_fetch = mailmessage_generic_fetch, 75 .msg_fetch = mailmessage_generic_fetch,
71 .msg_fetch_header = mailmessage_generic_fetch_header, 76 .msg_fetch_header = mailmessage_generic_fetch_header,
72 .msg_fetch_body = mailmessage_generic_fetch_header, 77 .msg_fetch_body = mailmessage_generic_fetch_header,
73 .msg_fetch_size = NULL, 78 .msg_fetch_size = NULL,
74 .msg_get_bodystructure = mailmessage_generic_get_bodystructure, 79 .msg_get_bodystructure = mailmessage_generic_get_bodystructure,
75 .msg_fetch_section = mailmessage_generic_fetch_section, 80 .msg_fetch_section = mailmessage_generic_fetch_section,
76 .msg_fetch_section_header = mailmessage_generic_fetch_section_header, 81 .msg_fetch_section_header = mailmessage_generic_fetch_section_header,
77 .msg_fetch_section_mime = mailmessage_generic_fetch_section_mime, 82 .msg_fetch_section_mime = mailmessage_generic_fetch_section_mime,
78 .msg_fetch_section_body = mailmessage_generic_fetch_section_body, 83 .msg_fetch_section_body = mailmessage_generic_fetch_section_body,
79 .msg_fetch_envelope = mailmessage_generic_fetch_envelope, 84 .msg_fetch_envelope = mailmessage_generic_fetch_envelope,
80 85
81 .msg_get_flags = NULL, 86 .msg_get_flags = get_flags,
82}; 87};
83 88
84mailmessage_driver * maildir_cached_message_driver = 89mailmessage_driver * maildir_cached_message_driver =
85&local_maildir_cached_message_driver; 90&local_maildir_cached_message_driver;
86 91
87struct maildir_msg_data { 92struct maildir_msg_data {
88 int fd; 93 int fd;
89}; 94};
90 95
91#if 0 96#if 0
92static inline struct maildir_cached_session_state_data * 97static inline struct maildir_cached_session_state_data *
93get_cached_session_data(mailmessage * msg) 98get_cached_session_data(mailmessage * msg)
94{ 99{
95 return msg->session->data; 100 return msg->session->data;
96} 101}
97 102
98static inline mailsession * cached_session_get_ancestor(mailsession * session) 103static inline mailsession * cached_session_get_ancestor(mailsession * session)
99{ 104{
100 return get_data(session)->session; 105 return get_data(session)->session;
101} 106}
102 107
103static inline struct maildir_session_state_data * 108static inline struct maildir_session_state_data *
104cached_session_get_ancestor_data(mailsession * session) 109cached_session_get_ancestor_data(mailsession * session)
105{ 110{
@@ -225,24 +230,105 @@ static int initialize(mailmessage * msg_info)
225 int r; 230 int r;
226 231
227 r = mailmessage_generic_initialize(msg_info); 232 r = mailmessage_generic_initialize(msg_info);
228 if (r != MAIL_NO_ERROR) 233 if (r != MAIL_NO_ERROR)
229 return r; 234 return r;
230 235
231 msg = msg_info->msg_data; 236 msg = msg_info->msg_data;
232 msg->msg_prefetch = prefetch; 237 msg->msg_prefetch = prefetch;
233 msg->msg_prefetch_free = prefetch_free; 238 msg->msg_prefetch_free = prefetch_free;
234 239
235 return MAIL_NO_ERROR; 240 return MAIL_NO_ERROR;
236} 241}
237 242
238static void check(mailmessage * msg_info) 243static void check(mailmessage * msg_info)
239{ 244{
240 int r; 245 int r;
241 246
242 if (msg_info->msg_flags != NULL) { 247 if (msg_info->msg_flags != NULL) {
243 r = mail_flags_store_set(get_session_ancestor_data(msg_info)->md_flags_store, msg_info); 248 r = mail_flags_store_set(get_session_ancestor_data(msg_info)->md_flags_store, msg_info);
244 249
245 r = mail_flags_store_set(get_cached_session_data(msg_info)->md_flags_store, msg_info); 250 r = mail_flags_store_set(get_cached_session_data(msg_info)->md_flags_store, msg_info);
246 /* ignore errors */ 251 /* ignore errors */
247 } 252 }
248} 253}
254
255#define FLAGS_NAME "flags.db"
256
257static int get_flags(mailmessage * msg_info,
258 struct mail_flags ** result)
259{
260 struct mail_cache_db * cache_db_flags;
261 chashdatum key;
262 chashdatum value;
263 struct maildir * md;
264 struct mail_flags * flags;
265 struct maildir_cached_session_state_data * data;
266 struct maildir_msg * md_msg;
267 int r;
268 uint32_t driver_flags;
269 char filename_flags[PATH_MAX];
270 char keyname[PATH_MAX];
271 MMAPString * mmapstr;
272
273 if (msg_info->msg_flags != NULL) {
274 * result = msg_info->msg_flags;
275 return MAIL_NO_ERROR;
276 }
277
278 data = get_cached_session_data(msg_info);
279 flags = mail_flags_store_get(data->md_flags_store,
280 msg_info->msg_index);
281 if (flags != NULL) {
282 msg_info->msg_flags = flags;
283 * result = msg_info->msg_flags;
284 return MAIL_NO_ERROR;
285 }
286
287 snprintf(filename_flags, PATH_MAX, "%s%c%s%c%s",
288 data->md_flags_directory, MAIL_DIR_SEPARATOR, data->md_quoted_mb,
289 MAIL_DIR_SEPARATOR, FLAGS_NAME);
290
291 r = mail_cache_db_open_lock(filename_flags, &cache_db_flags);
292 if (r < 0)
293 return MAIL_ERROR_FILE;
294
295 snprintf(keyname, PATH_MAX, "%s-flags", msg_info->msg_uid);
296
297 mmapstr = mmap_string_new("");
298 if (mmapstr == NULL) {
299 mail_cache_db_close_unlock(filename_flags, cache_db_flags);
300 return MAIL_ERROR_MEMORY;
301 }
302
303 r = generic_cache_flags_read(cache_db_flags, mmapstr, keyname, &flags);
304 mmap_string_free(mmapstr);
305
306 mail_cache_db_close_unlock(filename_flags, cache_db_flags);
307
308 if (r != MAIL_NO_ERROR) {
309 flags = mail_flags_new_empty();
310 if (flags == NULL)
311 return MAIL_ERROR_MEMORY;
312 }
313
314 md = get_maildir_session(msg_info);
315 if (md == NULL)
316 return MAIL_ERROR_BAD_STATE;
317
318 key.data = msg_info->msg_uid;
319 key.len = strlen(msg_info->msg_uid);
320 r = chash_get(md->mdir_msg_hash, &key, &value);
321 if (r < 0)
322 return MAIL_ERROR_MSG_NOT_FOUND;
323
324 md_msg = value.data;
325
326 driver_flags = maildirdriver_maildir_flags_to_flags(md_msg->msg_flags);
327
328 flags->fl_flags = driver_flags;
329 msg_info->msg_flags = flags;
330
331 * result = msg_info->msg_flags;
332
333 return MAIL_NO_ERROR;
334}