summaryrefslogtreecommitdiffabout
path: root/kmicromail/libetpan/generic/nntpdriver.c
Unidiff
Diffstat (limited to 'kmicromail/libetpan/generic/nntpdriver.c') (more/less context) (show whitespace changes)
-rw-r--r--kmicromail/libetpan/generic/nntpdriver.c1170
1 files changed, 1170 insertions, 0 deletions
diff --git a/kmicromail/libetpan/generic/nntpdriver.c b/kmicromail/libetpan/generic/nntpdriver.c
new file mode 100644
index 0000000..fde5f1a
--- a/dev/null
+++ b/kmicromail/libetpan/generic/nntpdriver.c
@@ -0,0 +1,1170 @@
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 "nntpdriver.h"
37
38#include <string.h>
39#include <stdlib.h>
40
41#include "mail.h"
42#include "mailmessage.h"
43#include "nntpdriver_tools.h"
44#include "maildriver_tools.h"
45#include "nntpdriver_message.h"
46
47static int nntpdriver_initialize(mailsession * session);
48
49static void nntpdriver_uninitialize(mailsession * session);
50
51static int nntpdriver_parameters(mailsession * session,
52 int id, void * value);
53
54static int nntpdriver_connect_stream(mailsession * session, mailstream * s);
55
56static int nntpdriver_login(mailsession * session,
57 char * userid, char * password);
58
59static int nntpdriver_logout(mailsession * session);
60
61static int nntpdriver_status_folder(mailsession * session, char * mb,
62 uint32_t * result_messages,
63 uint32_t * result_recent,
64 uint32_t * result_unseen);
65
66static int nntpdriver_messages_number(mailsession * session, char * mb,
67 uint32_t * result);
68
69static int nntpdriver_append_message(mailsession * session,
70 char * message, size_t size);
71
72static int
73nntpdriver_get_envelopes_list(mailsession * session,
74 struct mailmessage_list * env_list);
75
76
77static int nntpdriver_get_messages_list(mailsession * session,
78 struct mailmessage_list ** result);
79
80static int nntpdriver_list_folders(mailsession * session, char * mb,
81 struct mail_list ** result);
82
83static int nntpdriver_lsub_folders(mailsession * session, char * mb,
84 struct mail_list ** result);
85
86static int nntpdriver_subscribe_folder(mailsession * session, char * mb);
87
88static int nntpdriver_unsubscribe_folder(mailsession * session, char * mb);
89
90static int nntpdriver_get_message(mailsession * session,
91 uint32_t num, mailmessage ** result);
92
93static int nntpdriver_get_message_by_uid(mailsession * session,
94 const char * uid,
95 mailmessage ** result);
96
97static int nntpdriver_noop(mailsession * session);
98
99static mailsession_driver local_nntp_session_driver = {
100 .sess_name = "nntp",
101
102 .sess_initialize = nntpdriver_initialize,
103 .sess_uninitialize = nntpdriver_uninitialize,
104
105 .sess_parameters = nntpdriver_parameters,
106
107 .sess_connect_stream = nntpdriver_connect_stream,
108 .sess_connect_path = NULL,
109 .sess_starttls = NULL,
110 .sess_login = nntpdriver_login,
111 .sess_logout = nntpdriver_logout,
112 .sess_noop = nntpdriver_noop,
113
114 .sess_build_folder_name = NULL,
115 .sess_create_folder = NULL,
116 .sess_delete_folder = NULL,
117 .sess_rename_folder = NULL,
118 .sess_check_folder = NULL,
119 .sess_examine_folder = NULL,
120 .sess_select_folder = nntpdriver_select_folder,
121 .sess_expunge_folder = NULL,
122 .sess_status_folder = nntpdriver_status_folder,
123 .sess_messages_number = nntpdriver_messages_number,
124 .sess_recent_number = nntpdriver_messages_number,
125 .sess_unseen_number = nntpdriver_messages_number,
126 .sess_list_folders = nntpdriver_list_folders,
127 .sess_lsub_folders = nntpdriver_lsub_folders,
128 .sess_subscribe_folder = nntpdriver_subscribe_folder,
129 .sess_unsubscribe_folder = nntpdriver_unsubscribe_folder,
130
131 .sess_append_message = nntpdriver_append_message,
132 .sess_copy_message = NULL,
133 .sess_move_message = NULL,
134
135 .sess_get_messages_list = nntpdriver_get_messages_list,
136 .sess_get_envelopes_list = nntpdriver_get_envelopes_list,
137 .sess_remove_message = NULL,
138#if 0
139 .sess_search_messages = maildriver_generic_search_messages,
140#endif
141
142 .sess_get_message = nntpdriver_get_message,
143 .sess_get_message_by_uid = nntpdriver_get_message_by_uid,
144};
145
146
147mailsession_driver * nntp_session_driver = &local_nntp_session_driver;
148
149static inline struct nntp_session_state_data *
150get_data(mailsession * session)
151{
152 return session->sess_data;
153}
154
155static inline newsnntp * get_nntp_session(mailsession * session)
156{
157 return get_data(session)->nntp_session;
158}
159
160static int nntpdriver_initialize(mailsession * session)
161{
162 struct nntp_session_state_data * data;
163 newsnntp * nntp;
164
165 nntp = newsnntp_new(0, NULL);
166 if (nntp == NULL)
167 goto err;
168
169 data = malloc(sizeof(* data));
170 if (data == NULL)
171 goto free;
172
173 data->nntp_session = nntp;
174
175 data->nntp_userid = NULL;
176 data->nntp_password = NULL;
177
178 data->nntp_group_info = NULL;
179 data->nntp_group_name = NULL;
180
181 data->nntp_subscribed_list = clist_new();
182 if (data->nntp_subscribed_list == NULL)
183 goto free_data;
184
185 data->nntp_max_articles = 0;
186
187 data->nntp_mode_reader = FALSE;
188
189 session->sess_data = data;
190
191 return MAIL_NO_ERROR;
192
193 free_data:
194 free(data);
195 free:
196 newsnntp_free(nntp);
197 err:
198 return MAIL_ERROR_MEMORY;
199}
200
201static void nntpdriver_uninitialize(mailsession * session)
202{
203 struct nntp_session_state_data * data;
204
205 data = get_data(session);
206
207 clist_foreach(data->nntp_subscribed_list, (clist_func) free, NULL);
208 clist_free(data->nntp_subscribed_list);
209
210 if (data->nntp_group_info != NULL)
211 newsnntp_group_free(data->nntp_group_info);
212
213 if (data->nntp_group_name != NULL)
214 free(data->nntp_group_name);
215
216 if (data->nntp_userid != NULL)
217 free(data->nntp_userid);
218
219 if (data->nntp_password != NULL)
220 free(data->nntp_password);
221
222 newsnntp_free(data->nntp_session);
223 free(data);
224
225 session->sess_data = NULL;
226}
227
228
229static int nntpdriver_parameters(mailsession * session,
230 int id, void * value)
231{
232 struct nntp_session_state_data * data;
233
234 data = get_data(session);
235
236 switch (id) {
237 case NNTPDRIVER_SET_MAX_ARTICLES:
238 {
239 uint32_t * param;
240
241 param = value;
242
243 data->nntp_max_articles = * param;
244 return MAIL_NO_ERROR;
245 }
246 }
247
248 return MAIL_ERROR_INVAL;
249}
250
251
252static int add_to_list(mailsession * session, char * mb)
253{
254 char * new_mb;
255 int r;
256 struct nntp_session_state_data * data;
257
258 data = get_data(session);
259
260 new_mb = strdup(mb);
261 if (new_mb == NULL)
262 return -1;
263
264 r = clist_append(data->nntp_subscribed_list, new_mb);
265 if (r < 0) {
266 free(mb);
267 return -1;
268 }
269
270 return 0;
271}
272
273static int remove_from_list(mailsession * session, char * mb)
274{
275 clistiter * cur;
276 struct nntp_session_state_data * data;
277
278 data = get_data(session);
279
280 for(cur = clist_begin(data->nntp_subscribed_list) ; cur != NULL ;
281 cur = clist_next(cur)) {
282 char * cur_name;
283
284 cur_name = clist_content(cur);
285 if (strcmp(cur_name, mb) == 0) {
286 clist_delete(data->nntp_subscribed_list, cur);
287 free(cur_name);
288 return 0;
289 }
290 }
291
292 return -1;
293}
294
295
296static int nntpdriver_connect_stream(mailsession * session, mailstream * s)
297{
298 int r;
299
300 r = newsnntp_connect(get_nntp_session(session), s);
301
302 switch (r) {
303 case NEWSNNTP_NO_ERROR:
304 return MAIL_NO_ERROR_NON_AUTHENTICATED;
305
306 default:
307 return nntpdriver_nntp_error_to_mail_error(r);
308 }
309}
310
311static int nntpdriver_login(mailsession * session,
312 char * userid, char * password)
313{
314 struct nntp_session_state_data * data;
315 char * new_userid;
316 char * new_password;
317
318 data = get_data(session);
319
320 if (userid != NULL) {
321 new_userid = strdup(userid);
322 if (new_userid == NULL)
323 goto err;
324 }
325 else
326 new_userid = NULL;
327
328 if (password != NULL) {
329 new_password = strdup(password);
330 if (new_password == NULL)
331 goto free_uid;
332 }
333 else
334 new_password = NULL;
335
336 data->nntp_userid = new_userid;
337 data->nntp_password = new_password;
338
339 return MAIL_NO_ERROR;
340
341 free_uid:
342 if (new_userid != NULL)
343 free(new_userid);
344 err:
345 return MAIL_ERROR_MEMORY;
346}
347
348static int nntpdriver_logout(mailsession * session)
349{
350 int r;
351
352 r = newsnntp_quit(get_nntp_session(session));
353
354 return nntpdriver_nntp_error_to_mail_error(r);
355}
356
357
358static int nntpdriver_status_folder(mailsession * session, char * mb,
359 uint32_t * result_messages,
360 uint32_t * result_recent,
361 uint32_t * result_unseen)
362{
363 uint32_t count;
364 int r;
365
366 r = nntpdriver_select_folder(session, mb);
367 if (r != MAIL_NO_ERROR)
368 return r;
369
370 r = nntpdriver_messages_number(session, mb, &count);
371 if (r != MAIL_NO_ERROR)
372 return r;
373
374 * result_messages = count;
375 * result_recent = count;
376 * result_unseen = count;
377
378 return MAIL_NO_ERROR;
379}
380
381static int nntpdriver_messages_number(mailsession * session, char * mb,
382 uint32_t * result)
383{
384 int r;
385 struct nntp_session_state_data * data;
386
387 if (mb != NULL) {
388 r = nntpdriver_select_folder(session, mb);
389 if (r != MAIL_NO_ERROR)
390 return r;
391 }
392
393 data = get_data(session);
394
395 if (data->nntp_group_info == NULL)
396 return MAIL_ERROR_FOLDER_NOT_FOUND;
397
398 * result = data->nntp_group_info->grp_last -
399 data->nntp_group_info->grp_first + 1;
400
401 return MAIL_NO_ERROR;
402}
403
404static int nntpdriver_list_folders(mailsession * session, char * mb,
405 struct mail_list ** result)
406{
407 int r;
408 clist * group_list;
409 newsnntp * nntp;
410 clistiter * cur;
411 char * new_mb;
412 int done;
413 clist * list;
414 struct mail_list * ml;
415 int res;
416
417 nntp = get_nntp_session(session);
418
419 new_mb = NULL;
420 if ((mb != NULL) && (*mb != '\0')) {
421 new_mb = malloc(strlen(mb) + 3);
422 if (new_mb == NULL) {
423 res = MAIL_ERROR_MEMORY;
424 goto err;
425 }
426 strcpy(new_mb, mb);
427 strcat(new_mb, ".*");
428 }
429
430 done = FALSE;
431 do {
432 if (new_mb != NULL)
433 r = newsnntp_list_active(nntp, new_mb, &group_list);
434 else
435 r = newsnntp_list(nntp, &group_list);
436
437 switch (r) {
438 case NEWSNNTP_WARNING_REQUEST_AUTHORIZATION_USERNAME:
439 r = nntpdriver_authenticate_user(session);
440 if (r != MAIL_NO_ERROR) {
441 res = r;
442 goto err;
443 }
444 break;
445
446 case NEWSNNTP_WARNING_REQUEST_AUTHORIZATION_PASSWORD:
447 r = nntpdriver_authenticate_password(session);
448 if (r != MAIL_NO_ERROR) {
449 res = r;
450 goto err;
451 }
452 break;
453
454 case NEWSNNTP_NO_ERROR:
455 if (new_mb != NULL)
456 free(new_mb);
457 done = TRUE;
458 break;
459
460 default:
461 if (new_mb != NULL)
462 free(new_mb);
463 return nntpdriver_nntp_error_to_mail_error(r);
464 }
465 }
466 while (!done);
467
468 list = clist_new();
469 if (list == NULL) {
470 res = MAIL_ERROR_MEMORY;
471 goto err;
472 }
473
474 for(cur = clist_begin(group_list) ; cur != NULL ;
475 cur = clist_next(cur)) {
476 struct newsnntp_group_info * info;
477 char * new_name;
478
479 info = clist_content(cur);
480 new_name = strdup(info->grp_name);
481 if (new_name == NULL) {
482 res = MAIL_ERROR_MEMORY;
483 goto free_list;
484 }
485
486 r = clist_append(list, new_name);
487 if (r < 0) {
488 free(new_name);
489 res = MAIL_ERROR_MEMORY;
490 goto free_list;
491 }
492 }
493
494 ml = mail_list_new(list);
495 if (ml == NULL) {
496 res = MAIL_ERROR_MEMORY;
497 goto free_list;
498 }
499
500 newsnntp_list_free(group_list);
501
502 * result = ml;
503
504 return MAIL_NO_ERROR;
505
506 free_list:
507 clist_foreach(list, (clist_func) free, NULL);
508 clist_free(list);
509 newsnntp_list_free(group_list);
510 err:
511 return res;
512}
513
514static int nntpdriver_lsub_folders(mailsession * session, char * mb,
515 struct mail_list ** result)
516{
517 clist * subscribed;
518 clist * lsub_result;
519 clistiter * cur;
520 struct mail_list * lsub;
521 size_t length;
522 int res;
523 int r;
524 struct nntp_session_state_data * data;
525
526 length = strlen(mb);
527
528 data = get_data(session);
529
530 subscribed = data->nntp_subscribed_list;
531 lsub_result = clist_new();
532 if (lsub_result == NULL) {
533 res = MAIL_ERROR_MEMORY;
534 goto err;
535 }
536
537 for(cur = clist_begin(subscribed) ; cur != NULL ;
538 cur = clist_next(cur)) {
539 char * cur_mb;
540 char * new_mb;
541
542 cur_mb = clist_content(cur);
543
544 if (strncmp(mb, cur_mb, length) == 0) {
545 new_mb = strdup(cur_mb);
546 if (new_mb == NULL) {
547 res = MAIL_ERROR_MEMORY;
548 goto free_list;
549 }
550
551 r = clist_append(lsub_result, new_mb);
552 if (r < 0) {
553 free(new_mb);
554 res = MAIL_ERROR_MEMORY;
555 goto free_list;
556 }
557 }
558 }
559
560 lsub = mail_list_new(lsub_result);
561 if (lsub == NULL) {
562 res = MAIL_ERROR_MEMORY;
563 goto free_list;
564 }
565
566 * result = lsub;
567
568 return MAIL_NO_ERROR;
569
570 free_list:
571 clist_foreach(lsub_result, (clist_func) free, NULL);
572 clist_free(lsub_result);
573 err:
574 return res;
575}
576
577static int nntpdriver_subscribe_folder(mailsession * session, char * mb)
578{
579 int r;
580
581 r = add_to_list(session, mb);
582 if (r < 0)
583 return MAIL_ERROR_SUBSCRIBE;
584
585 return MAIL_NO_ERROR;
586}
587
588static int nntpdriver_unsubscribe_folder(mailsession * session, char * mb)
589{
590 int r;
591
592 r = remove_from_list(session, mb);
593 if (r < 0)
594 return MAIL_ERROR_UNSUBSCRIBE;
595
596 return MAIL_NO_ERROR;
597}
598
599
600
601/* messages operations */
602
603static int nntpdriver_append_message(mailsession * session,
604 char * message, size_t size)
605{
606 int r;
607 struct nntp_session_state_data * data;
608
609 data = get_data(session);
610
611 do {
612 r = newsnntp_post(get_nntp_session(session), message, size);
613 switch (r) {
614 case NEWSNNTP_WARNING_REQUEST_AUTHORIZATION_USERNAME:
615 r = nntpdriver_authenticate_user(session);
616 if (r != MAIL_NO_ERROR)
617 return r;
618 break;
619
620 case NEWSNNTP_WARNING_REQUEST_AUTHORIZATION_PASSWORD:
621 r = nntpdriver_authenticate_password(session);
622 if (r != MAIL_NO_ERROR)
623 return r;
624 break;
625
626 default:
627 return nntpdriver_nntp_error_to_mail_error(r);
628 }
629 }
630 while (1);
631}
632
633
634static int xover_resp_to_fields(struct newsnntp_xover_resp_item * item,
635 struct mailimf_fields ** result);
636
637
638static int
639nntpdriver_get_envelopes_list(mailsession * session,
640 struct mailmessage_list * env_list)
641{
642 newsnntp * nntp;
643 int r;
644 struct nntp_session_state_data * data;
645 clist * list;
646 int done;
647 clistiter * cur;
648 uint32_t first_seq;
649 unsigned int i;
650
651 nntp = get_nntp_session(session);
652
653 data = get_data(session);
654
655 if (data->nntp_group_info == NULL)
656 return MAIL_ERROR_BAD_STATE;
657
658 first_seq = data->nntp_group_info->grp_first;
659
660 if (carray_count(env_list->msg_tab) > 0) {
661 mailmessage * msg;
662
663 msg = carray_get(env_list->msg_tab, 0);
664
665 first_seq = msg->msg_index;
666 }
667
668 if (carray_count(env_list->msg_tab) > 0) {
669 i = carray_count(env_list->msg_tab) - 1;
670 while (1) {
671 mailmessage * msg;
672
673 msg = carray_get(env_list->msg_tab, i);
674
675 if (msg->msg_fields != NULL) {
676 first_seq = msg->msg_index + 1;
677 break;
678 }
679
680 if (i == 0)
681 break;
682
683 i --;
684 }
685 }
686
687 if (first_seq > data->nntp_group_info->grp_last) {
688 list = NULL;
689 }
690 else {
691 done = FALSE;
692 do {
693 r = newsnntp_xover_range(nntp, first_seq,
694 data->nntp_group_info->grp_last, &list);
695
696 switch (r) {
697 case NEWSNNTP_WARNING_REQUEST_AUTHORIZATION_USERNAME:
698 r = nntpdriver_authenticate_user(session);
699 if (r != MAIL_NO_ERROR)
700 return r;
701 break;
702
703 case NEWSNNTP_WARNING_REQUEST_AUTHORIZATION_PASSWORD:
704 r = nntpdriver_authenticate_password(session);
705 if (r != MAIL_NO_ERROR)
706 return r;
707 break;
708
709 case NEWSNNTP_NO_ERROR:
710 done = TRUE;
711 break;
712
713 default:
714 return nntpdriver_nntp_error_to_mail_error(r);
715 }
716 }
717 while (!done);
718 }
719
720#if 0
721 i = 0;
722 j = 0;
723
724 if (list != NULL) {
725 for(cur = clist_begin(list) ; cur != NULL ; cur = clist_next(cur)) {
726 struct newsnntp_xover_resp_item * item;
727 struct mailimf_fields * fields;
728
729 item = clist_content(cur);
730
731 while (i < carray_count(env_list->msg_tab)) {
732 mailmessage * info;
733
734 info = carray_get(env_list->msg_tab, i);
735
736 if (item->ovr_article == info->msg_index) {
737
738 if (info->fields == NULL) {
739 r = xover_resp_to_fields(item, &fields);
740 if (r == MAIL_NO_ERROR) {
741 info->fields = fields;
742 }
743
744 info->size = item->ovr_size;
745
746 carray_set(env_list->msg_tab, j, info);
747 j ++;
748 i ++;
749 break;
750 }
751 else {
752 carray_set(env_list->msg_tab, j, info);
753 j ++;
754 }
755 }
756 else {
757 if (info->fields != NULL) {
758 carray_set(env_list->msg_tab, j, info);
759 j ++;
760 }
761 else {
762 if (info->flags != NULL) {
763 info->flags->flags &= ~MAIL_FLAG_NEW;
764 info->flags->flags |= MAIL_FLAG_SEEN | MAIL_FLAG_DELETED;
765 mailmessage_check(info);
766 }
767 mailmessage_free(info);
768 carray_set(env_list->msg_tab, i, NULL);
769 }
770 }
771
772 i ++;
773 }
774 }
775 }
776
777 while (i < carray_count(env_list->msg_tab)) {
778 mailmessage * info;
779
780 info = carray_get(env_list->msg_tab, i);
781 if (info->fields != NULL) {
782 carray_set(env_list->msg_tab, j, info);
783 j ++;
784 }
785 else {
786 if (info->flags != NULL) {
787 info->flags->flags &= ~MAIL_FLAG_NEW;
788 info->flags->flags |= MAIL_FLAG_SEEN | MAIL_FLAG_DELETED;
789 mailmessage_check(info);
790 }
791 mailmessage_free(info);
792 carray_set(env_list->msg_tab, i, NULL);
793 }
794
795 i ++;
796 }
797
798 r = carray_set_size(env_list->msg_tab, j);
799 if (r < 0) {
800 if (list != NULL)
801 newsnntp_xover_resp_list_free(list);
802 return MAIL_ERROR_MEMORY;
803 }
804#endif
805 i = 0;
806
807 if (list != NULL) {
808 for(cur = clist_begin(list) ; cur != NULL ; cur = clist_next(cur)) {
809 struct newsnntp_xover_resp_item * item;
810 struct mailimf_fields * fields;
811
812 item = clist_content(cur);
813
814 while (i < carray_count(env_list->msg_tab)) {
815 mailmessage * info;
816
817 info = carray_get(env_list->msg_tab, i);
818
819 if (item->ovr_article == info->msg_index) {
820
821 if (info->msg_fields == NULL) {
822 r = xover_resp_to_fields(item, &fields);
823 if (r == MAIL_NO_ERROR) {
824 info->msg_fields = fields;
825 }
826
827 info->msg_size = item->ovr_size;
828
829 i ++;
830 break;
831 }
832 }
833#if 0
834 else if ((info->fields == NULL) && (info->flags != NULL)) {
835 info->flags->flags &= ~MAIL_FLAG_NEW;
836 info->flags->flags |= MAIL_FLAG_CANCELLED;
837 mailmessage_check(info);
838 }
839#endif
840
841 i ++;
842 }
843 }
844 }
845
846#if 0
847 while (i < env_list->msg_tab->len) {
848 mailmessage * info;
849
850 info = carray_get(env_list->msg_tab, i);
851 if ((info->fields == NULL) && (info->flags != NULL)) {
852 info->flags->flags &= ~MAIL_FLAG_NEW;
853 info->flags->flags |= MAIL_FLAG_CANCELLED;
854 mailmessage_check(info);
855 }
856
857 i ++;
858 }
859#endif
860
861 if (list != NULL)
862 newsnntp_xover_resp_list_free(list);
863
864 return MAIL_NO_ERROR;
865}
866
867
868static int xover_resp_to_fields(struct newsnntp_xover_resp_item * item,
869 struct mailimf_fields ** result)
870{
871 size_t cur_token;
872 clist * list;
873 int r;
874 struct mailimf_fields * fields;
875 int res;
876
877 list = clist_new();
878 if (list == NULL) {
879 res = MAIL_ERROR_MEMORY;
880 goto err;
881 }
882
883 if (item->ovr_subject != NULL) {
884 char * subject_str;
885 struct mailimf_subject * subject;
886 struct mailimf_field * field;
887
888 subject_str = strdup(item->ovr_subject);
889 if (subject_str == NULL) {
890 res = MAIL_ERROR_MEMORY;
891 goto free_list;
892 }
893
894 subject = mailimf_subject_new(subject_str);
895 if (subject == NULL) {
896 free(subject_str);
897 res = MAIL_ERROR_MEMORY;
898 goto free_list;
899 }
900
901 field = mailimf_field_new(MAILIMF_FIELD_SUBJECT,
902 NULL, NULL, NULL, NULL, NULL, NULL, NULL,
903 NULL, NULL, NULL,
904 NULL, NULL, NULL, NULL, NULL, NULL, NULL,
905 NULL, subject, NULL, NULL, NULL);
906 if (field == NULL) {
907 mailimf_subject_free(subject);
908 res = MAIL_ERROR_MEMORY;
909 goto free_list;
910 }
911
912 r = clist_append(list, field);
913 if (r < 0) {
914 mailimf_field_free(field);
915 res = MAIL_ERROR_MEMORY;
916 goto free_list;
917 }
918 }
919
920 if (item->ovr_author != NULL) {
921 struct mailimf_mailbox_list * mb_list;
922 struct mailimf_from * from;
923 struct mailimf_field * field;
924
925 cur_token = 0;
926 r = mailimf_mailbox_list_parse(item->ovr_author, strlen(item->ovr_author),
927 &cur_token, &mb_list);
928 switch (r) {
929 case MAILIMF_NO_ERROR:
930 from = mailimf_from_new(mb_list);
931 if (from == NULL) {
932 mailimf_mailbox_list_free(mb_list);
933 res = MAIL_ERROR_MEMORY;
934 goto free_list;
935 }
936
937 field = mailimf_field_new(MAILIMF_FIELD_FROM,
938 NULL, NULL, NULL, NULL, NULL, NULL, NULL,
939 NULL, NULL, from,
940 NULL, NULL, NULL, NULL, NULL, NULL, NULL,
941 NULL, NULL, NULL, NULL, NULL);
942 if (field == NULL) {
943 mailimf_from_free(from);
944 res = MAIL_ERROR_MEMORY;
945 goto free_list;
946 }
947
948 r = clist_append(list, field);
949 if (r < 0) {
950 mailimf_field_free(field);
951 res = MAIL_ERROR_MEMORY;
952 goto free_list;
953 }
954 break;
955
956 case MAILIMF_ERROR_PARSE:
957 break;
958
959 default:
960 res = maildriver_imf_error_to_mail_error(r);
961 goto free_list;
962 }
963 }
964
965 if (item->ovr_date != NULL) {
966 struct mailimf_date_time * date_time;
967 struct mailimf_orig_date * orig_date;
968 struct mailimf_field * field;
969
970 cur_token = 0;
971 r = mailimf_date_time_parse(item->ovr_date, strlen(item->ovr_date),
972 &cur_token, &date_time);
973 switch (r) {
974 case MAILIMF_NO_ERROR:
975 orig_date = mailimf_orig_date_new(date_time);
976 if (orig_date == NULL) {
977 mailimf_date_time_free(date_time);
978 res = MAIL_ERROR_MEMORY;
979 goto free_list;
980 }
981
982 field = mailimf_field_new(MAILIMF_FIELD_ORIG_DATE,
983 NULL, NULL, NULL, NULL, NULL, NULL, NULL,
984 NULL, orig_date, NULL,
985 NULL, NULL, NULL, NULL, NULL, NULL, NULL,
986 NULL, NULL, NULL, NULL, NULL);
987 if (field == NULL) {
988 mailimf_orig_date_free(orig_date);
989 res = MAIL_ERROR_MEMORY;
990 goto free_list;
991 }
992
993 r = clist_append(list, field);
994 if (r < 0) {
995 mailimf_field_free(field);
996 res = MAIL_ERROR_MEMORY;
997 goto free_list;
998 }
999 break;
1000
1001 case MAILIMF_ERROR_PARSE:
1002 break;
1003
1004 default:
1005 res = maildriver_imf_error_to_mail_error(r);
1006 goto free_list;
1007 }
1008 }
1009
1010 if (item->ovr_message_id != NULL) {
1011 char * msgid_str;
1012 struct mailimf_message_id * msgid;
1013 struct mailimf_field * field;
1014
1015 cur_token = 0;
1016 r = mailimf_msg_id_parse(item->ovr_message_id, strlen(item->ovr_message_id),
1017 &cur_token, &msgid_str);
1018
1019 switch (r) {
1020 case MAILIMF_NO_ERROR:
1021 msgid = mailimf_message_id_new(msgid_str);
1022 if (msgid == NULL) {
1023 mailimf_msg_id_free(msgid_str);
1024 res = MAIL_ERROR_MEMORY;
1025 goto free_list;
1026 }
1027
1028 field = mailimf_field_new(MAILIMF_FIELD_MESSAGE_ID,
1029 NULL, NULL, NULL, NULL, NULL, NULL, NULL,
1030 NULL, NULL, NULL,
1031 NULL, NULL, NULL, NULL, NULL, msgid, NULL,
1032 NULL, NULL, NULL, NULL, NULL);
1033
1034 r = clist_append(list, field);
1035 if (r < 0) {
1036 mailimf_field_free(field);
1037 res = MAIL_ERROR_MEMORY;
1038 goto free_list;
1039 }
1040 break;
1041
1042 case MAILIMF_ERROR_PARSE:
1043 break;
1044
1045 default:
1046 res = maildriver_imf_error_to_mail_error(r);
1047 goto free_list;
1048 }
1049 }
1050
1051 if (item->ovr_references != NULL) {
1052 clist * msgid_list;
1053 struct mailimf_references * references;
1054 struct mailimf_field * field;
1055
1056 cur_token = 0;
1057
1058 r = mailimf_msg_id_list_parse(item->ovr_references, strlen(item->ovr_references),
1059 &cur_token, &msgid_list);
1060
1061 switch (r) {
1062 case MAILIMF_NO_ERROR:
1063 references = mailimf_references_new(msgid_list);
1064 if (references == NULL) {
1065 clist_foreach(msgid_list,
1066 (clist_func) mailimf_msg_id_free, NULL);
1067 clist_free(msgid_list);
1068 res = MAIL_ERROR_MEMORY;
1069 goto free_list;
1070 }
1071
1072 field = mailimf_field_new(MAILIMF_FIELD_REFERENCES,
1073 NULL, NULL, NULL, NULL, NULL, NULL, NULL,
1074 NULL, NULL, NULL,
1075 NULL, NULL, NULL, NULL, NULL, NULL, NULL,
1076 references, NULL, NULL, NULL, NULL);
1077
1078 r = clist_append(list, field);
1079 if (r < 0) {
1080 mailimf_field_free(field);
1081 res = MAIL_ERROR_MEMORY;
1082 goto free_list;
1083 }
1084
1085 case MAILIMF_ERROR_PARSE:
1086 break;
1087
1088 default:
1089 res = maildriver_imf_error_to_mail_error(r);
1090 goto free_list;
1091 }
1092 }
1093
1094 fields = mailimf_fields_new(list);
1095 if (fields == NULL) {
1096 res = MAIL_ERROR_MEMORY;
1097 goto free_list;
1098 }
1099
1100 * result = fields;
1101
1102 return MAIL_NO_ERROR;
1103
1104 free_list:
1105 clist_foreach(list, (clist_func) mailimf_field_free, NULL);
1106 clist_free(list);
1107 err:
1108 return res;
1109}
1110
1111
1112/* get messages list with group info */
1113
1114static int nntpdriver_get_messages_list(mailsession * session,
1115 struct mailmessage_list ** result)
1116{
1117 return nntp_get_messages_list(session, session, nntp_message_driver, result);
1118
1119}
1120
1121static int nntpdriver_get_message(mailsession * session,
1122 uint32_t num, mailmessage ** result)
1123{
1124 mailmessage * msg_info;
1125 int r;
1126
1127 msg_info = mailmessage_new();
1128 if (msg_info == NULL)
1129 return MAIL_ERROR_MEMORY;
1130
1131 r = mailmessage_init(msg_info, session, nntp_message_driver, num, 0);
1132 if (r != MAIL_NO_ERROR) {
1133 mailmessage_free(msg_info);
1134 return r;
1135 }
1136
1137 * result = msg_info;
1138
1139 return MAIL_NO_ERROR;
1140}
1141
1142static int nntpdriver_noop(mailsession * session)
1143{
1144 newsnntp * nntp;
1145 int r;
1146 struct tm tm;
1147
1148 nntp = get_nntp_session(session);
1149
1150 r = newsnntp_date(nntp, &tm);
1151
1152 return nntpdriver_nntp_error_to_mail_error(r);
1153}
1154
1155static int nntpdriver_get_message_by_uid(mailsession * session,
1156 const char * uid,
1157 mailmessage ** result)
1158{
1159 uint32_t num;
1160 char * p;
1161
1162 if (uid == NULL)
1163 return MAIL_ERROR_INVAL;
1164
1165 num = strtoul(uid, &p, 10);
1166 if ((p == uid) || (* p != '\0'))
1167 return MAIL_ERROR_INVAL;
1168
1169 return nntpdriver_get_message(session, num, result);
1170 }