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