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