summaryrefslogtreecommitdiffabout
path: root/kmicromail/libetpan/generic/mhdriver.c
Unidiff
Diffstat (limited to 'kmicromail/libetpan/generic/mhdriver.c') (more/less context) (show whitespace changes)
-rw-r--r--kmicromail/libetpan/generic/mhdriver.c866
1 files changed, 866 insertions, 0 deletions
diff --git a/kmicromail/libetpan/generic/mhdriver.c b/kmicromail/libetpan/generic/mhdriver.c
new file mode 100644
index 0000000..af38d27
--- a/dev/null
+++ b/kmicromail/libetpan/generic/mhdriver.c
@@ -0,0 +1,866 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2002 - 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 REGENTS 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 REGENTS 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 "mhdriver.h"
37
38#include <stdio.h>
39#include <sys/types.h>
40#include <dirent.h>
41#include <unistd.h>
42#include <sys/stat.h>
43#include <ctype.h>
44#include <fcntl.h>
45#include <sys/mman.h>
46#include <stdlib.h>
47#include <string.h>
48
49#include "mailmh.h"
50#include "maildriver_tools.h"
51#include "mhdriver_tools.h"
52#include "mhdriver_message.h"
53#include "mailmessage.h"
54
55static int mhdriver_initialize(mailsession * session);
56
57static void mhdriver_uninitialize(mailsession * session);
58
59static int mhdriver_connect_path(mailsession * session, char * path);
60static int mhdriver_logout(mailsession * session);
61
62static int mhdriver_build_folder_name(mailsession * session, char * mb,
63 char * name, char ** result);
64static int mhdriver_create_folder(mailsession * session, char * mb);
65
66static int mhdriver_delete_folder(mailsession * session, char * mb);
67
68static int mhdriver_rename_folder(mailsession * session, char * mb,
69 char * new_name);
70
71static int mhdriver_select_folder(mailsession * session, char * mb);
72
73static int mhdriver_status_folder(mailsession * session, char * mb,
74 uint32_t * result_messages, uint32_t * result_recent,
75 uint32_t * result_unseen);
76
77static int mhdriver_messages_number(mailsession * session, char * mb,
78 uint32_t * result);
79
80static int mhdriver_list_folders(mailsession * session, char * mb,
81 struct mail_list ** result);
82
83static int mhdriver_lsub_folders(mailsession * session, char * mb,
84 struct mail_list ** result);
85
86static int mhdriver_subscribe_folder(mailsession * session, char * mb);
87
88static int mhdriver_unsubscribe_folder(mailsession * session, char * mb);
89
90static int mhdriver_append_message(mailsession * session,
91 char * message, size_t size);
92static int mhdriver_copy_message(mailsession * session,
93 uint32_t num, char * mb);
94
95static int mhdriver_remove_message(mailsession * session, uint32_t num);
96
97static int mhdriver_move_message(mailsession * session,
98 uint32_t num, char * mb);
99
100static int mhdriver_get_messages_list(mailsession * session,
101 struct mailmessage_list ** result);
102
103static int mhdriver_get_message(mailsession * session,
104 uint32_t num, mailmessage ** result);
105
106static int mhdriver_get_message_by_uid(mailsession * session,
107 const char * uid,
108 mailmessage ** result);
109
110static mailsession_driver local_mh_session_driver = {
111 .sess_name = "mh",
112
113 .sess_initialize = mhdriver_initialize,
114 .sess_uninitialize = mhdriver_uninitialize,
115
116 .sess_parameters = NULL,
117
118 .sess_connect_stream = NULL,
119 .sess_connect_path = mhdriver_connect_path,
120 .sess_starttls = NULL,
121 .sess_login = NULL,
122 .sess_logout = mhdriver_logout,
123 .sess_noop = NULL,
124
125 .sess_build_folder_name = mhdriver_build_folder_name,
126 .sess_create_folder = mhdriver_create_folder,
127 .sess_delete_folder = mhdriver_delete_folder,
128 .sess_rename_folder = mhdriver_rename_folder,
129 .sess_check_folder = NULL,
130 .sess_examine_folder = NULL,
131 .sess_select_folder = mhdriver_select_folder,
132 .sess_expunge_folder = NULL,
133 .sess_status_folder = mhdriver_status_folder,
134 .sess_messages_number = mhdriver_messages_number,
135 .sess_recent_number = mhdriver_messages_number,
136 .sess_unseen_number = mhdriver_messages_number,
137 .sess_list_folders = mhdriver_list_folders,
138 .sess_lsub_folders = mhdriver_lsub_folders,
139 .sess_subscribe_folder = mhdriver_subscribe_folder,
140 .sess_unsubscribe_folder = mhdriver_unsubscribe_folder,
141
142 .sess_append_message = mhdriver_append_message,
143 .sess_copy_message = mhdriver_copy_message,
144 .sess_move_message = mhdriver_move_message,
145
146 .sess_get_messages_list = mhdriver_get_messages_list,
147 .sess_get_envelopes_list = maildriver_generic_get_envelopes_list,
148 .sess_remove_message = mhdriver_remove_message,
149#if 0
150 .sess_search_messages = maildriver_generic_search_messages,
151#endif
152
153 .sess_get_message = mhdriver_get_message,
154 .sess_get_message_by_uid = mhdriver_get_message_by_uid,
155};
156
157mailsession_driver * mh_session_driver = &local_mh_session_driver;
158
159static inline struct mh_session_state_data * get_data(mailsession * session)
160{
161 return session->sess_data;
162}
163
164static inline struct mailmh * get_mh_session(mailsession * session)
165{
166 return get_data(session)->mh_session;
167}
168
169static inline struct mailmh_folder * get_mh_cur_folder(mailsession * session)
170{
171 return get_data(session)->mh_cur_folder;
172}
173
174static int add_to_list(mailsession * session, char * mb)
175{
176 char * new_mb;
177 struct mh_session_state_data * data;
178 int r;
179
180 data = get_data(session);
181
182 new_mb = strdup(mb);
183 if (new_mb == NULL)
184 return -1;
185
186 r = clist_append(data->mh_subscribed_list, new_mb);
187 if (r < 0) {
188 free(mb);
189 return -1;
190 }
191
192 return 0;
193}
194
195static int remove_from_list(mailsession * session, char * mb)
196{
197 clistiter * cur;
198 struct mh_session_state_data * data;
199
200 data = get_data(session);
201
202 for(cur = clist_begin(data->mh_subscribed_list) ;
203 cur != NULL ; cur = clist_next(cur)) {
204 char * cur_name;
205
206 cur_name = clist_content(cur);
207 if (strcmp(cur_name, mb) == 0) {
208 clist_delete(data->mh_subscribed_list, cur);
209 free(cur_name);
210 return 0;
211 }
212 }
213
214 return -1;
215}
216
217static int mhdriver_initialize(mailsession * session)
218{
219 struct mh_session_state_data * data;
220
221 data = malloc(sizeof(* data));
222 if (data == NULL)
223 goto err;
224
225 data->mh_session = NULL;
226 data->mh_cur_folder = NULL;
227
228 data->mh_subscribed_list = clist_new();
229 if (data->mh_subscribed_list == NULL)
230 goto free;
231
232 session->sess_data = data;
233
234 return MAIL_NO_ERROR;
235
236 free:
237 free(data);
238 err:
239 return MAIL_ERROR_MEMORY;
240}
241
242static void mhdriver_uninitialize(mailsession * session)
243{
244 struct mh_session_state_data * data;
245
246 data = get_data(session);
247
248 if (data->mh_session != NULL)
249 mailmh_free(data->mh_session);
250
251 clist_foreach(data->mh_subscribed_list, (clist_func) free, NULL);
252 clist_free(data->mh_subscribed_list);
253
254 free(data);
255
256 session->sess_data = NULL;
257}
258
259
260static int mhdriver_connect_path(mailsession * session, char * path)
261{
262 struct mailmh * mh;
263
264 if (get_mh_session(session) != NULL)
265 return MAIL_ERROR_BAD_STATE;
266
267 mh = mailmh_new(path);
268 if (mh == NULL)
269 return MAIL_ERROR_MEMORY;
270
271 get_data(session)->mh_session = mh;
272
273 return MAIL_NO_ERROR;
274}
275
276static int mhdriver_logout(mailsession * session)
277{
278 struct mailmh * mh;
279
280 mh = get_mh_session(session);
281
282 if (mh == NULL)
283 return MAIL_ERROR_BAD_STATE;
284
285 mailmh_free(mh);
286 get_data(session)->mh_session = NULL;
287
288 return MAIL_NO_ERROR;
289}
290
291/* folders operations */
292
293static int mhdriver_build_folder_name(mailsession * session, char * mb,
294 char * name, char ** result)
295{
296 char * folder_name;
297
298 folder_name = malloc(strlen(mb) + 2 + strlen(name));
299 if (folder_name == NULL)
300 return MAIL_ERROR_MEMORY;
301
302 strcpy(folder_name, mb);
303 strcat(folder_name, "/");
304 strcat(folder_name, name);
305
306 * result = folder_name;
307
308 return MAIL_NO_ERROR;
309}
310
311static int get_parent(mailsession * session, char * mb,
312 struct mailmh_folder ** result_folder,
313 char ** result_name)
314{
315 char * name;
316 size_t length;
317 int i;
318 char * parent_name;
319 struct mailmh_folder * parent;
320 struct mailmh * mh;
321
322 mh = get_mh_session(session);
323 if (mh == NULL)
324 return MAIL_ERROR_BAD_STATE;
325
326 length = strlen(mb);
327 for(i = length - 1 ; i >= 0 ; i--)
328 if (mb[i] == '/')
329 break;
330 name = mb + i + 1;
331
332 parent_name = malloc(i + 1);
333 /* strndup(mb, i) */
334 if (parent_name == NULL)
335 return MAIL_ERROR_MEMORY;
336
337 strncpy(parent_name, mb, i);
338 parent_name[i] = '\0';
339
340 parent = mailmh_folder_find(mh->mh_main, parent_name);
341 free(parent_name);
342 if (parent == NULL)
343 return MAIL_ERROR_FOLDER_NOT_FOUND;
344
345 * result_folder = parent;
346 * result_name = name;
347
348 return MAIL_NO_ERROR;
349}
350
351static int mhdriver_create_folder(mailsession * session, char * mb)
352{
353 int r;
354 struct mailmh_folder * parent;
355 char * name;
356
357 r = get_parent(session, mb, &parent, &name);
358 if (r != MAIL_NO_ERROR)
359 return r;
360
361 r = mailmh_folder_add_subfolder(parent, name);
362
363 return mhdriver_mh_error_to_mail_error(r);
364}
365
366static int mhdriver_delete_folder(mailsession * session, char * mb)
367{
368 int r;
369 struct mailmh_folder * folder;
370 struct mailmh * mh;
371
372 mh = get_mh_session(session);
373 if (mh == NULL)
374 return MAIL_ERROR_BAD_STATE;
375
376 folder = mailmh_folder_find(mh->mh_main, mb);
377 if (folder == NULL)
378 return MAIL_ERROR_FOLDER_NOT_FOUND;
379
380 if (get_mh_cur_folder(session) == folder)
381 get_data(session)->mh_cur_folder = NULL;
382
383 r = mailmh_folder_remove_subfolder(folder);
384
385 return mhdriver_mh_error_to_mail_error(r);
386}
387
388static int mhdriver_rename_folder(mailsession * session, char * mb,
389 char * new_name)
390{
391 struct mailmh_folder * src_folder;
392 struct mailmh_folder * dst_folder;
393 char * name;
394 struct mailmh * mh;
395 int r;
396
397 r = get_parent(session, new_name, &dst_folder, &name);
398 if (r != MAIL_NO_ERROR)
399 return r;
400
401 mh = get_mh_session(session);
402 if (mh == NULL)
403 return MAIL_ERROR_BAD_STATE;
404
405 src_folder = mailmh_folder_find(mh->mh_main, mb);
406 if (src_folder == NULL)
407 return MAIL_ERROR_FOLDER_NOT_FOUND;
408
409 if (get_mh_cur_folder(session) == src_folder)
410 get_data(session)->mh_cur_folder = NULL;
411
412 r = mailmh_folder_rename_subfolder(src_folder, dst_folder, name);
413
414 return mhdriver_mh_error_to_mail_error(r);
415}
416
417static int mhdriver_select_folder(mailsession * session, char * mb)
418{
419 struct mailmh_folder * folder;
420 struct mailmh * mh;
421 int r;
422
423 mh = get_mh_session(session);
424 if (mh == NULL)
425 return MAIL_ERROR_BAD_STATE;
426
427 r = mailmh_folder_update(mh->mh_main);
428
429 folder = mailmh_folder_find(mh->mh_main, mb);
430 if (folder == NULL)
431 return MAIL_ERROR_FOLDER_NOT_FOUND;
432
433 get_data(session)->mh_cur_folder = folder;
434 r = mailmh_folder_update(folder);
435
436 return mhdriver_mh_error_to_mail_error(r);
437}
438
439static int mhdriver_status_folder(mailsession * session, char * mb,
440 uint32_t * result_messages, uint32_t * result_recent,
441 uint32_t * result_unseen)
442{
443 uint32_t count;
444 int r;
445
446 r = mhdriver_messages_number(session, mb, &count);
447 if (r != MAIL_NO_ERROR)
448 return r;
449
450 * result_messages = count;
451 * result_recent = count;
452 * result_unseen = count;
453
454 return MAIL_NO_ERROR;
455}
456
457static int mhdriver_messages_number(mailsession * session, char * mb,
458 uint32_t * result)
459{
460 struct mailmh_folder * folder;
461 uint32_t count;
462 struct mailmh * mh;
463 unsigned int i;
464
465 mh = get_mh_session(session);
466 if (mh == NULL)
467 return MAIL_ERROR_BAD_STATE;
468
469 if (mb != NULL) {
470 folder = mailmh_folder_find(mh->mh_main, mb);
471 if (folder == NULL)
472 return MAIL_ERROR_FOLDER_NOT_FOUND;
473 }
474 else {
475 folder = get_mh_cur_folder(session);
476 if (folder == NULL)
477 return MAIL_ERROR_BAD_STATE;
478 }
479
480 mailmh_folder_update(folder);
481 count = 0;
482 for (i = 0 ; i < carray_count(folder->fl_msgs_tab) ; i ++) {
483 struct mailmh_msg_info * msg_info;
484
485 msg_info = carray_get(folder->fl_msgs_tab, i);
486 if (msg_info != NULL)
487 count ++;
488 }
489
490 * result = count;
491
492 return MAIL_NO_ERROR;
493}
494
495
496static int get_list_folders(struct mailmh_folder * folder, clist ** result)
497{
498 unsigned int i;
499 clist * list;
500 char * new_filename;
501 int res;
502 int r;
503
504 list = * result;
505
506 new_filename = strdup(folder->fl_filename);
507 if (new_filename == NULL) {
508 res = MAIL_ERROR_MEMORY;
509 goto free;
510 }
511
512 r = mailmh_folder_update(folder);
513
514 switch (r) {
515 case MAILMH_NO_ERROR:
516 break;
517
518 default:
519 res = mhdriver_mh_error_to_mail_error(r);
520 goto free;
521 }
522
523 r = clist_append(list, new_filename);
524 if (r < 0) {
525 free(new_filename);
526 res = MAIL_ERROR_MEMORY;
527 goto free;
528 }
529
530 if (folder->fl_subfolders_tab != NULL) {
531 for(i = 0 ; i < carray_count(folder->fl_subfolders_tab) ; i++) {
532 struct mailmh_folder * subfolder;
533
534 subfolder = carray_get(folder->fl_subfolders_tab, i);
535
536 r = get_list_folders(subfolder, &list);
537 if (r != MAIL_NO_ERROR) {
538 res = MAIL_ERROR_MEMORY;
539 goto free;
540 }
541 }
542 }
543
544 * result = list;
545
546 return MAIL_NO_ERROR;
547
548 free:
549 clist_foreach(list, (clist_func) free, NULL);
550 clist_free(list);
551 return res;
552}
553
554
555static int mhdriver_list_folders(mailsession * session, char * mb,
556 struct mail_list ** result)
557{
558 clist * list;
559 int r;
560 struct mailmh * mh;
561 struct mail_list * ml;
562
563 mh = get_mh_session(session);
564
565 if (mh == NULL)
566 return MAIL_ERROR_BAD_STATE;
567
568 list = clist_new();
569 if (list == NULL)
570 return MAIL_ERROR_MEMORY;
571
572 r = get_list_folders(mh->mh_main, &list);
573 if (r != MAIL_NO_ERROR)
574 return r;
575
576 ml = mail_list_new(list);
577 if (ml == NULL)
578 goto free;
579
580 * result = ml;
581
582 return MAIL_NO_ERROR;
583
584 free:
585 clist_foreach(list, (clist_func) free, NULL);
586 clist_free(list);
587 return MAIL_ERROR_MEMORY;
588}
589
590static int mhdriver_lsub_folders(mailsession * session, char * mb,
591 struct mail_list ** result)
592{
593 clist * subscribed;
594 clist * lsub_result;
595 clistiter * cur;
596 struct mail_list * lsub;
597 size_t length;
598 int r;
599
600 length = strlen(mb);
601
602 subscribed = get_data(session)->mh_subscribed_list;
603
604 lsub_result = clist_new();
605 if (lsub_result == NULL)
606 return MAIL_ERROR_MEMORY;
607
608 for(cur = clist_begin(subscribed) ; cur != NULL ;
609 cur = clist_next(cur)) {
610 char * cur_mb;
611 char * new_mb;
612
613 cur_mb = clist_content(cur);
614
615 if (strncmp(mb, cur_mb, length) == 0) {
616 new_mb = strdup(cur_mb);
617 if (new_mb == NULL)
618 goto free_list;
619
620 r = clist_append(lsub_result, new_mb);
621 if (r < 0) {
622 free(new_mb);
623 goto free_list;
624 }
625 }
626 }
627
628 lsub = mail_list_new(lsub_result);
629 if (lsub == NULL)
630 goto free_list;
631
632 * result = lsub;
633
634 return MAIL_NO_ERROR;
635
636 free_list:
637 clist_foreach(lsub_result, (clist_func) free, NULL);
638 clist_free(lsub_result);
639 return MAIL_ERROR_MEMORY;
640}
641
642static int mhdriver_subscribe_folder(mailsession * session, char * mb)
643{
644 int r;
645
646 r = add_to_list(session, mb);
647 if (r < 0)
648 return MAIL_ERROR_SUBSCRIBE;
649
650 return MAIL_NO_ERROR;
651}
652
653static int mhdriver_unsubscribe_folder(mailsession * session, char * mb)
654{
655 int r;
656
657 r = remove_from_list(session, mb);
658 if (r < 0)
659 return MAIL_ERROR_UNSUBSCRIBE;
660
661 return MAIL_NO_ERROR;
662}
663
664/* messages operations */
665
666static int mhdriver_append_message(mailsession * session,
667 char * message, size_t size)
668{
669 int r;
670 struct mailmh_folder * folder;
671
672 folder = get_mh_cur_folder(session);
673 if (folder == NULL)
674 return MAIL_ERROR_BAD_STATE;
675
676 r = mailmh_folder_add_message(folder, message, size);
677
678 switch (r) {
679 case MAILMH_ERROR_FILE:
680 return MAIL_ERROR_DISKSPACE;
681
682 default:
683 return mhdriver_mh_error_to_mail_error(r);
684 }
685}
686
687static int mhdriver_copy_message(mailsession * session,
688 uint32_t num, char * mb)
689{
690 int fd;
691 int r;
692 struct mailmh_folder * folder;
693 struct mailmh * mh;
694 int res;
695
696 mh = get_mh_session(session);
697 if (mh == NULL) {
698 res = MAIL_ERROR_BAD_STATE;
699 goto err;
700 }
701
702 folder = get_mh_cur_folder(session);
703 if (folder == NULL) {
704 res = MAIL_ERROR_BAD_STATE;
705 goto err;
706 }
707
708 r = mailmh_folder_get_message_fd(folder, num, O_RDONLY, &fd);
709 if (r != MAIL_NO_ERROR) {
710 res = r;
711 goto err;
712 }
713
714 folder = mailmh_folder_find(mh->mh_main, mb);
715 if (folder == NULL) {
716 res = MAIL_ERROR_FOLDER_NOT_FOUND;
717 goto close;
718 }
719
720 r = mailmh_folder_add_message_file(folder, fd);
721 if (r != MAIL_NO_ERROR) {
722 res = MAIL_ERROR_COPY;
723 goto close;
724 }
725
726 close(fd);
727
728 return MAIL_NO_ERROR;
729
730 close:
731 close(fd);
732 err:
733 return res;
734}
735
736static int mhdriver_remove_message(mailsession * session, uint32_t num)
737{
738 int r;
739 struct mailmh_folder * folder;
740
741 folder = get_mh_cur_folder(session);
742 if (folder == NULL)
743 return MAIL_ERROR_DELETE;
744
745 r = mailmh_folder_remove_message(folder, num);
746
747 return mhdriver_mh_error_to_mail_error(r);
748}
749
750static int mhdriver_move_message(mailsession * session,
751 uint32_t num, char * mb)
752{
753 int r;
754 struct mailmh_folder * src_folder;
755 struct mailmh_folder * dest_folder;
756 struct mailmh * mh;
757
758 mh = get_mh_session(session);
759 if (mh == NULL)
760 return MAIL_ERROR_BAD_STATE;
761
762 src_folder = get_mh_cur_folder(session);
763 if (src_folder == NULL)
764 return MAIL_ERROR_BAD_STATE;
765
766 dest_folder = mailmh_folder_find(mh->mh_main, mb);
767 if (dest_folder == NULL)
768 return MAIL_ERROR_FOLDER_NOT_FOUND;
769
770 r = mailmh_folder_move_message(dest_folder, src_folder, num);
771
772 return mhdriver_mh_error_to_mail_error(r);
773}
774
775
776static int mhdriver_get_messages_list(mailsession * session,
777 struct mailmessage_list ** result)
778{
779 struct mailmh_folder * folder;
780 int res;
781
782 folder = get_mh_cur_folder(session);
783 if (folder == NULL) {
784 res = MAIL_ERROR_BAD_STATE;
785 goto err;
786 }
787
788 mailmh_folder_update(folder);
789 return mh_get_messages_list(folder, session, mh_message_driver, result);
790
791 err:
792 return res;
793}
794
795static int mhdriver_get_message(mailsession * session,
796 uint32_t num, mailmessage ** result)
797{
798 mailmessage * msg_info;
799 int r;
800
801 msg_info = mailmessage_new();
802 if (msg_info == NULL)
803 return MAIL_ERROR_MEMORY;
804
805 r = mailmessage_init(msg_info, session, mh_message_driver, num, 0);
806 if (r != MAIL_NO_ERROR) {
807 mailmessage_free(msg_info);
808 return r;
809 }
810
811 * result = msg_info;
812
813 return MAIL_NO_ERROR;
814}
815
816static int mhdriver_get_message_by_uid(mailsession * session,
817 const char * uid,
818 mailmessage ** result)
819{
820 uint32_t index;
821 char *p;
822 struct mailmh_msg_info * mh_msg_info;
823 struct mh_session_state_data * mh_data;
824 chashdatum key;
825 chashdatum data;
826 int r;
827 time_t mtime;
828 char * mtime_p;
829
830 if (uid == NULL)
831 return MAIL_ERROR_INVAL;
832
833 index = strtoul(uid, &p, 10);
834 if (p == uid || * p != '-')
835 return MAIL_ERROR_INVAL;
836
837 mh_data = session->sess_data;
838#if 0
839 mh_msg_info = cinthash_find(mh_data->mh_cur_folder->fl_msgs_hash, index);
840#endif
841 key.data = &index;
842 key.len = sizeof(index);
843 r = chash_get(mh_data->mh_cur_folder->fl_msgs_hash, &key, &data);
844 if (r < 0)
845 return MAIL_ERROR_MSG_NOT_FOUND;
846
847 mh_msg_info = data.data;
848
849 mtime_p = p + 1;
850
851 mtime = strtoul(mtime_p, &p, 10);
852 if ((* p == '-') && (mtime == mh_msg_info->msg_mtime)) {
853 size_t size;
854 char *size_p;
855
856 size_p = p + 1;
857 size = strtoul(size_p, &p, 10);
858 if ((* p == '\0') && (size == mh_msg_info->msg_size))
859 return mhdriver_get_message(session, index, result);
860 }
861 else if (* p != '-') {
862 return MAIL_ERROR_INVAL;
863 }
864
865 return MAIL_ERROR_MSG_NOT_FOUND;
866}