author | zautrix <zautrix> | 2005-03-18 20:17:03 (UTC) |
---|---|---|
committer | zautrix <zautrix> | 2005-03-18 20:17:03 (UTC) |
commit | 9e549686b23b6dffdcbd09c9b10dc2cb795fbcdf (patch) (unidiff) | |
tree | 2528e6cc740225ca0f47d5ac8ff70f7d3bb10621 /libetpan/src/driver/implementation/nntp/nntpdriver_tools.c | |
parent | 9319998f20f03dcc217fbb39656755dc65226276 (diff) | |
download | kdepimpi-9e549686b23b6dffdcbd09c9b10dc2cb795fbcdf.zip kdepimpi-9e549686b23b6dffdcbd09c9b10dc2cb795fbcdf.tar.gz kdepimpi-9e549686b23b6dffdcbd09c9b10dc2cb795fbcdf.tar.bz2 |
Initial revision
Diffstat (limited to 'libetpan/src/driver/implementation/nntp/nntpdriver_tools.c') (more/less context) (ignore whitespace changes)
-rw-r--r-- | libetpan/src/driver/implementation/nntp/nntpdriver_tools.c | 563 |
1 files changed, 563 insertions, 0 deletions
diff --git a/libetpan/src/driver/implementation/nntp/nntpdriver_tools.c b/libetpan/src/driver/implementation/nntp/nntpdriver_tools.c new file mode 100644 index 0000000..eef0953 --- a/dev/null +++ b/libetpan/src/driver/implementation/nntp/nntpdriver_tools.c | |||
@@ -0,0 +1,563 @@ | |||
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_tools.h" | ||
37 | |||
38 | #include "mail.h" | ||
39 | #include "nntpdriver.h" | ||
40 | #include "nntpdriver_cached.h" | ||
41 | #include "newsnntp.h" | ||
42 | #include "maildriver_types.h" | ||
43 | #include "generic_cache.h" | ||
44 | #include "imfcache.h" | ||
45 | #include "mailmessage.h" | ||
46 | #include "mail_cache_db.h" | ||
47 | |||
48 | #include <sys/types.h> | ||
49 | #include <sys/stat.h> | ||
50 | #include <fcntl.h> | ||
51 | #include <unistd.h> | ||
52 | #include <string.h> | ||
53 | #include <stdlib.h> | ||
54 | |||
55 | int nntpdriver_nntp_error_to_mail_error(int error) | ||
56 | { | ||
57 | switch (error) { | ||
58 | case NEWSNNTP_NO_ERROR: | ||
59 | return MAIL_NO_ERROR; | ||
60 | |||
61 | case NEWSNNTP_ERROR_STREAM: | ||
62 | return MAIL_ERROR_STREAM; | ||
63 | |||
64 | case NEWSNNTP_ERROR_UNEXPECTED: | ||
65 | return MAIL_ERROR_PROGRAM_ERROR; | ||
66 | |||
67 | case NEWSNNTP_ERROR_NO_NEWSGROUP_SELECTED: | ||
68 | return MAIL_ERROR_FOLDER_NOT_FOUND; | ||
69 | |||
70 | case NEWSNNTP_ERROR_NO_ARTICLE_SELECTED: | ||
71 | case NEWSNNTP_ERROR_INVALID_ARTICLE_NUMBER: | ||
72 | case NEWSNNTP_ERROR_ARTICLE_NOT_FOUND: | ||
73 | return MAIL_ERROR_MSG_NOT_FOUND; | ||
74 | |||
75 | case NEWSNNTP_ERROR_UNEXPECTED_RESPONSE: | ||
76 | case NEWSNNTP_ERROR_INVALID_RESPONSE: | ||
77 | return MAIL_ERROR_PARSE; | ||
78 | |||
79 | case NEWSNNTP_ERROR_NO_SUCH_NEWS_GROUP: | ||
80 | return MAIL_ERROR_FOLDER_NOT_FOUND; | ||
81 | |||
82 | case NEWSNNTP_ERROR_POSTING_NOT_ALLOWED: | ||
83 | return MAIL_ERROR_READONLY; | ||
84 | |||
85 | case NEWSNNTP_ERROR_POSTING_FAILED: | ||
86 | return MAIL_ERROR_APPEND; | ||
87 | |||
88 | case NEWSNNTP_ERROR_PROGRAM_ERROR: | ||
89 | return MAIL_ERROR_PROGRAM_ERROR; | ||
90 | |||
91 | case NEWSNNTP_ERROR_NO_PERMISSION: | ||
92 | return MAIL_ERROR_NO_PERMISSION; | ||
93 | |||
94 | case NEWSNNTP_ERROR_COMMAND_NOT_UNDERSTOOD: | ||
95 | case NEWSNNTP_ERROR_COMMAND_NOT_SUPPORTED: | ||
96 | return MAIL_ERROR_COMMAND_NOT_SUPPORTED; | ||
97 | |||
98 | case NEWSNNTP_ERROR_CONNECTION_REFUSED: | ||
99 | return MAIL_ERROR_CONNECT; | ||
100 | |||
101 | case NEWSNNTP_ERROR_MEMORY: | ||
102 | return MAIL_ERROR_MEMORY; | ||
103 | |||
104 | case NEWSNNTP_ERROR_AUTHENTICATION_REJECTED: | ||
105 | return MAIL_ERROR_LOGIN; | ||
106 | |||
107 | case NEWSNNTP_ERROR_BAD_STATE: | ||
108 | return MAIL_ERROR_BAD_STATE; | ||
109 | |||
110 | case NEWSNNTP_WARNING_REQUEST_AUTHORIZATION_USERNAME: | ||
111 | case NEWSNNTP_WARNING_REQUEST_AUTHORIZATION_PASSWORD: | ||
112 | default: | ||
113 | return MAIL_ERROR_INVAL; | ||
114 | } | ||
115 | } | ||
116 | |||
117 | static inline struct nntp_session_state_data * | ||
118 | session_get_data(mailsession * session) | ||
119 | { | ||
120 | return session->sess_data; | ||
121 | } | ||
122 | |||
123 | static inline newsnntp * session_get_nntp_session(mailsession * session) | ||
124 | { | ||
125 | return session_get_data(session)->nntp_session; | ||
126 | } | ||
127 | |||
128 | static inline struct nntp_cached_session_state_data * | ||
129 | cached_session_get_data(mailsession * session) | ||
130 | { | ||
131 | return session->sess_data; | ||
132 | } | ||
133 | |||
134 | static inline mailsession * cached_session_get_ancestor(mailsession * session) | ||
135 | { | ||
136 | return cached_session_get_data(session)->nntp_ancestor; | ||
137 | } | ||
138 | |||
139 | static inline struct nntp_session_state_data * | ||
140 | cached_session_get_ancestor_data(mailsession * session) | ||
141 | { | ||
142 | return session_get_data(cached_session_get_ancestor(session)); | ||
143 | } | ||
144 | |||
145 | static inline newsnntp * cached_session_get_nntp_session(mailsession * session) | ||
146 | { | ||
147 | return session_get_nntp_session(cached_session_get_ancestor(session)); | ||
148 | } | ||
149 | |||
150 | |||
151 | int nntpdriver_authenticate_password(mailsession * session) | ||
152 | { | ||
153 | struct nntp_session_state_data * data; | ||
154 | int r; | ||
155 | |||
156 | data = session_get_data(session); | ||
157 | |||
158 | if (data->nntp_password == NULL) | ||
159 | return MAIL_ERROR_LOGIN; | ||
160 | |||
161 | r = newsnntp_authinfo_password(session_get_nntp_session(session), | ||
162 | data->nntp_password); | ||
163 | |||
164 | return nntpdriver_nntp_error_to_mail_error(r); | ||
165 | } | ||
166 | |||
167 | int nntpdriver_mode_reader(mailsession * session) | ||
168 | { | ||
169 | int done; | ||
170 | int r; | ||
171 | |||
172 | done = FALSE; | ||
173 | |||
174 | do { | ||
175 | r = newsnntp_mode_reader(session_get_nntp_session(session)); | ||
176 | |||
177 | switch (r) { | ||
178 | case NEWSNNTP_WARNING_REQUEST_AUTHORIZATION_USERNAME: | ||
179 | r = nntpdriver_authenticate_user(session); | ||
180 | if (r != MAIL_NO_ERROR) | ||
181 | return r; | ||
182 | break; | ||
183 | |||
184 | case NEWSNNTP_WARNING_REQUEST_AUTHORIZATION_PASSWORD: | ||
185 | r = nntpdriver_authenticate_password(session); | ||
186 | if (r != MAIL_NO_ERROR) | ||
187 | return r; | ||
188 | break; | ||
189 | |||
190 | case NEWSNNTP_NO_ERROR: | ||
191 | done = TRUE; | ||
192 | break; | ||
193 | |||
194 | default: | ||
195 | done = TRUE; | ||
196 | break; | ||
197 | } | ||
198 | } | ||
199 | while (!done); | ||
200 | |||
201 | return MAIL_NO_ERROR; | ||
202 | } | ||
203 | |||
204 | int nntpdriver_authenticate_user(mailsession * session) | ||
205 | { | ||
206 | struct nntp_session_state_data * data; | ||
207 | int r; | ||
208 | |||
209 | data = session_get_data(session); | ||
210 | |||
211 | if (data->nntp_userid == NULL) | ||
212 | return MAIL_ERROR_LOGIN; | ||
213 | |||
214 | r = newsnntp_authinfo_username(session_get_nntp_session(session), | ||
215 | data->nntp_userid); | ||
216 | |||
217 | switch (r) { | ||
218 | case NEWSNNTP_WARNING_REQUEST_AUTHORIZATION_PASSWORD: | ||
219 | return nntpdriver_authenticate_password(session); | ||
220 | |||
221 | default: | ||
222 | return nntpdriver_nntp_error_to_mail_error(r); | ||
223 | } | ||
224 | } | ||
225 | |||
226 | int nntpdriver_article(mailsession * session, uint32_t index, | ||
227 | char ** result, | ||
228 | size_t * result_len) | ||
229 | { | ||
230 | char * msg_content; | ||
231 | size_t msg_length; | ||
232 | int r; | ||
233 | int done; | ||
234 | |||
235 | done = FALSE; | ||
236 | do { | ||
237 | r = newsnntp_article(session_get_nntp_session(session), | ||
238 | index, &msg_content, &msg_length); | ||
239 | |||
240 | switch (r) { | ||
241 | case NEWSNNTP_WARNING_REQUEST_AUTHORIZATION_USERNAME: | ||
242 | r = nntpdriver_authenticate_user(session); | ||
243 | if (r != MAIL_NO_ERROR) | ||
244 | return r; | ||
245 | break; | ||
246 | |||
247 | case NEWSNNTP_WARNING_REQUEST_AUTHORIZATION_PASSWORD: | ||
248 | r = nntpdriver_authenticate_password(session); | ||
249 | if (r != MAIL_NO_ERROR) | ||
250 | return r; | ||
251 | break; | ||
252 | |||
253 | case NEWSNNTP_NO_ERROR: | ||
254 | done = TRUE; | ||
255 | break; | ||
256 | |||
257 | default: | ||
258 | return nntpdriver_nntp_error_to_mail_error(r); | ||
259 | } | ||
260 | } | ||
261 | while (!done); | ||
262 | |||
263 | * result = msg_content; | ||
264 | * result_len = msg_length; | ||
265 | |||
266 | return MAIL_NO_ERROR; | ||
267 | } | ||
268 | |||
269 | int nntpdriver_head(mailsession * session, uint32_t index, | ||
270 | char ** result, | ||
271 | size_t * result_len) | ||
272 | { | ||
273 | char * headers; | ||
274 | size_t headers_length; | ||
275 | int r; | ||
276 | int done; | ||
277 | |||
278 | done = FALSE; | ||
279 | do { | ||
280 | r = newsnntp_head(session_get_nntp_session(session), | ||
281 | index, &headers, &headers_length); | ||
282 | |||
283 | switch (r) { | ||
284 | case NEWSNNTP_WARNING_REQUEST_AUTHORIZATION_USERNAME: | ||
285 | r = nntpdriver_authenticate_user(session); | ||
286 | if (r != MAIL_NO_ERROR) | ||
287 | return r; | ||
288 | break; | ||
289 | |||
290 | case NEWSNNTP_WARNING_REQUEST_AUTHORIZATION_PASSWORD: | ||
291 | r = nntpdriver_authenticate_password(session); | ||
292 | if (r != MAIL_NO_ERROR) | ||
293 | return r; | ||
294 | break; | ||
295 | |||
296 | case NEWSNNTP_NO_ERROR: | ||
297 | done = TRUE; | ||
298 | break; | ||
299 | |||
300 | default: | ||
301 | return nntpdriver_nntp_error_to_mail_error(r); | ||
302 | } | ||
303 | } | ||
304 | while (!done); | ||
305 | |||
306 | * result = headers; | ||
307 | * result_len = headers_length; | ||
308 | |||
309 | return MAIL_NO_ERROR; | ||
310 | } | ||
311 | |||
312 | int nntpdriver_size(mailsession * session, uint32_t index, | ||
313 | size_t * result) | ||
314 | { | ||
315 | newsnntp * nntp; | ||
316 | struct newsnntp_xover_resp_item * item; | ||
317 | int r; | ||
318 | int done; | ||
319 | |||
320 | nntp = session_get_nntp_session(session); | ||
321 | |||
322 | done = FALSE; | ||
323 | do { | ||
324 | r = newsnntp_xover_single(nntp, index, &item); | ||
325 | switch (r) { | ||
326 | case NEWSNNTP_WARNING_REQUEST_AUTHORIZATION_USERNAME: | ||
327 | r = nntpdriver_authenticate_user(session); | ||
328 | if (r != MAIL_NO_ERROR) | ||
329 | return r; | ||
330 | break; | ||
331 | |||
332 | case NEWSNNTP_WARNING_REQUEST_AUTHORIZATION_PASSWORD: | ||
333 | r = nntpdriver_authenticate_password(session); | ||
334 | if (r != MAIL_NO_ERROR) | ||
335 | return r; | ||
336 | break; | ||
337 | |||
338 | case NEWSNNTP_NO_ERROR: | ||
339 | done = TRUE; | ||
340 | break; | ||
341 | |||
342 | default: | ||
343 | return nntpdriver_nntp_error_to_mail_error(r); | ||
344 | } | ||
345 | } | ||
346 | while (!done); | ||
347 | |||
348 | * result = item->ovr_size; | ||
349 | |||
350 | xover_resp_item_free(item); | ||
351 | |||
352 | return MAIL_NO_ERROR; | ||
353 | } | ||
354 | |||
355 | int | ||
356 | nntpdriver_get_cached_flags(struct mail_cache_db * cache_db, | ||
357 | MMAPString * mmapstr, | ||
358 | uint32_t num, | ||
359 | struct mail_flags ** result) | ||
360 | { | ||
361 | int r; | ||
362 | char keyname[PATH_MAX]; | ||
363 | struct mail_flags * flags; | ||
364 | int res; | ||
365 | |||
366 | snprintf(keyname, PATH_MAX, "%u-flags", num); | ||
367 | |||
368 | r = generic_cache_flags_read(cache_db, mmapstr, keyname, &flags); | ||
369 | if (r != MAIL_NO_ERROR) { | ||
370 | res = r; | ||
371 | goto err; | ||
372 | } | ||
373 | |||
374 | * result = flags; | ||
375 | |||
376 | return MAIL_NO_ERROR; | ||
377 | |||
378 | err: | ||
379 | return res; | ||
380 | } | ||
381 | |||
382 | int | ||
383 | nntpdriver_write_cached_flags(struct mail_cache_db * cache_db, | ||
384 | MMAPString * mmapstr, | ||
385 | uint32_t num, | ||
386 | struct mail_flags * flags) | ||
387 | { | ||
388 | int r; | ||
389 | char keyname[PATH_MAX]; | ||
390 | int res; | ||
391 | |||
392 | snprintf(keyname, PATH_MAX, "%u-flags", num); | ||
393 | |||
394 | r = generic_cache_flags_write(cache_db, mmapstr, keyname, flags); | ||
395 | if (r != MAIL_NO_ERROR) { | ||
396 | res = r; | ||
397 | goto err; | ||
398 | } | ||
399 | |||
400 | return MAIL_NO_ERROR; | ||
401 | |||
402 | err: | ||
403 | return res; | ||
404 | } | ||
405 | |||
406 | |||
407 | |||
408 | int nntpdriver_select_folder(mailsession * session, char * mb) | ||
409 | { | ||
410 | int r; | ||
411 | struct newsnntp_group_info * info; | ||
412 | newsnntp * nntp_session; | ||
413 | struct nntp_session_state_data * data; | ||
414 | char * new_name; | ||
415 | int done; | ||
416 | |||
417 | data = session_get_data(session); | ||
418 | |||
419 | if (!data->nntp_mode_reader) { | ||
420 | r = nntpdriver_mode_reader(session); | ||
421 | if (r != MAIL_NO_ERROR) | ||
422 | return r; | ||
423 | |||
424 | data->nntp_mode_reader = TRUE; | ||
425 | } | ||
426 | |||
427 | if (data->nntp_group_name != NULL) | ||
428 | if (strcmp(data->nntp_group_name, mb) == 0) | ||
429 | return MAIL_NO_ERROR; | ||
430 | |||
431 | nntp_session = session_get_nntp_session(session); | ||
432 | |||
433 | done = FALSE; | ||
434 | do { | ||
435 | r = newsnntp_group(nntp_session, mb, &info); | ||
436 | |||
437 | switch (r) { | ||
438 | case NEWSNNTP_WARNING_REQUEST_AUTHORIZATION_USERNAME: | ||
439 | r = nntpdriver_authenticate_user(session); | ||
440 | if (r != MAIL_NO_ERROR) | ||
441 | return r; | ||
442 | break; | ||
443 | |||
444 | case NEWSNNTP_WARNING_REQUEST_AUTHORIZATION_PASSWORD: | ||
445 | r = nntpdriver_authenticate_password(session); | ||
446 | if (r != MAIL_NO_ERROR) | ||
447 | return r; | ||
448 | break; | ||
449 | |||
450 | case NEWSNNTP_NO_ERROR: | ||
451 | done = TRUE; | ||
452 | break; | ||
453 | |||
454 | default: | ||
455 | return nntpdriver_nntp_error_to_mail_error(r); | ||
456 | } | ||
457 | |||
458 | } | ||
459 | while (!done); | ||
460 | |||
461 | new_name = strdup(mb); | ||
462 | if (new_name == NULL) | ||
463 | return MAIL_ERROR_MEMORY; | ||
464 | |||
465 | if (data->nntp_group_name != NULL) | ||
466 | free(data->nntp_group_name); | ||
467 | data->nntp_group_name = new_name; | ||
468 | if (data->nntp_group_info != NULL) | ||
469 | newsnntp_group_free(data->nntp_group_info); | ||
470 | data->nntp_group_info = info; | ||
471 | |||
472 | return MAIL_NO_ERROR; | ||
473 | } | ||
474 | |||
475 | |||
476 | int nntp_get_messages_list(mailsession * nntp_session, | ||
477 | mailsession * session, | ||
478 | mailmessage_driver * driver, | ||
479 | struct mailmessage_list ** result) | ||
480 | { | ||
481 | carray * tab; | ||
482 | struct mailmessage_list * env_list; | ||
483 | uint32_t i; | ||
484 | int res; | ||
485 | int r; | ||
486 | struct nntp_session_state_data * data; | ||
487 | struct newsnntp_group_info * group_info; | ||
488 | uint32_t max; | ||
489 | unsigned int cur; | ||
490 | |||
491 | data = session_get_data(nntp_session); | ||
492 | |||
493 | if (data->nntp_group_name == NULL) { | ||
494 | res = MAIL_ERROR_BAD_STATE; | ||
495 | goto err; | ||
496 | } | ||
497 | |||
498 | r = nntpdriver_select_folder(nntp_session, data->nntp_group_name); | ||
499 | if (r != MAIL_NO_ERROR) { | ||
500 | res = r; | ||
501 | goto err; | ||
502 | } | ||
503 | |||
504 | group_info = data->nntp_group_info; | ||
505 | |||
506 | if (group_info == NULL) { | ||
507 | res = MAIL_ERROR_BAD_STATE; | ||
508 | goto err; | ||
509 | } | ||
510 | |||
511 | max = group_info->grp_first; | ||
512 | if (data->nntp_max_articles != 0) { | ||
513 | if (group_info->grp_last - data->nntp_max_articles + 1 > max) | ||
514 | max = group_info->grp_last - data->nntp_max_articles + 1; | ||
515 | } | ||
516 | |||
517 | tab = carray_new(128); | ||
518 | if (tab == NULL) { | ||
519 | res = MAIL_ERROR_MEMORY; | ||
520 | goto err; | ||
521 | } | ||
522 | |||
523 | for(i = max ; i <= group_info->grp_last ; i++) { | ||
524 | mailmessage * msg; | ||
525 | |||
526 | msg = mailmessage_new(); | ||
527 | if (msg == NULL) { | ||
528 | res = MAIL_ERROR_MEMORY; | ||
529 | goto free_list; | ||
530 | } | ||
531 | |||
532 | r = mailmessage_init(msg, session, driver, i, 0); | ||
533 | if (r != MAIL_NO_ERROR) { | ||
534 | mailmessage_free(msg); | ||
535 | res = r; | ||
536 | goto free_list; | ||
537 | } | ||
538 | |||
539 | r = carray_add(tab, msg, NULL); | ||
540 | if (r < 0) { | ||
541 | mailmessage_free(msg); | ||
542 | res = MAIL_ERROR_MEMORY; | ||
543 | goto free_list; | ||
544 | } | ||
545 | } | ||
546 | |||
547 | env_list = mailmessage_list_new(tab); | ||
548 | if (env_list == NULL) { | ||
549 | res = MAIL_ERROR_MEMORY; | ||
550 | goto free_list; | ||
551 | } | ||
552 | |||
553 | * result = env_list; | ||
554 | |||
555 | return MAIL_NO_ERROR; | ||
556 | |||
557 | free_list: | ||
558 | for(cur = 0 ; cur < carray_count(tab) ; cur ++) | ||
559 | mailmessage_free(carray_get(tab, cur)); | ||
560 | carray_free(tab); | ||
561 | err: | ||
562 | return res; | ||
563 | } | ||