Diffstat (limited to 'libetpan/src/driver/tools/generic_cache.c') (more/less context) (ignore whitespace changes)
-rw-r--r-- | libetpan/src/driver/tools/generic_cache.c | 729 |
1 files changed, 729 insertions, 0 deletions
diff --git a/libetpan/src/driver/tools/generic_cache.c b/libetpan/src/driver/tools/generic_cache.c new file mode 100644 index 0000000..3ff6e43 --- a/dev/null +++ b/libetpan/src/driver/tools/generic_cache.c | |||
@@ -0,0 +1,729 @@ | |||
1 | /* | ||
2 | * libEtPan! -- a mail stuff library | ||
3 | * | ||
4 | * Copyright (C) 2001, 2005 - DINH Viet Hoa | ||
5 | * All rights reserved. | ||
6 | * | ||
7 | * Redistribution and use in source and binary forms, with or without | ||
8 | * modification, are permitted provided that the following conditions | ||
9 | * are met: | ||
10 | * 1. Redistributions of source code must retain the above copyright | ||
11 | * notice, this list of conditions and the following disclaimer. | ||
12 | * 2. Redistributions in binary form must reproduce the above copyright | ||
13 | * notice, this list of conditions and the following disclaimer in the | ||
14 | * documentation and/or other materials provided with the distribution. | ||
15 | * 3. Neither the name of the libEtPan! project nor the names of its | ||
16 | * contributors may be used to endorse or promote products derived | ||
17 | * from this software without specific prior written permission. | ||
18 | * | ||
19 | * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND | ||
20 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
22 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE | ||
23 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
24 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
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 | ||
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 | ||
29 | * SUCH DAMAGE. | ||
30 | */ | ||
31 | |||
32 | /* | ||
33 | * $Id$ | ||
34 | */ | ||
35 | |||
36 | #include "generic_cache.h" | ||
37 | |||
38 | #include "libetpan-config.h" | ||
39 | |||
40 | #include <unistd.h> | ||
41 | #include <string.h> | ||
42 | #include <sys/mman.h> | ||
43 | #include <stdio.h> | ||
44 | #include <sys/types.h> | ||
45 | #include <sys/stat.h> | ||
46 | #include <fcntl.h> | ||
47 | #include <unistd.h> | ||
48 | #include <stdlib.h> | ||
49 | |||
50 | #include "maildriver_types.h" | ||
51 | #include "imfcache.h" | ||
52 | #include "chash.h" | ||
53 | #include "mailmessage.h" | ||
54 | #include "mail_cache_db.h" | ||
55 | |||
56 | int generic_cache_create_dir(char * dirname) | ||
57 | { | ||
58 | struct stat buf; | ||
59 | int r; | ||
60 | |||
61 | r = stat(dirname, &buf); | ||
62 | if (r != 0) { | ||
63 | r = mkdir(dirname, 0700); | ||
64 | |||
65 | if (r < 0) | ||
66 | return MAIL_ERROR_FILE; | ||
67 | } | ||
68 | else { | ||
69 | if (!S_ISDIR(buf.st_mode)) | ||
70 | return MAIL_ERROR_FILE; | ||
71 | } | ||
72 | |||
73 | return MAIL_NO_ERROR; | ||
74 | } | ||
75 | |||
76 | int generic_cache_store(char * filename, char * content, size_t length) | ||
77 | { | ||
78 | int fd; | ||
79 | char * str; | ||
80 | |||
81 | fd = open(filename, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR); | ||
82 | if (fd == -1) | ||
83 | return MAIL_ERROR_FILE; | ||
84 | |||
85 | if (ftruncate(fd, length) < 0) | ||
86 | return MAIL_ERROR_FILE; | ||
87 | |||
88 | str = mmap(NULL, length, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); | ||
89 | if (str == MAP_FAILED) | ||
90 | return MAIL_ERROR_FILE; | ||
91 | |||
92 | memcpy(str, content, length); | ||
93 | msync(str, length, MS_SYNC); | ||
94 | munmap(str, length); | ||
95 | |||
96 | close(fd); | ||
97 | |||
98 | return MAIL_NO_ERROR; | ||
99 | } | ||
100 | |||
101 | int generic_cache_read(char * filename, char ** result, size_t * result_len) | ||
102 | { | ||
103 | int fd; | ||
104 | char * str; | ||
105 | struct stat buf; | ||
106 | MMAPString * mmapstr; | ||
107 | char * content; | ||
108 | int res; | ||
109 | |||
110 | if (stat(filename, &buf) < 0) { | ||
111 | res = MAIL_ERROR_CACHE_MISS; | ||
112 | goto err; | ||
113 | } | ||
114 | |||
115 | fd = open(filename, O_RDONLY); | ||
116 | if (fd == -1) { | ||
117 | res = MAIL_ERROR_CACHE_MISS; | ||
118 | goto err; | ||
119 | } | ||
120 | |||
121 | str = mmap(NULL, buf.st_size, PROT_READ, MAP_PRIVATE, fd, 0); | ||
122 | if (str == MAP_FAILED) { | ||
123 | res = MAIL_ERROR_FILE; | ||
124 | goto close; | ||
125 | } | ||
126 | |||
127 | mmapstr = mmap_string_new_len(str, buf.st_size); | ||
128 | if (mmapstr == NULL) { | ||
129 | res = MAIL_ERROR_MEMORY; | ||
130 | goto unmap; | ||
131 | } | ||
132 | |||
133 | if (mmap_string_ref(mmapstr) < 0) { | ||
134 | res = MAIL_ERROR_MEMORY; | ||
135 | goto free; | ||
136 | } | ||
137 | |||
138 | content = mmapstr->str; | ||
139 | |||
140 | munmap(str, buf.st_size); | ||
141 | close(fd); | ||
142 | |||
143 | * result = content; | ||
144 | * result_len = buf.st_size; | ||
145 | |||
146 | return MAIL_NO_ERROR; | ||
147 | |||
148 | free: | ||
149 | mmap_string_free(mmapstr); | ||
150 | unmap: | ||
151 | munmap(str, buf.st_size); | ||
152 | close: | ||
153 | close(fd); | ||
154 | err: | ||
155 | return res; | ||
156 | } | ||
157 | |||
158 | static int flags_extension_read(MMAPString * mmapstr, size_t * index, | ||
159 | clist ** result) | ||
160 | { | ||
161 | clist * list; | ||
162 | int r; | ||
163 | uint32_t count; | ||
164 | uint32_t i; | ||
165 | int res; | ||
166 | |||
167 | r = mailimf_cache_int_read(mmapstr, index, &count); | ||
168 | if (r != MAIL_NO_ERROR) { | ||
169 | res = r; | ||
170 | goto err; | ||
171 | } | ||
172 | |||
173 | list = clist_new(); | ||
174 | if (list == NULL) { | ||
175 | res = MAIL_ERROR_MEMORY; | ||
176 | goto err; | ||
177 | } | ||
178 | |||
179 | for(i = 0 ; i < count ; i++) { | ||
180 | char * str; | ||
181 | |||
182 | r = mailimf_cache_string_read(mmapstr, index, &str); | ||
183 | if (r != MAIL_NO_ERROR) { | ||
184 | res = r; | ||
185 | goto free_list; | ||
186 | } | ||
187 | |||
188 | r = clist_append(list, str); | ||
189 | if (r < 0) { | ||
190 | free(str); | ||
191 | res = MAIL_ERROR_MEMORY; | ||
192 | goto free_list; | ||
193 | } | ||
194 | } | ||
195 | |||
196 | * result = list; | ||
197 | |||
198 | return MAIL_NO_ERROR; | ||
199 | |||
200 | free_list: | ||
201 | clist_foreach(list, (clist_func) free, NULL); | ||
202 | clist_free(list); | ||
203 | err: | ||
204 | return res; | ||
205 | } | ||
206 | |||
207 | static int generic_flags_read(MMAPString * mmapstr, size_t * index, | ||
208 | struct mail_flags ** result) | ||
209 | { | ||
210 | clist * ext; | ||
211 | int r; | ||
212 | struct mail_flags * flags; | ||
213 | uint32_t value; | ||
214 | int res; | ||
215 | |||
216 | r = mailimf_cache_int_read(mmapstr, index, &value); | ||
217 | if (r != MAIL_NO_ERROR) { | ||
218 | res = r; | ||
219 | goto err; | ||
220 | } | ||
221 | |||
222 | r = flags_extension_read(mmapstr, index, &ext); | ||
223 | if (r != MAIL_NO_ERROR) { | ||
224 | res = r; | ||
225 | goto err; | ||
226 | } | ||
227 | |||
228 | flags = mail_flags_new(value, ext); | ||
229 | if (flags == NULL) { | ||
230 | res = r; | ||
231 | goto free; | ||
232 | } | ||
233 | |||
234 | * result = flags; | ||
235 | |||
236 | return MAIL_NO_ERROR; | ||
237 | |||
238 | free: | ||
239 | clist_foreach(ext, (clist_func) free, NULL); | ||
240 | clist_free(ext); | ||
241 | err: | ||
242 | return res; | ||
243 | } | ||
244 | |||
245 | static int flags_extension_write(MMAPString * mmapstr, size_t * index, | ||
246 | clist * ext) | ||
247 | { | ||
248 | int r; | ||
249 | clistiter * cur; | ||
250 | |||
251 | r = mailimf_cache_int_write(mmapstr, index, clist_count(ext)); | ||
252 | if (r != MAIL_NO_ERROR) | ||
253 | return r; | ||
254 | |||
255 | for(cur = clist_begin(ext) ; cur != NULL ; cur = clist_next(cur)) { | ||
256 | r = mailimf_cache_string_write(mmapstr, index, | ||
257 | clist_content(cur), strlen(clist_content(cur))); | ||
258 | if (r != MAIL_NO_ERROR) | ||
259 | return r; | ||
260 | } | ||
261 | |||
262 | return MAIL_NO_ERROR; | ||
263 | } | ||
264 | |||
265 | static int generic_flags_write(MMAPString * mmapstr, size_t * index, | ||
266 | struct mail_flags * flags) | ||
267 | { | ||
268 | int r; | ||
269 | |||
270 | r = mailimf_cache_int_write(mmapstr, index, | ||
271 | flags->fl_flags & ~MAIL_FLAG_NEW); | ||
272 | if (r != MAIL_NO_ERROR) | ||
273 | return r; | ||
274 | |||
275 | r = flags_extension_write(mmapstr, index, | ||
276 | flags->fl_extension); | ||
277 | if (r != MAIL_NO_ERROR) | ||
278 | return r; | ||
279 | |||
280 | return MAIL_NO_ERROR; | ||
281 | } | ||
282 | |||
283 | |||
284 | |||
285 | |||
286 | static struct mail_flags * mail_flags_dup(struct mail_flags * flags) | ||
287 | { | ||
288 | clist * list; | ||
289 | struct mail_flags * new_flags; | ||
290 | int r; | ||
291 | clistiter * cur; | ||
292 | |||
293 | list = clist_new(); | ||
294 | if (list == NULL) { | ||
295 | goto err; | ||
296 | } | ||
297 | |||
298 | for(cur = clist_begin(flags->fl_extension) ; cur != NULL ; | ||
299 | cur = clist_next(cur)) { | ||
300 | char * ext; | ||
301 | |||
302 | ext = strdup(clist_content(cur)); | ||
303 | if (ext == NULL) { | ||
304 | goto free; | ||
305 | } | ||
306 | |||
307 | r = clist_append(list, ext); | ||
308 | if (r < 0) { | ||
309 | free(ext); | ||
310 | goto free; | ||
311 | } | ||
312 | } | ||
313 | |||
314 | new_flags = mail_flags_new(flags->fl_flags, list); | ||
315 | if (new_flags == NULL) { | ||
316 | goto free; | ||
317 | } | ||
318 | |||
319 | return new_flags; | ||
320 | |||
321 | free: | ||
322 | clist_foreach(list, (clist_func) free, NULL); | ||
323 | clist_free(list); | ||
324 | err: | ||
325 | return NULL; | ||
326 | } | ||
327 | |||
328 | static mailmessage * mailmessage_build(mailmessage * msg) | ||
329 | { | ||
330 | mailmessage * new_msg; | ||
331 | |||
332 | new_msg = malloc(sizeof(* new_msg)); | ||
333 | if (new_msg == NULL) | ||
334 | goto err; | ||
335 | |||
336 | new_msg->msg_session = msg->msg_session; | ||
337 | new_msg->msg_driver = msg->msg_driver; | ||
338 | new_msg->msg_index = msg->msg_index; | ||
339 | if (msg->msg_uid == NULL) | ||
340 | new_msg->msg_uid = NULL; | ||
341 | else { | ||
342 | new_msg->msg_uid = strdup(msg->msg_uid); | ||
343 | if (new_msg->msg_uid == NULL) | ||
344 | goto free; | ||
345 | } | ||
346 | |||
347 | new_msg->msg_cached = msg->msg_cached; | ||
348 | new_msg->msg_size = msg->msg_size; | ||
349 | new_msg->msg_fields = NULL; | ||
350 | new_msg->msg_flags = mail_flags_dup(msg->msg_flags); | ||
351 | if (new_msg->msg_flags == NULL) { | ||
352 | free(new_msg->msg_uid); | ||
353 | goto free; | ||
354 | } | ||
355 | |||
356 | new_msg->msg_mime = NULL; | ||
357 | new_msg->msg_data = NULL; | ||
358 | |||
359 | return new_msg; | ||
360 | |||
361 | free: | ||
362 | free(new_msg); | ||
363 | err: | ||
364 | return NULL; | ||
365 | } | ||
366 | |||
367 | struct mail_flags_store * mail_flags_store_new(void) | ||
368 | { | ||
369 | struct mail_flags_store * flags_store; | ||
370 | |||
371 | flags_store = malloc(sizeof(struct mail_flags_store)); | ||
372 | if (flags_store == NULL) | ||
373 | goto err; | ||
374 | |||
375 | flags_store->fls_tab = carray_new(128); | ||
376 | if (flags_store->fls_tab == NULL) | ||
377 | goto free; | ||
378 | |||
379 | flags_store->fls_hash = chash_new(128, CHASH_COPYALL); | ||
380 | if (flags_store->fls_hash == NULL) | ||
381 | goto free_tab; | ||
382 | |||
383 | return flags_store; | ||
384 | |||
385 | free_tab: | ||
386 | carray_free(flags_store->fls_tab); | ||
387 | free: | ||
388 | free(flags_store); | ||
389 | err: | ||
390 | return NULL; | ||
391 | } | ||
392 | |||
393 | void mail_flags_store_clear(struct mail_flags_store * flags_store) | ||
394 | { | ||
395 | unsigned int i; | ||
396 | |||
397 | for(i = 0 ; i < carray_count(flags_store->fls_tab) ; i ++) { | ||
398 | chashdatum key; | ||
399 | mailmessage * msg; | ||
400 | |||
401 | msg = carray_get(flags_store->fls_tab, i); | ||
402 | |||
403 | key.data = &msg->msg_index; | ||
404 | key.len = sizeof(msg->msg_index); | ||
405 | chash_delete(flags_store->fls_hash, &key, NULL); | ||
406 | |||
407 | mailmessage_free(msg); | ||
408 | } | ||
409 | carray_set_size(flags_store->fls_tab, 0); | ||
410 | } | ||
411 | |||
412 | void mail_flags_store_free(struct mail_flags_store * flags_store) | ||
413 | { | ||
414 | mail_flags_store_clear(flags_store); | ||
415 | chash_free(flags_store->fls_hash); | ||
416 | carray_free(flags_store->fls_tab); | ||
417 | free(flags_store); | ||
418 | } | ||
419 | |||
420 | int mail_flags_store_set(struct mail_flags_store * flags_store, | ||
421 | mailmessage * msg) | ||
422 | { | ||
423 | chashdatum key; | ||
424 | chashdatum value; | ||
425 | unsigned int index; | ||
426 | int res; | ||
427 | int r; | ||
428 | mailmessage * new_msg; | ||
429 | |||
430 | if (msg->msg_flags == NULL) { | ||
431 | res = MAIL_NO_ERROR; | ||
432 | goto err; | ||
433 | } | ||
434 | |||
435 | /* duplicate needed message info */ | ||
436 | new_msg = mailmessage_build(msg); | ||
437 | if (new_msg == NULL) { | ||
438 | res = MAIL_ERROR_MEMORY; | ||
439 | goto err; | ||
440 | } | ||
441 | |||
442 | key.data = &new_msg->msg_index; | ||
443 | key.len = sizeof(new_msg->msg_index); | ||
444 | |||
445 | r = chash_get(flags_store->fls_hash, &key, &value); | ||
446 | if (r == 0) { | ||
447 | mailmessage * old_msg; | ||
448 | |||
449 | index = * (unsigned int *) value.data; | ||
450 | old_msg = carray_get(flags_store->fls_tab, index); | ||
451 | mailmessage_free(old_msg); | ||
452 | } | ||
453 | else { | ||
454 | r = carray_set_size(flags_store->fls_tab, | ||
455 | carray_count(flags_store->fls_tab) + 1); | ||
456 | if (r != 0) { | ||
457 | res = MAIL_ERROR_MEMORY; | ||
458 | goto err; | ||
459 | } | ||
460 | index = carray_count(flags_store->fls_tab) - 1; | ||
461 | } | ||
462 | |||
463 | carray_set(flags_store->fls_tab, index, new_msg); | ||
464 | |||
465 | value.data = &index; | ||
466 | value.len = sizeof(index); | ||
467 | |||
468 | r = chash_set(flags_store->fls_hash, &key, &value, NULL); | ||
469 | if (r < 0) { | ||
470 | carray_delete(flags_store->fls_tab, index); | ||
471 | res = MAIL_ERROR_MEMORY; | ||
472 | goto free; | ||
473 | } | ||
474 | |||
475 | return MAIL_NO_ERROR; | ||
476 | |||
477 | free: | ||
478 | mailmessage_free(new_msg); | ||
479 | err: | ||
480 | return res; | ||
481 | } | ||
482 | |||
483 | static int msg_index_compare(mailmessage ** msg1, mailmessage ** msg2) | ||
484 | { | ||
485 | return (* msg1)->msg_index - (* msg2)->msg_index; | ||
486 | } | ||
487 | |||
488 | void mail_flags_store_sort(struct mail_flags_store * flags_store) | ||
489 | { | ||
490 | qsort(carray_data(flags_store->fls_tab), | ||
491 | carray_count(flags_store->fls_tab), sizeof(mailmessage *), | ||
492 | (int (*)(const void *, const void *)) msg_index_compare); | ||
493 | } | ||
494 | |||
495 | struct mail_flags * | ||
496 | mail_flags_store_get(struct mail_flags_store * flags_store, uint32_t index) | ||
497 | { | ||
498 | struct mail_flags * flags; | ||
499 | chashdatum key; | ||
500 | chashdatum value; | ||
501 | int r; | ||
502 | unsigned int tab_index; | ||
503 | mailmessage * msg; | ||
504 | |||
505 | key.data = &index; | ||
506 | key.len = sizeof(index); | ||
507 | |||
508 | r = chash_get(flags_store->fls_hash, &key, &value); | ||
509 | |||
510 | if (r < 0) | ||
511 | return NULL; | ||
512 | |||
513 | #if 0 | ||
514 | flags = mail_flags_dup((struct mail_flags *) value.data); | ||
515 | #endif | ||
516 | tab_index = * (unsigned int *) value.data; | ||
517 | msg = carray_get(flags_store->fls_tab, tab_index); | ||
518 | if (msg->msg_flags == NULL) | ||
519 | return NULL; | ||
520 | |||
521 | flags = mail_flags_dup(msg->msg_flags); | ||
522 | |||
523 | return flags; | ||
524 | } | ||
525 | |||
526 | int mail_flags_compare(struct mail_flags * flags1, struct mail_flags * flags2) | ||
527 | { | ||
528 | clistiter * cur1; | ||
529 | |||
530 | if (clist_count(flags1->fl_extension) != clist_count(flags2->fl_extension)) | ||
531 | return -1; | ||
532 | |||
533 | for(cur1 = clist_begin(flags1->fl_extension) ; cur1 != NULL ; | ||
534 | cur1 = clist_next(cur1)) { | ||
535 | char * flag1; | ||
536 | clistiter * cur2; | ||
537 | int found; | ||
538 | |||
539 | flag1 = clist_content(cur1); | ||
540 | |||
541 | found = 0; | ||
542 | for(cur2 = clist_begin(flags2->fl_extension) ; cur2 != NULL ; | ||
543 | cur2 = clist_next(cur2)) { | ||
544 | char * flag2; | ||
545 | |||
546 | flag2 = clist_content(cur2); | ||
547 | |||
548 | if (strcasecmp(flag1, flag2) == 0) { | ||
549 | found = 1; | ||
550 | break; | ||
551 | } | ||
552 | } | ||
553 | |||
554 | if (!found) | ||
555 | return -1; | ||
556 | } | ||
557 | |||
558 | return flags1->fl_flags - flags2->fl_flags; | ||
559 | } | ||
560 | |||
561 | |||
562 | int generic_cache_fields_read(struct mail_cache_db * cache_db, | ||
563 | MMAPString * mmapstr, | ||
564 | char * keyname, struct mailimf_fields ** result) | ||
565 | { | ||
566 | int r; | ||
567 | int res; | ||
568 | size_t cur_token; | ||
569 | struct mailimf_fields * fields; | ||
570 | void * data; | ||
571 | size_t data_len; | ||
572 | |||
573 | r = mail_cache_db_get(cache_db, keyname, strlen(keyname), &data, &data_len); | ||
574 | if (r != 0) { | ||
575 | res = MAIL_ERROR_CACHE_MISS; | ||
576 | goto err; | ||
577 | } | ||
578 | |||
579 | r = mail_serialize_clear(mmapstr, &cur_token); | ||
580 | if (r != MAIL_NO_ERROR) { | ||
581 | res = r; | ||
582 | goto err; | ||
583 | } | ||
584 | |||
585 | if (mmap_string_append_len(mmapstr, data, data_len) == NULL) { | ||
586 | res = MAIL_ERROR_MEMORY; | ||
587 | goto err; | ||
588 | } | ||
589 | |||
590 | r = mailimf_cache_fields_read(mmapstr, &cur_token, &fields); | ||
591 | if (r != MAIL_NO_ERROR) { | ||
592 | res = r; | ||
593 | goto err; | ||
594 | } | ||
595 | |||
596 | * result = fields; | ||
597 | |||
598 | return MAIL_NO_ERROR; | ||
599 | |||
600 | err: | ||
601 | return res; | ||
602 | } | ||
603 | |||
604 | int generic_cache_fields_write(struct mail_cache_db * cache_db, | ||
605 | MMAPString * mmapstr, | ||
606 | char * keyname, struct mailimf_fields * fields) | ||
607 | { | ||
608 | int r; | ||
609 | int res; | ||
610 | size_t cur_token; | ||
611 | |||
612 | r = mail_serialize_clear(mmapstr, &cur_token); | ||
613 | if (r != MAIL_NO_ERROR) { | ||
614 | res = r; | ||
615 | goto err; | ||
616 | } | ||
617 | |||
618 | r = mailimf_cache_fields_write(mmapstr, &cur_token, fields); | ||
619 | if (r != MAIL_NO_ERROR) { | ||
620 | res = r; | ||
621 | goto err; | ||
622 | } | ||
623 | |||
624 | r = mail_cache_db_put(cache_db, keyname, strlen(keyname), | ||
625 | mmapstr->str, mmapstr->len); | ||
626 | if (r != 0) { | ||
627 | res = MAIL_ERROR_FILE; | ||
628 | goto err; | ||
629 | } | ||
630 | |||
631 | return MAIL_NO_ERROR; | ||
632 | |||
633 | err: | ||
634 | return res; | ||
635 | } | ||
636 | |||
637 | int generic_cache_flags_read(struct mail_cache_db * cache_db, | ||
638 | MMAPString * mmapstr, | ||
639 | char * keyname, struct mail_flags ** result) | ||
640 | { | ||
641 | int r; | ||
642 | int res; | ||
643 | size_t cur_token; | ||
644 | struct mail_flags * flags; | ||
645 | void * data; | ||
646 | size_t data_len; | ||
647 | |||
648 | r = mail_cache_db_get(cache_db, keyname, strlen(keyname), &data, &data_len); | ||
649 | if (r != 0) { | ||
650 | res = MAIL_ERROR_CACHE_MISS; | ||
651 | goto err; | ||
652 | } | ||
653 | |||
654 | r = mail_serialize_clear(mmapstr, &cur_token); | ||
655 | if (r != MAIL_NO_ERROR) { | ||
656 | res = r; | ||
657 | goto err; | ||
658 | } | ||
659 | |||
660 | if (mmap_string_append_len(mmapstr, data, data_len) == NULL) { | ||
661 | res = MAIL_ERROR_MEMORY; | ||
662 | goto err; | ||
663 | } | ||
664 | |||
665 | r = generic_flags_read(mmapstr, &cur_token, &flags); | ||
666 | if (r != MAIL_NO_ERROR) { | ||
667 | res = r; | ||
668 | goto err; | ||
669 | } | ||
670 | |||
671 | * result = flags; | ||
672 | |||
673 | return MAIL_NO_ERROR; | ||
674 | |||
675 | err: | ||
676 | return res; | ||
677 | } | ||
678 | |||
679 | int generic_cache_flags_write(struct mail_cache_db * cache_db, | ||
680 | MMAPString * mmapstr, | ||
681 | char * keyname, struct mail_flags * flags) | ||
682 | { | ||
683 | int r; | ||
684 | int res; | ||
685 | size_t cur_token; | ||
686 | |||
687 | r = mail_serialize_clear(mmapstr, &cur_token); | ||
688 | if (r != MAIL_NO_ERROR) { | ||
689 | res = r; | ||
690 | goto err; | ||
691 | } | ||
692 | |||
693 | r = generic_flags_write(mmapstr, &cur_token, flags); | ||
694 | if (r != MAIL_NO_ERROR) { | ||
695 | res = r; | ||
696 | goto err; | ||
697 | } | ||
698 | |||
699 | r = mail_cache_db_put(cache_db, keyname, strlen(keyname), | ||
700 | mmapstr->str, mmapstr->len); | ||
701 | if (r != 0) { | ||
702 | res = MAIL_ERROR_FILE; | ||
703 | goto err; | ||
704 | } | ||
705 | |||
706 | return MAIL_NO_ERROR; | ||
707 | |||
708 | err: | ||
709 | return res; | ||
710 | } | ||
711 | |||
712 | |||
713 | int generic_cache_delete(struct mail_cache_db * cache_db, | ||
714 | char * keyname) | ||
715 | { | ||
716 | int r; | ||
717 | int res; | ||
718 | |||
719 | r = mail_cache_db_del(cache_db, keyname, strlen(keyname)); | ||
720 | if (r != 0) { | ||
721 | res = MAIL_ERROR_FILE; | ||
722 | goto err; | ||
723 | } | ||
724 | |||
725 | return MAIL_NO_ERROR; | ||
726 | |||
727 | err: | ||
728 | return res; | ||
729 | } | ||