summaryrefslogtreecommitdiffabout
path: root/libetpan/src/driver/interface/mailmessage_tools.c
Unidiff
Diffstat (limited to 'libetpan/src/driver/interface/mailmessage_tools.c') (more/less context) (ignore whitespace changes)
-rw-r--r--libetpan/src/driver/interface/mailmessage_tools.c600
1 files changed, 600 insertions, 0 deletions
diff --git a/libetpan/src/driver/interface/mailmessage_tools.c b/libetpan/src/driver/interface/mailmessage_tools.c
new file mode 100644
index 0000000..9e53173
--- a/dev/null
+++ b/libetpan/src/driver/interface/mailmessage_tools.c
@@ -0,0 +1,600 @@
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 "mailmessage_tools.h"
37#include "mailmessage.h"
38
39#include <stdlib.h>
40
41#include "maildriver.h"
42#include "maildriver_tools.h"
43
44int
45mailmessage_generic_initialize(mailmessage * msg_info)
46{
47 struct generic_message_t * msg;
48
49 msg = malloc(sizeof(* msg));
50
51 if (msg == NULL) {
52 return MAIL_ERROR_MEMORY;
53 }
54
55 msg->msg_fetched = 0;
56 msg->msg_message = NULL;
57 msg->msg_length = 0;
58
59 msg->msg_prefetch = NULL;
60 msg->msg_prefetch_free = NULL;
61 msg->msg_data = NULL;
62
63 msg_info->msg_data = msg;
64
65 return MAIL_NO_ERROR;
66}
67
68void mailmessage_generic_flush(mailmessage * msg_info)
69{
70 struct generic_message_t * msg;
71
72 if (msg_info->msg_mime != NULL) {
73 mailmime_free(msg_info->msg_mime);
74 msg_info->msg_mime = NULL;
75 }
76 msg = msg_info->msg_data;
77 if (msg != NULL) {
78 if (msg->msg_prefetch_free != NULL)
79 msg->msg_prefetch_free(msg);
80 msg->msg_fetched = 0;
81 }
82}
83
84void mailmessage_generic_uninitialize(mailmessage * msg_info)
85{
86 struct generic_message_t * msg;
87
88 mailmessage_generic_flush(msg_info);
89
90 msg = msg_info->msg_data;
91 msg_info->msg_data = NULL;
92 free(msg);
93}
94
95static inline int
96mailmessage_generic_prefetch(mailmessage * msg_info)
97{
98 struct generic_message_t * msg;
99 int r;
100
101 msg = msg_info->msg_data;
102
103 if (msg->msg_fetched)
104 return MAIL_NO_ERROR;
105
106#if 0
107 if (msg->message != NULL)
108 return MAIL_NO_ERROR;
109#endif
110
111 r = msg->msg_prefetch(msg_info);
112 if (r != MAIL_NO_ERROR)
113 return r;
114
115 msg->msg_fetched = 1;
116
117 return MAIL_NO_ERROR;
118}
119
120static int
121mailmessage_generic_prefetch_bodystructure(mailmessage * msg_info)
122{
123 size_t length;
124 char * message;
125 size_t cur_token;
126 struct mailmime * mime;
127 int r;
128 int res;
129 struct generic_message_t * msg;
130
131 if (msg_info->msg_mime != NULL) {
132 /* it has already been fetched */
133 return MAIL_NO_ERROR;
134 }
135
136#if 0
137 msg = msg_info->data;
138 if (msg->message == NULL) {
139 r = mailmessage_generic_prefetch(msg_info);
140 if (r != MAIL_NO_ERROR) {
141 res = r;
142 goto err;
143 }
144 }
145#endif
146 r = mailmessage_generic_prefetch(msg_info);
147 if (r != MAIL_NO_ERROR) {
148 res = r;
149 goto err;
150 }
151
152 msg = msg_info->msg_data;
153 message = msg->msg_message;
154 length = msg->msg_length;
155 cur_token = 0;
156 r = mailmime_parse(message, length, &cur_token, &mime);
157 if (r != MAILIMF_NO_ERROR) {
158 res = MAIL_ERROR_PARSE;
159 goto err;
160 }
161
162 msg_info->msg_mime = mime;
163
164 return MAIL_NO_ERROR;
165
166 err:
167 return res;
168}
169
170void
171mailmessage_generic_fetch_result_free(mailmessage * msg_info, char * msg)
172{
173 int r;
174
175 r = mmap_string_unref(msg);
176}
177
178int mailmessage_generic_fetch(mailmessage * msg_info,
179 char ** result,
180 size_t * result_len)
181{
182 int r;
183 char * message;
184 size_t cur_token;
185 size_t length;
186 MMAPString * mmapstr;
187 int res;
188 struct generic_message_t * msg;
189
190 msg = msg_info->msg_data;
191 r = mailmessage_generic_prefetch(msg_info);
192 if (r != MAIL_NO_ERROR) {
193 res = r;
194 goto err;
195 }
196
197 message = msg->msg_message;
198 length = msg->msg_length;
199 cur_token = 0;
200
201 mmapstr = mmap_string_new_len(message, length);
202 if (mmapstr == NULL) {
203 res = MAIL_ERROR_MEMORY;
204 goto err;
205 }
206
207 r = mmap_string_ref(mmapstr);
208 if (r < 0) {
209 res = MAIL_ERROR_MEMORY;
210 goto free_mmap;
211 }
212
213 * result = mmapstr->str;
214 * result_len = length;
215
216 return MAIL_NO_ERROR;
217
218 free_mmap:
219 mmap_string_free(mmapstr);
220 err:
221 return res;
222}
223
224int mailmessage_generic_fetch_header(mailmessage * msg_info,
225 char ** result,
226 size_t * result_len)
227{
228 int r;
229 char * message;
230 size_t cur_token;
231 size_t length;
232 MMAPString * mmapstr;
233 char * headers;
234 int res;
235 struct generic_message_t * msg;
236
237 msg = msg_info->msg_data;
238 r = mailmessage_generic_prefetch(msg_info);
239 if (r != MAIL_NO_ERROR) {
240 res = r;
241 goto err;
242 }
243
244 message = msg->msg_message;
245 length = msg->msg_length;
246 cur_token = 0;
247
248 while (1) {
249 r = mailimf_ignore_field_parse(message, length, &cur_token);
250 if (r == MAILIMF_NO_ERROR) {
251 /* do nothing */
252 }
253 else
254 break;
255 }
256 mailimf_crlf_parse(message, length, &cur_token);
257
258 mmapstr = mmap_string_new_len(message, cur_token);
259 if (mmapstr == NULL) {
260 res = MAIL_ERROR_MEMORY;
261 goto err;
262 }
263
264 r = mmap_string_ref(mmapstr);
265 if (r < 0) {
266 res = MAIL_ERROR_MEMORY;
267 goto free_mmap;
268 }
269
270 headers = mmapstr->str;
271
272 * result = headers;
273 * result_len = cur_token;
274
275 return MAIL_NO_ERROR;
276
277 free_mmap:
278 mmap_string_free(mmapstr);
279 err:
280 return res;
281}
282
283int mailmessage_generic_fetch_body(mailmessage * msg_info,
284 char ** result, size_t * result_len)
285{
286 int r;
287 char * message;
288 size_t cur_token;
289 MMAPString * mmapstr;
290 size_t length;
291 int res;
292 struct generic_message_t * msg;
293
294 msg = msg_info->msg_data;
295 r = mailmessage_generic_prefetch(msg_info);
296 if (r != MAIL_NO_ERROR) {
297 res = r;
298 goto err;
299 }
300
301 message = msg->msg_message;
302 length = msg->msg_length;
303 cur_token = 0;
304
305 while (1) {
306 r = mailimf_ignore_field_parse(message, length, &cur_token);
307 if (r == MAILIMF_NO_ERROR) {
308 /* do nothing */
309 }
310 else
311 break;
312 }
313 mailimf_crlf_parse(message, length, &cur_token);
314
315 mmapstr = mmap_string_new_len(message + cur_token, length - cur_token);
316 if (mmapstr == NULL) {
317 res = MAIL_ERROR_MEMORY;
318 goto err;
319 }
320
321 r = mmap_string_ref(mmapstr);
322 if (r < 0) {
323 res = MAIL_ERROR_MEMORY;
324 goto free_mmap;
325 }
326
327 * result = mmapstr->str;
328 * result_len = length - cur_token;
329
330 return MAIL_NO_ERROR;
331
332 free_mmap:
333 mmap_string_free(mmapstr);
334 err:
335 return res;
336}
337
338
339
340
341int
342mailmessage_generic_get_bodystructure(mailmessage * msg_info,
343 struct mailmime ** result)
344{
345 int r;
346
347 r = mailmessage_generic_prefetch_bodystructure(msg_info);
348 if (r != MAIL_NO_ERROR)
349 return r;
350
351 * result = msg_info->msg_mime;
352
353 return MAIL_NO_ERROR;
354}
355
356
357
358
359int
360mailmessage_generic_fetch_section(mailmessage * msg_info,
361 struct mailmime * mime,
362 char ** result, size_t * result_len)
363{
364 MMAPString * mmapstr;
365 int r;
366 int res;
367
368 mmapstr = mmap_string_new_len(mime->mm_body->dt_data.dt_text.dt_data,
369 mime->mm_body->dt_data.dt_text.dt_length);
370 if (mmapstr == NULL) {
371 res = MAIL_ERROR_MEMORY;
372 goto err;
373 }
374
375 r = mmap_string_ref(mmapstr);
376 if (r < 0) {
377 res = MAIL_ERROR_MEMORY;
378 goto free_mmap;
379 }
380
381 * result = mmapstr->str;
382 * result_len = mmapstr->len;
383
384 return MAIL_NO_ERROR;
385
386 free_mmap:
387 mmap_string_free(mmapstr);
388 err:
389 return res;
390}
391
392int
393mailmessage_generic_fetch_section_header(mailmessage * msg_info,
394 struct mailmime * mime,
395 char ** result,
396 size_t * result_len)
397{
398 MMAPString * mmapstr;
399 int r;
400 int res;
401 size_t cur_token;
402
403 /* skip mime */
404
405 cur_token = 0;
406
407 if (mime->mm_type == MAILMIME_MESSAGE) {
408
409 while (1) {
410 r = mailimf_ignore_field_parse(mime->mm_body->dt_data.dt_text.dt_data,
411 mime->mm_body->dt_data.dt_text.dt_length, &cur_token);
412 if (r == MAILIMF_NO_ERROR) {
413 /* do nothing */
414 }
415 else
416 break;
417 }
418
419 r = mailimf_crlf_parse(mime->mm_body->dt_data.dt_text.dt_data,
420 mime->mm_body->dt_data.dt_text.dt_length, &cur_token);
421 if ((r != MAILIMF_NO_ERROR) && (r != MAILIMF_ERROR_PARSE)) {
422 res = maildriver_imf_error_to_mail_error(r);
423 goto err;
424 }
425 }
426
427 mmapstr = mmap_string_new_len(mime->mm_body->dt_data.dt_text.dt_data,
428 cur_token);
429 if (mmapstr == NULL) {
430 res = MAIL_ERROR_MEMORY;
431 goto err;
432 }
433
434 r = mmap_string_ref(mmapstr);
435 if (r < 0) {
436 res = MAIL_ERROR_MEMORY;
437 goto free_mmap;
438 }
439
440 * result = mmapstr->str;
441 * result_len = mmapstr->len;
442
443 return MAIL_NO_ERROR;
444
445 free_mmap:
446 mmap_string_free(mmapstr);
447 err:
448 return res;
449}
450
451int
452mailmessage_generic_fetch_section_mime(mailmessage * msg_info,
453 struct mailmime * mime,
454 char ** result,
455 size_t * result_len)
456{
457 MMAPString * mmapstr;
458 int r;
459 int res;
460 size_t cur_token;
461
462 cur_token = 0;
463
464 /* skip header */
465
466 while (1) {
467 r = mailimf_ignore_field_parse(mime->mm_mime_start,
468 mime->mm_length, &cur_token);
469 if (r == MAILIMF_NO_ERROR) {
470 /* do nothing */
471 }
472 else
473 break;
474 }
475
476 r = mailimf_crlf_parse(mime->mm_mime_start, mime->mm_length, &cur_token);
477 if ((r != MAILIMF_NO_ERROR) && (r != MAILIMF_ERROR_PARSE)) {
478 res = maildriver_imf_error_to_mail_error(r);
479 goto err;
480 }
481
482 mmapstr = mmap_string_new_len(mime->mm_mime_start, cur_token);
483 if (mmapstr == NULL) {
484 res = MAIL_ERROR_MEMORY;
485 goto err;
486 }
487
488 r = mmap_string_ref(mmapstr);
489 if (r < 0) {
490 res = MAIL_ERROR_MEMORY;
491 goto free_mmap;
492 }
493
494 * result = mmapstr->str;
495 * result_len = mmapstr->len;
496
497 return MAIL_NO_ERROR;
498
499 free_mmap:
500 mmap_string_free(mmapstr);
501 err:
502 return res;
503}
504
505int
506mailmessage_generic_fetch_section_body(mailmessage * msg_info,
507 struct mailmime * mime,
508 char ** result,
509 size_t * result_len)
510{
511 MMAPString * mmapstr;
512 int r;
513 int res;
514 size_t cur_token;
515
516 cur_token = 0;
517
518 if (mime->mm_type == MAILMIME_MESSAGE) {
519
520 /* skip header */
521
522 while (1) {
523 r = mailimf_ignore_field_parse(mime->mm_body->dt_data.dt_text.dt_data,
524 mime->mm_body->dt_data.dt_text.dt_length, &cur_token);
525 if (r == MAILIMF_NO_ERROR) {
526 /* do nothing */
527 }
528 else
529 break;
530 }
531
532 r = mailimf_crlf_parse(mime->mm_body->dt_data.dt_text.dt_data,
533 mime->mm_body->dt_data.dt_text.dt_length, &cur_token);
534 if ((r != MAILIMF_NO_ERROR) && (r != MAILIMF_ERROR_PARSE)) {
535 res = maildriver_imf_error_to_mail_error(r);
536 goto err;
537 }
538 }
539
540 mmapstr = mmap_string_new_len(mime->mm_body->dt_data.dt_text.dt_data +
541 cur_token, mime->mm_body->dt_data.dt_text.dt_length - cur_token);
542 if (mmapstr == NULL) {
543 res = MAIL_ERROR_MEMORY;
544 goto err;
545 }
546
547 r = mmap_string_ref(mmapstr);
548 if (r < 0) {
549 res = MAIL_ERROR_MEMORY;
550 goto free_mmap;
551 }
552
553 * result = mmapstr->str;
554 * result_len = mmapstr->len;
555
556 return MAIL_NO_ERROR;
557
558 free_mmap:
559 mmap_string_free(mmapstr);
560 err:
561 return res;
562}
563
564int mailmessage_generic_fetch_envelope(mailmessage * msg_info,
565 struct mailimf_fields ** result)
566{
567 int r;
568 int res;
569 size_t cur_token;
570 char * header;
571 size_t length;
572 struct mailimf_fields * fields;
573
574 r = mailmessage_fetch_header(msg_info, &header, &length);
575 if (r != MAIL_NO_ERROR) {
576 res = r;
577 goto err;
578 }
579
580 cur_token = 0;
581
582 r = mailimf_envelope_fields_parse(header, length, &cur_token,
583 &fields);
584 if (r != MAILIMF_NO_ERROR) {
585 res = maildriver_imf_error_to_mail_error(r);
586 goto free;
587 /* do nothing */
588 }
589
590 mailmessage_fetch_result_free(msg_info, header);
591
592 * result = fields;
593
594 return MAIL_NO_ERROR;
595
596 free:
597 mailmessage_fetch_result_free(msg_info, header);
598 err:
599 return res;
600}