Diffstat (limited to 'libetpan/src/low-level/mime/mailmime_types_helper.c') (more/less context) (ignore whitespace changes)
-rw-r--r-- | libetpan/src/low-level/mime/mailmime_types_helper.c | 1385 |
1 files changed, 1385 insertions, 0 deletions
diff --git a/libetpan/src/low-level/mime/mailmime_types_helper.c b/libetpan/src/low-level/mime/mailmime_types_helper.c new file mode 100644 index 0000000..e45330c --- a/dev/null +++ b/libetpan/src/low-level/mime/mailmime_types_helper.c | |||
@@ -0,0 +1,1385 @@ | |||
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 "mailmime_types_helper.h" | ||
37 | #include "clist.h" | ||
38 | |||
39 | #include "mailmime.h" | ||
40 | |||
41 | #include <string.h> | ||
42 | #include <time.h> | ||
43 | #include <sys/types.h> | ||
44 | #include <unistd.h> | ||
45 | #include <stdlib.h> | ||
46 | |||
47 | #define MIME_VERSION (1 << 16) | ||
48 | |||
49 | int mailmime_transfer_encoding_get(struct mailmime_fields * fields) | ||
50 | { | ||
51 | clistiter * cur; | ||
52 | |||
53 | for(cur = clist_begin(fields->fld_list) ; | ||
54 | cur != NULL ; cur = clist_next(cur)) { | ||
55 | struct mailmime_field * field; | ||
56 | |||
57 | field = clist_content(cur); | ||
58 | if (field->fld_type == MAILMIME_FIELD_TRANSFER_ENCODING) | ||
59 | return field->fld_data.fld_encoding->enc_type; | ||
60 | } | ||
61 | |||
62 | return MAILMIME_MECHANISM_8BIT; | ||
63 | } | ||
64 | |||
65 | struct mailmime_disposition * | ||
66 | mailmime_disposition_new_filename(int type, char * filename) | ||
67 | { | ||
68 | return mailmime_disposition_new_with_data(type, filename, | ||
69 | NULL, NULL, NULL, (size_t) -1); | ||
70 | |||
71 | } | ||
72 | |||
73 | struct mailmime_fields * mailmime_fields_new_empty(void) | ||
74 | { | ||
75 | clist * list; | ||
76 | struct mailmime_fields * fields; | ||
77 | |||
78 | list = clist_new(); | ||
79 | if (list == NULL) | ||
80 | goto err; | ||
81 | |||
82 | fields = mailmime_fields_new(list); | ||
83 | if (fields == NULL) | ||
84 | goto free; | ||
85 | |||
86 | return fields; | ||
87 | |||
88 | free: | ||
89 | clist_free(list); | ||
90 | err: | ||
91 | return NULL; | ||
92 | } | ||
93 | |||
94 | int mailmime_fields_add(struct mailmime_fields * fields, | ||
95 | struct mailmime_field * field) | ||
96 | { | ||
97 | int r; | ||
98 | |||
99 | r = clist_append(fields->fld_list, field); | ||
100 | if (r < 0) | ||
101 | return MAILIMF_ERROR_MEMORY; | ||
102 | |||
103 | return MAILIMF_NO_ERROR; | ||
104 | } | ||
105 | |||
106 | static void mailmime_field_detach(struct mailmime_field * field) | ||
107 | { | ||
108 | switch (field->fld_type) { | ||
109 | case MAILMIME_FIELD_TYPE: | ||
110 | field->fld_data.fld_content = NULL; | ||
111 | break; | ||
112 | case MAILMIME_FIELD_TRANSFER_ENCODING: | ||
113 | field->fld_data.fld_encoding = NULL; | ||
114 | break; | ||
115 | case MAILMIME_FIELD_ID: | ||
116 | field->fld_data.fld_id = NULL; | ||
117 | break; | ||
118 | case MAILMIME_FIELD_DESCRIPTION: | ||
119 | field->fld_data.fld_description = NULL; | ||
120 | break; | ||
121 | case MAILMIME_FIELD_DISPOSITION: | ||
122 | field->fld_data.fld_disposition = NULL; | ||
123 | break; | ||
124 | case MAILMIME_FIELD_LANGUAGE: | ||
125 | field->fld_data.fld_language = NULL; | ||
126 | break; | ||
127 | } | ||
128 | } | ||
129 | |||
130 | struct mailmime_fields * | ||
131 | mailmime_fields_new_with_data(struct mailmime_mechanism * encoding, | ||
132 | char * id, | ||
133 | char * description, | ||
134 | struct mailmime_disposition * disposition, | ||
135 | struct mailmime_language * language) | ||
136 | { | ||
137 | struct mailmime_field * field; | ||
138 | struct mailmime_fields * fields; | ||
139 | int r; | ||
140 | |||
141 | fields = mailmime_fields_new_empty(); | ||
142 | if (fields == NULL) | ||
143 | goto err; | ||
144 | |||
145 | #if 0 | ||
146 | if (content != NULL) { | ||
147 | field = mailmime_field_new(MAILMIME_FIELD_TYPE, | ||
148 | content, NULL, NULL, NULL, 0, NULL, NULL); | ||
149 | if (field == NULL) | ||
150 | goto free; | ||
151 | |||
152 | r = mailmime_fields_add(fields, field); | ||
153 | if (r != MAILIMF_NO_ERROR) { | ||
154 | mailmime_field_detach(field); | ||
155 | mailmime_field_free(field); | ||
156 | goto free; | ||
157 | } | ||
158 | } | ||
159 | #endif | ||
160 | |||
161 | if (encoding != NULL) { | ||
162 | field = mailmime_field_new(MAILMIME_FIELD_TRANSFER_ENCODING, | ||
163 | NULL, encoding, NULL, NULL, 0, NULL, NULL); | ||
164 | if (field == NULL) | ||
165 | goto free; | ||
166 | |||
167 | r = mailmime_fields_add(fields, field); | ||
168 | if (r != MAILIMF_NO_ERROR) { | ||
169 | mailmime_field_detach(field); | ||
170 | mailmime_field_free(field); | ||
171 | goto free; | ||
172 | } | ||
173 | } | ||
174 | |||
175 | if (id != NULL) { | ||
176 | field = mailmime_field_new(MAILMIME_FIELD_ID, | ||
177 | NULL, NULL, id, NULL, 0, NULL, NULL); | ||
178 | if (field == NULL) | ||
179 | goto free; | ||
180 | |||
181 | r = mailmime_fields_add(fields, field); | ||
182 | if (r != MAILIMF_NO_ERROR) { | ||
183 | mailmime_field_detach(field); | ||
184 | mailmime_field_free(field); | ||
185 | goto free; | ||
186 | } | ||
187 | } | ||
188 | |||
189 | if (description != NULL) { | ||
190 | field = mailmime_field_new(MAILMIME_FIELD_DESCRIPTION, | ||
191 | NULL, NULL, NULL, description, 0, NULL, NULL); | ||
192 | if (field == NULL) | ||
193 | goto free; | ||
194 | |||
195 | r = mailmime_fields_add(fields, field); | ||
196 | if (r != MAILIMF_NO_ERROR) { | ||
197 | mailmime_field_detach(field); | ||
198 | mailmime_field_free(field); | ||
199 | goto free; | ||
200 | } | ||
201 | } | ||
202 | |||
203 | if (disposition != NULL) { | ||
204 | field = mailmime_field_new(MAILMIME_FIELD_DISPOSITION, | ||
205 | NULL, NULL, NULL, NULL, 0, disposition, NULL); | ||
206 | if (field == NULL) | ||
207 | goto free; | ||
208 | |||
209 | r = mailmime_fields_add(fields, field); | ||
210 | if (r != MAILIMF_NO_ERROR) { | ||
211 | mailmime_field_detach(field); | ||
212 | mailmime_field_free(field); | ||
213 | goto free; | ||
214 | } | ||
215 | } | ||
216 | |||
217 | if (language != NULL) { | ||
218 | field = mailmime_field_new(MAILMIME_FIELD_DISPOSITION, | ||
219 | NULL, NULL, NULL, NULL, 0, NULL, language); | ||
220 | if (field == NULL) | ||
221 | goto free; | ||
222 | |||
223 | r = mailmime_fields_add(fields, field); | ||
224 | if (r != MAILIMF_NO_ERROR) { | ||
225 | mailmime_field_detach(field); | ||
226 | mailmime_field_free(field); | ||
227 | goto free; | ||
228 | } | ||
229 | } | ||
230 | |||
231 | return fields; | ||
232 | |||
233 | free: | ||
234 | clist_foreach(fields->fld_list, (clist_func) mailmime_field_detach, NULL); | ||
235 | mailmime_fields_free(fields); | ||
236 | err: | ||
237 | return NULL; | ||
238 | } | ||
239 | |||
240 | struct mailmime_fields * | ||
241 | mailmime_fields_new_with_version(struct mailmime_mechanism * encoding, | ||
242 | char * id, | ||
243 | char * description, | ||
244 | struct mailmime_disposition * disposition, | ||
245 | struct mailmime_language * language) | ||
246 | { | ||
247 | struct mailmime_field * field; | ||
248 | struct mailmime_fields * fields; | ||
249 | int r; | ||
250 | |||
251 | fields = mailmime_fields_new_with_data(encoding, id, description, | ||
252 | disposition, language); | ||
253 | if (fields == NULL) | ||
254 | goto err; | ||
255 | |||
256 | field = mailmime_field_new(MAILMIME_FIELD_VERSION, | ||
257 | NULL, NULL, NULL, NULL, MIME_VERSION, NULL, NULL); | ||
258 | if (field == NULL) | ||
259 | goto free; | ||
260 | |||
261 | r = mailmime_fields_add(fields, field); | ||
262 | if (r != MAILIMF_NO_ERROR) { | ||
263 | mailmime_field_detach(field); | ||
264 | mailmime_field_free(field); | ||
265 | goto free; | ||
266 | } | ||
267 | |||
268 | return fields; | ||
269 | |||
270 | free: | ||
271 | clist_foreach(fields->fld_list, (clist_func) mailmime_field_detach, NULL); | ||
272 | mailmime_fields_free(fields); | ||
273 | err: | ||
274 | return NULL; | ||
275 | } | ||
276 | |||
277 | |||
278 | struct mailmime_content * mailmime_get_content_message(void) | ||
279 | { | ||
280 | clist * list; | ||
281 | struct mailmime_composite_type * composite_type; | ||
282 | struct mailmime_type * mime_type; | ||
283 | struct mailmime_content * content; | ||
284 | char * subtype; | ||
285 | |||
286 | composite_type = | ||
287 | mailmime_composite_type_new(MAILMIME_COMPOSITE_TYPE_MESSAGE, | ||
288 | NULL); | ||
289 | if (composite_type == NULL) | ||
290 | goto err; | ||
291 | |||
292 | mime_type = mailmime_type_new(MAILMIME_TYPE_COMPOSITE_TYPE, | ||
293 | NULL, composite_type); | ||
294 | if (mime_type == NULL) | ||
295 | goto free_composite; | ||
296 | composite_type = NULL; | ||
297 | |||
298 | list = clist_new(); | ||
299 | if (list == NULL) | ||
300 | goto free_mime_type; | ||
301 | |||
302 | subtype = strdup("rfc822"); | ||
303 | if (subtype == NULL) | ||
304 | goto free_list; | ||
305 | |||
306 | content = mailmime_content_new(mime_type, subtype, list); | ||
307 | if (content == NULL) | ||
308 | goto free_subtype; | ||
309 | |||
310 | return content; | ||
311 | |||
312 | free_subtype: | ||
313 | free(subtype); | ||
314 | free_list: | ||
315 | clist_free(list); | ||
316 | free_mime_type: | ||
317 | mailmime_type_free(mime_type); | ||
318 | free_composite: | ||
319 | if (composite_type != NULL) | ||
320 | mailmime_composite_type_free(composite_type); | ||
321 | err: | ||
322 | return NULL; | ||
323 | } | ||
324 | |||
325 | struct mailmime_content * mailmime_get_content_text(void) | ||
326 | { | ||
327 | clist * list; | ||
328 | struct mailmime_discrete_type * discrete_type; | ||
329 | struct mailmime_type * mime_type; | ||
330 | struct mailmime_content * content; | ||
331 | char * subtype; | ||
332 | |||
333 | discrete_type = mailmime_discrete_type_new(MAILMIME_DISCRETE_TYPE_TEXT, | ||
334 | NULL); | ||
335 | if (discrete_type == NULL) | ||
336 | goto err; | ||
337 | |||
338 | mime_type = mailmime_type_new(MAILMIME_TYPE_DISCRETE_TYPE, | ||
339 | discrete_type, NULL); | ||
340 | if (mime_type == NULL) | ||
341 | goto free_discrete; | ||
342 | discrete_type = NULL; | ||
343 | |||
344 | list = clist_new(); | ||
345 | if (list == NULL) | ||
346 | goto free_type; | ||
347 | |||
348 | subtype = strdup("plain"); | ||
349 | if (subtype == NULL) | ||
350 | goto free_list; | ||
351 | |||
352 | content = mailmime_content_new(mime_type, subtype, list); | ||
353 | if (content == NULL) | ||
354 | goto free_subtype; | ||
355 | |||
356 | return content; | ||
357 | |||
358 | free_subtype: | ||
359 | free(subtype); | ||
360 | free_list: | ||
361 | clist_free(list); | ||
362 | free_type: | ||
363 | mailmime_type_free(mime_type); | ||
364 | free_discrete: | ||
365 | if (discrete_type != NULL) | ||
366 | mailmime_discrete_type_free(discrete_type); | ||
367 | err: | ||
368 | return NULL; | ||
369 | } | ||
370 | |||
371 | |||
372 | |||
373 | |||
374 | |||
375 | |||
376 | |||
377 | |||
378 | /* mailmime build */ | ||
379 | |||
380 | |||
381 | #if 0 | ||
382 | struct mailmime * | ||
383 | mailmime_new_message_file(char * filename) | ||
384 | { | ||
385 | struct mailmime_content * content; | ||
386 | struct mailmime * build_info; | ||
387 | struct mailmime_data * msg_content; | ||
388 | struct mailmime_fields * mime_fields; | ||
389 | |||
390 | content = mailmime_get_content_message(); | ||
391 | if (content == NULL) { | ||
392 | goto err; | ||
393 | } | ||
394 | |||
395 | mime_fields = mailmime_fields_new_with_version(NULL, NULL, | ||
396 | NULL, NULL, NULL); | ||
397 | if (mime_fields == NULL) | ||
398 | goto free_content; | ||
399 | |||
400 | msg_content = mailmime_data_new(MAILMIME_DATA_FILE, MAILMIME_MECHANISM_8BIT, | ||
401 | 1, NULL, 0, filename); | ||
402 | if (msg_content == NULL) | ||
403 | goto free_fields; | ||
404 | |||
405 | build_info = mailmime_new(MAILMIME_MESSAGE, | ||
406 | NULL, 0, mime_fields, content, | ||
407 | msg_content, NULL, NULL, NULL, NULL, NULL); | ||
408 | if (build_info == NULL) | ||
409 | goto free_msg_content; | ||
410 | |||
411 | return build_info; | ||
412 | |||
413 | free_msg_content: | ||
414 | mailmime_data_free(msg_content); | ||
415 | free_fields: | ||
416 | mailmime_fields_free(mime_fields); | ||
417 | free_content: | ||
418 | mailmime_content_free(content); | ||
419 | err: | ||
420 | return NULL; | ||
421 | } | ||
422 | |||
423 | struct mailmime * | ||
424 | mailmime_new_message_text(char * data_str, size_t length) | ||
425 | { | ||
426 | struct mailmime_content * content; | ||
427 | struct mailmime * build_info; | ||
428 | struct mailmime_data * msg_content; | ||
429 | struct mailmime_fields * mime_fields; | ||
430 | |||
431 | content = mailmime_get_content_message(); | ||
432 | if (content == NULL) { | ||
433 | goto err; | ||
434 | } | ||
435 | |||
436 | mime_fields = mailmime_fields_new_with_version(NULL, NULL, | ||
437 | NULL, NULL, NULL); | ||
438 | if (mime_fields == NULL) | ||
439 | goto free_fields; | ||
440 | |||
441 | msg_content = mailmime_data_new(MAILMIME_DATA_TEXT, MAILMIME_MECHANISM_8BIT, | ||
442 | 1, data_str, length, NULL); | ||
443 | if (msg_content == NULL) | ||
444 | goto free_content; | ||
445 | |||
446 | build_info = mailmime_new(MAILMIME_MESSAGE, | ||
447 | NULL, 0, mime_fields, content, | ||
448 | msg_content, NULL, NULL, NULL, | ||
449 | NULL, NULL); | ||
450 | if (build_info == NULL) | ||
451 | goto free_msg_content; | ||
452 | |||
453 | return build_info; | ||
454 | |||
455 | free_msg_content: | ||
456 | mailmime_data_free(msg_content); | ||
457 | free_fields: | ||
458 | mailmime_fields_free(mime_fields); | ||
459 | free_content: | ||
460 | mailmime_content_free(content); | ||
461 | err: | ||
462 | return NULL; | ||
463 | } | ||
464 | #endif | ||
465 | |||
466 | struct mailmime * | ||
467 | mailmime_new_message_data(struct mailmime * msg_mime) | ||
468 | { | ||
469 | struct mailmime_content * content; | ||
470 | struct mailmime * build_info; | ||
471 | struct mailmime_fields * mime_fields; | ||
472 | |||
473 | content = mailmime_get_content_message(); | ||
474 | if (content == NULL) | ||
475 | goto err; | ||
476 | |||
477 | mime_fields = mailmime_fields_new_with_version(NULL, NULL, | ||
478 | NULL, NULL, NULL); | ||
479 | if (mime_fields == NULL) | ||
480 | goto free_content; | ||
481 | |||
482 | build_info = mailmime_new(MAILMIME_MESSAGE, | ||
483 | NULL, 0, mime_fields, content, | ||
484 | NULL, NULL, NULL, NULL, | ||
485 | NULL, msg_mime); | ||
486 | if (build_info == NULL) | ||
487 | goto free_fields; | ||
488 | |||
489 | return build_info; | ||
490 | |||
491 | free_fields: | ||
492 | mailmime_fields_free(mime_fields); | ||
493 | free_content: | ||
494 | mailmime_content_free(content); | ||
495 | err: | ||
496 | return NULL; | ||
497 | } | ||
498 | |||
499 | #define MAX_MESSAGE_ID 512 | ||
500 | |||
501 | static char * generate_boundary() | ||
502 | { | ||
503 | char id[MAX_MESSAGE_ID]; | ||
504 | time_t now; | ||
505 | char name[MAX_MESSAGE_ID]; | ||
506 | long value; | ||
507 | |||
508 | now = time(NULL); | ||
509 | value = random(); | ||
510 | |||
511 | gethostname(name, MAX_MESSAGE_ID); | ||
512 | snprintf(id, MAX_MESSAGE_ID, "%lx_%lx_%x", now, value, getpid()); | ||
513 | |||
514 | return strdup(id); | ||
515 | } | ||
516 | |||
517 | struct mailmime * | ||
518 | mailmime_new_empty(struct mailmime_content * content, | ||
519 | struct mailmime_fields * mime_fields) | ||
520 | { | ||
521 | struct mailmime * build_info; | ||
522 | clist * list; | ||
523 | int r; | ||
524 | int mime_type; | ||
525 | |||
526 | list = NULL; | ||
527 | |||
528 | switch (content->ct_type->tp_type) { | ||
529 | case MAILMIME_TYPE_DISCRETE_TYPE: | ||
530 | mime_type = MAILMIME_SINGLE; | ||
531 | break; | ||
532 | |||
533 | case MAILMIME_TYPE_COMPOSITE_TYPE: | ||
534 | switch (content->ct_type->tp_data.tp_composite_type->ct_type) { | ||
535 | case MAILMIME_COMPOSITE_TYPE_MULTIPART: | ||
536 | mime_type = MAILMIME_MULTIPLE; | ||
537 | break; | ||
538 | |||
539 | case MAILMIME_COMPOSITE_TYPE_MESSAGE: | ||
540 | if (strcasecmp(content->ct_subtype, "rfc822") == 0) | ||
541 | mime_type = MAILMIME_MESSAGE; | ||
542 | else | ||
543 | mime_type = MAILMIME_SINGLE; | ||
544 | break; | ||
545 | |||
546 | default: | ||
547 | goto err; | ||
548 | } | ||
549 | break; | ||
550 | |||
551 | default: | ||
552 | goto err; | ||
553 | } | ||
554 | |||
555 | if (mime_type == MAILMIME_MULTIPLE) { | ||
556 | char * attr_name; | ||
557 | char * attr_value; | ||
558 | struct mailmime_parameter * param; | ||
559 | clist * parameters; | ||
560 | char * boundary; | ||
561 | |||
562 | list = clist_new(); | ||
563 | if (list == NULL) | ||
564 | goto err; | ||
565 | |||
566 | attr_name = strdup("boundary"); | ||
567 | if (attr_name == NULL) | ||
568 | goto free_list; | ||
569 | |||
570 | boundary = generate_boundary(); | ||
571 | attr_value = boundary; | ||
572 | if (attr_name == NULL) { | ||
573 | free(attr_name); | ||
574 | goto free_list; | ||
575 | } | ||
576 | |||
577 | param = mailmime_parameter_new(attr_name, attr_value); | ||
578 | if (param == NULL) { | ||
579 | free(attr_value); | ||
580 | free(attr_name); | ||
581 | goto free_list; | ||
582 | } | ||
583 | |||
584 | if (content->ct_parameters == NULL) { | ||
585 | parameters = clist_new(); | ||
586 | if (parameters == NULL) { | ||
587 | mailmime_parameter_free(param); | ||
588 | goto free_list; | ||
589 | } | ||
590 | } | ||
591 | else | ||
592 | parameters = content->ct_parameters; | ||
593 | |||
594 | r = clist_append(parameters, param); | ||
595 | if (r != 0) { | ||
596 | clist_free(parameters); | ||
597 | mailmime_parameter_free(param); | ||
598 | goto free_list; | ||
599 | } | ||
600 | |||
601 | if (content->ct_parameters == NULL) | ||
602 | content->ct_parameters = parameters; | ||
603 | } | ||
604 | |||
605 | build_info = mailmime_new(mime_type, | ||
606 | NULL, 0, mime_fields, content, | ||
607 | NULL, NULL, NULL, list, | ||
608 | NULL, NULL); | ||
609 | if (build_info == NULL) { | ||
610 | clist_free(list); | ||
611 | return NULL; | ||
612 | } | ||
613 | |||
614 | return build_info; | ||
615 | |||
616 | free_list: | ||
617 | clist_free(list); | ||
618 | err: | ||
619 | return NULL; | ||
620 | } | ||
621 | |||
622 | |||
623 | int | ||
624 | mailmime_new_with_content(const char * content_type, | ||
625 | struct mailmime_fields * mime_fields, | ||
626 | struct mailmime ** result) | ||
627 | { | ||
628 | int r; | ||
629 | size_t cur_token; | ||
630 | struct mailmime_content * content; | ||
631 | struct mailmime * build_info; | ||
632 | #if 0 | ||
633 | int mime_type; | ||
634 | #endif | ||
635 | int res; | ||
636 | |||
637 | cur_token = 0; | ||
638 | r = mailmime_content_parse(content_type, strlen(content_type), | ||
639 | &cur_token, | ||
640 | &content); | ||
641 | if (r != MAILIMF_NO_ERROR) { | ||
642 | res = r; | ||
643 | goto err; | ||
644 | } | ||
645 | |||
646 | #if 0 | ||
647 | switch (content->type->type) { | ||
648 | case MAILMIME_TYPE_DISCRETE_TYPE: | ||
649 | mime_type = MAILMIME_SINGLE; | ||
650 | break; | ||
651 | |||
652 | case MAILMIME_TYPE_COMPOSITE_TYPE: | ||
653 | switch (content->type->composite_type->type) { | ||
654 | case MAILMIME_COMPOSITE_TYPE_MULTIPART: | ||
655 | mime_type = MAILMIME_MULTIPLE; | ||
656 | break; | ||
657 | |||
658 | case MAILMIME_COMPOSITE_TYPE_MESSAGE: | ||
659 | if (strcasecmp(content->subtype, "rfc822") == 0) | ||
660 | mime_type = MAILMIME_MESSAGE; | ||
661 | else | ||
662 | mime_type = MAILMIME_SINGLE; | ||
663 | break; | ||
664 | |||
665 | default: | ||
666 | res = MAILIMF_ERROR_INVAL; | ||
667 | goto free; | ||
668 | } | ||
669 | break; | ||
670 | |||
671 | default: | ||
672 | res = MAILIMF_ERROR_INVAL; | ||
673 | goto free; | ||
674 | } | ||
675 | #endif | ||
676 | |||
677 | build_info = mailmime_new_empty(content, mime_fields); | ||
678 | if (build_info == NULL) { | ||
679 | res = MAILIMF_ERROR_MEMORY; | ||
680 | goto free; | ||
681 | } | ||
682 | |||
683 | * result = build_info; | ||
684 | |||
685 | return MAILIMF_NO_ERROR; | ||
686 | |||
687 | free: | ||
688 | mailmime_content_free(content); | ||
689 | err: | ||
690 | return res; | ||
691 | } | ||
692 | |||
693 | int mailmime_set_preamble_file(struct mailmime * build_info, | ||
694 | char * filename) | ||
695 | { | ||
696 | struct mailmime_data * data; | ||
697 | |||
698 | data = mailmime_data_new(MAILMIME_DATA_FILE, MAILMIME_MECHANISM_8BIT, | ||
699 | 0, NULL, 0, filename); | ||
700 | if (data == NULL) | ||
701 | return MAILIMF_ERROR_MEMORY; | ||
702 | |||
703 | build_info->mm_data.mm_multipart.mm_preamble = data; | ||
704 | |||
705 | return MAILIMF_NO_ERROR; | ||
706 | } | ||
707 | |||
708 | int mailmime_set_epilogue_file(struct mailmime * build_info, | ||
709 | char * filename) | ||
710 | { | ||
711 | struct mailmime_data * data; | ||
712 | |||
713 | data = mailmime_data_new(MAILMIME_DATA_FILE, MAILMIME_MECHANISM_8BIT, | ||
714 | 0, NULL, 0, filename); | ||
715 | if (data == NULL) | ||
716 | return MAILIMF_ERROR_MEMORY; | ||
717 | |||
718 | build_info->mm_data.mm_multipart.mm_epilogue = data; | ||
719 | |||
720 | return MAILIMF_NO_ERROR; | ||
721 | } | ||
722 | |||
723 | int mailmime_set_preamble_text(struct mailmime * build_info, | ||
724 | char * data_str, size_t length) | ||
725 | { | ||
726 | struct mailmime_data * data; | ||
727 | |||
728 | data = mailmime_data_new(MAILMIME_DATA_TEXT, MAILMIME_MECHANISM_8BIT, | ||
729 | 0, data_str, length, NULL); | ||
730 | if (data == NULL) | ||
731 | return MAILIMF_ERROR_MEMORY; | ||
732 | |||
733 | build_info->mm_data.mm_multipart.mm_preamble = data; | ||
734 | |||
735 | return MAILIMF_NO_ERROR; | ||
736 | } | ||
737 | |||
738 | int mailmime_set_epilogue_text(struct mailmime * build_info, | ||
739 | char * data_str, size_t length) | ||
740 | { | ||
741 | struct mailmime_data * data; | ||
742 | |||
743 | data = mailmime_data_new(MAILMIME_DATA_TEXT, MAILMIME_MECHANISM_8BIT, | ||
744 | 0, data_str, length, NULL); | ||
745 | if (data == NULL) | ||
746 | return MAILIMF_ERROR_MEMORY; | ||
747 | |||
748 | build_info->mm_data.mm_multipart.mm_epilogue = data; | ||
749 | |||
750 | return MAILIMF_NO_ERROR; | ||
751 | } | ||
752 | |||
753 | |||
754 | int mailmime_set_body_file(struct mailmime * build_info, | ||
755 | char * filename) | ||
756 | { | ||
757 | int encoding; | ||
758 | struct mailmime_data * data; | ||
759 | |||
760 | encoding = mailmime_transfer_encoding_get(build_info->mm_mime_fields); | ||
761 | |||
762 | data = mailmime_data_new(MAILMIME_DATA_FILE, encoding, | ||
763 | 0, NULL, 0, filename); | ||
764 | if (data == NULL) | ||
765 | return MAILIMF_ERROR_MEMORY; | ||
766 | |||
767 | build_info->mm_data.mm_single = data; | ||
768 | |||
769 | return MAILIMF_NO_ERROR; | ||
770 | } | ||
771 | |||
772 | int mailmime_set_body_text(struct mailmime * build_info, | ||
773 | char * data_str, size_t length) | ||
774 | { | ||
775 | int encoding; | ||
776 | struct mailmime_data * data; | ||
777 | |||
778 | encoding = mailmime_transfer_encoding_get(build_info->mm_mime_fields); | ||
779 | |||
780 | data = mailmime_data_new(MAILMIME_DATA_TEXT, encoding, | ||
781 | 0, data_str, length, NULL); | ||
782 | if (data == NULL) | ||
783 | return MAILIMF_ERROR_MEMORY; | ||
784 | |||
785 | build_info->mm_data.mm_single = data; | ||
786 | |||
787 | return MAILIMF_NO_ERROR; | ||
788 | } | ||
789 | |||
790 | |||
791 | /* add a part as subpart of a mime part */ | ||
792 | |||
793 | int mailmime_add_part(struct mailmime * build_info, | ||
794 | struct mailmime * part) | ||
795 | { | ||
796 | int r; | ||
797 | |||
798 | if (build_info->mm_type == MAILMIME_MESSAGE) { | ||
799 | build_info->mm_data.mm_message.mm_msg_mime = part; | ||
800 | part->mm_parent_type = MAILMIME_MESSAGE; | ||
801 | part->mm_parent = build_info; | ||
802 | } | ||
803 | else if (build_info->mm_type == MAILMIME_MULTIPLE) { | ||
804 | r = clist_append(build_info->mm_data.mm_multipart.mm_mp_list, part); | ||
805 | if (r != 0) | ||
806 | return MAILIMF_ERROR_MEMORY; | ||
807 | |||
808 | part->mm_parent_type = MAILMIME_MULTIPLE; | ||
809 | part->mm_parent = build_info; | ||
810 | part->mm_multipart_pos = | ||
811 | clist_end(build_info->mm_data.mm_multipart.mm_mp_list); | ||
812 | } | ||
813 | else { | ||
814 | return MAILIMF_ERROR_INVAL; | ||
815 | } | ||
816 | return MAILIMF_NO_ERROR; | ||
817 | } | ||
818 | |||
819 | /* detach part from parent */ | ||
820 | |||
821 | void mailmime_remove_part(struct mailmime * mime) | ||
822 | { | ||
823 | struct mailmime * parent; | ||
824 | |||
825 | parent = mime->mm_parent; | ||
826 | if (parent == NULL) | ||
827 | return; | ||
828 | |||
829 | switch (mime->mm_parent_type) { | ||
830 | case MAILMIME_MESSAGE: | ||
831 | mime->mm_parent = NULL; | ||
832 | parent->mm_data.mm_message.mm_msg_mime = NULL; | ||
833 | break; | ||
834 | |||
835 | case MAILMIME_MULTIPLE: | ||
836 | mime->mm_parent = NULL; | ||
837 | clist_delete(parent->mm_data.mm_multipart.mm_mp_list, | ||
838 | mime->mm_multipart_pos); | ||
839 | break; | ||
840 | } | ||
841 | } | ||
842 | |||
843 | |||
844 | /* | ||
845 | attach a part to a mime part and create multipart/mixed | ||
846 | when needed, when the parent part has already some part | ||
847 | attached to it. | ||
848 | */ | ||
849 | |||
850 | int mailmime_smart_add_part(struct mailmime * mime, | ||
851 | struct mailmime * mime_sub) | ||
852 | { | ||
853 | struct mailmime * saved_sub; | ||
854 | struct mailmime * mp; | ||
855 | int res; | ||
856 | int r; | ||
857 | |||
858 | switch (mime->mm_type) { | ||
859 | case MAILMIME_SINGLE: | ||
860 | res = MAILIMF_ERROR_INVAL; | ||
861 | goto err; | ||
862 | |||
863 | case MAILMIME_MULTIPLE: | ||
864 | r = mailmime_add_part(mime, mime_sub); | ||
865 | if (r != MAILIMF_NO_ERROR) { | ||
866 | res = MAILIMF_ERROR_MEMORY; | ||
867 | goto err; | ||
868 | } | ||
869 | |||
870 | return MAILIMF_NO_ERROR; | ||
871 | } | ||
872 | |||
873 | /* MAILMIME_MESSAGE */ | ||
874 | |||
875 | if (mime->mm_data.mm_message.mm_msg_mime == NULL) { | ||
876 | /* there is no subpart, we can simply attach it */ | ||
877 | |||
878 | r = mailmime_add_part(mime, mime_sub); | ||
879 | if (r != MAILIMF_NO_ERROR) { | ||
880 | res = MAILIMF_ERROR_MEMORY; | ||
881 | goto err; | ||
882 | } | ||
883 | |||
884 | return MAILIMF_NO_ERROR; | ||
885 | } | ||
886 | |||
887 | if (mime->mm_data.mm_message.mm_msg_mime->mm_type == MAILMIME_MULTIPLE) { | ||
888 | /* in case the subpart is multipart, simply attach it to the subpart */ | ||
889 | |||
890 | return mailmime_add_part(mime->mm_data.mm_message.mm_msg_mime, mime_sub); | ||
891 | } | ||
892 | |||
893 | /* we save the current subpart, ... */ | ||
894 | |||
895 | saved_sub = mime->mm_data.mm_message.mm_msg_mime; | ||
896 | |||
897 | /* create a multipart */ | ||
898 | |||
899 | mp = mailmime_multiple_new("multipart/mixed"); | ||
900 | if (mp == NULL) { | ||
901 | res = MAILIMF_ERROR_MEMORY; | ||
902 | goto err; | ||
903 | } | ||
904 | |||
905 | /* detach the saved subpart from the parent */ | ||
906 | |||
907 | mailmime_remove_part(saved_sub); | ||
908 | |||
909 | /* the created multipart is the new child of the parent */ | ||
910 | |||
911 | r = mailmime_add_part(mime, mp); | ||
912 | if (r != MAILIMF_NO_ERROR) { | ||
913 | res = MAILIMF_ERROR_MEMORY; | ||
914 | goto free_mp; | ||
915 | } | ||
916 | |||
917 | /* then, attach the saved subpart and ... */ | ||
918 | |||
919 | r = mailmime_add_part(mp, saved_sub); | ||
920 | if (r != MAILIMF_NO_ERROR) { | ||
921 | res = MAILIMF_ERROR_MEMORY; | ||
922 | goto free_saved_sub; | ||
923 | } | ||
924 | |||
925 | /* the given part to the parent */ | ||
926 | |||
927 | r = mailmime_add_part(mp, mime_sub); | ||
928 | if (r != MAILIMF_NO_ERROR) { | ||
929 | res = MAILIMF_ERROR_MEMORY; | ||
930 | goto free_saved_sub; | ||
931 | } | ||
932 | |||
933 | return MAILIMF_NO_ERROR; | ||
934 | |||
935 | free_mp: | ||
936 | mailmime_free(mp); | ||
937 | free_saved_sub: | ||
938 | mailmime_free(saved_sub); | ||
939 | err: | ||
940 | return res; | ||
941 | } | ||
942 | |||
943 | |||
944 | |||
945 | /* detach part from parent and free it only if the part has no child */ | ||
946 | |||
947 | int mailmime_smart_remove_part(struct mailmime * mime) | ||
948 | { | ||
949 | struct mailmime * parent; | ||
950 | int res; | ||
951 | |||
952 | parent = mime->mm_parent; | ||
953 | if (parent == NULL) { | ||
954 | res = MAILIMF_ERROR_INVAL; | ||
955 | goto err; | ||
956 | } | ||
957 | |||
958 | switch (mime->mm_type) { | ||
959 | case MAILMIME_MESSAGE: | ||
960 | if (mime->mm_data.mm_message.mm_msg_mime != NULL) { | ||
961 | res = MAILIMF_ERROR_INVAL; | ||
962 | goto err; | ||
963 | } | ||
964 | |||
965 | mailmime_remove_part(mime); | ||
966 | |||
967 | mailmime_free(mime); | ||
968 | |||
969 | return MAILIMF_NO_ERROR; | ||
970 | |||
971 | case MAILMIME_MULTIPLE: | ||
972 | if (!clist_isempty(mime->mm_data.mm_multipart.mm_mp_list)) { | ||
973 | res = MAILIMF_ERROR_INVAL; | ||
974 | goto err; | ||
975 | } | ||
976 | |||
977 | mailmime_remove_part(mime); | ||
978 | |||
979 | mailmime_free(mime); | ||
980 | |||
981 | return MAILIMF_NO_ERROR; | ||
982 | |||
983 | case MAILMIME_SINGLE: | ||
984 | mailmime_remove_part(mime); | ||
985 | |||
986 | mailmime_free(mime); | ||
987 | |||
988 | return MAILIMF_NO_ERROR; | ||
989 | |||
990 | default: | ||
991 | return MAILIMF_ERROR_INVAL; | ||
992 | } | ||
993 | |||
994 | err: | ||
995 | return res; | ||
996 | } | ||
997 | |||
998 | |||
999 | /* create a mailmime_content structure (Content-Type field) */ | ||
1000 | |||
1001 | struct mailmime_content * mailmime_content_new_with_str(const char * str) | ||
1002 | { | ||
1003 | int r; | ||
1004 | size_t cur_token; | ||
1005 | struct mailmime_content * content; | ||
1006 | |||
1007 | cur_token = 0; | ||
1008 | r = mailmime_content_parse(str, strlen(str), &cur_token, &content); | ||
1009 | if (r != MAILIMF_NO_ERROR) | ||
1010 | return NULL; | ||
1011 | |||
1012 | return content; | ||
1013 | } | ||
1014 | |||
1015 | /* create MIME fields with only the field Content-Transfer-Encoding */ | ||
1016 | |||
1017 | struct mailmime_fields * mailmime_fields_new_encoding(int type) | ||
1018 | { | ||
1019 | struct mailmime_mechanism * encoding; | ||
1020 | struct mailmime_fields * mime_fields; | ||
1021 | |||
1022 | encoding = mailmime_mechanism_new(type, NULL); | ||
1023 | if (encoding == NULL) | ||
1024 | goto err; | ||
1025 | |||
1026 | mime_fields = mailmime_fields_new_with_data(encoding, | ||
1027 | NULL, NULL, NULL, NULL); | ||
1028 | if (mime_fields == NULL) | ||
1029 | goto free; | ||
1030 | |||
1031 | return mime_fields; | ||
1032 | |||
1033 | free: | ||
1034 | mailmime_mechanism_free(encoding); | ||
1035 | err: | ||
1036 | return NULL; | ||
1037 | } | ||
1038 | |||
1039 | |||
1040 | /* create a multipart MIME part */ | ||
1041 | |||
1042 | struct mailmime * mailmime_multiple_new(const char * type) | ||
1043 | { | ||
1044 | struct mailmime_fields * mime_fields; | ||
1045 | struct mailmime_content * content; | ||
1046 | struct mailmime * mp; | ||
1047 | |||
1048 | mime_fields = mailmime_fields_new_encoding(MAILMIME_MECHANISM_8BIT); | ||
1049 | if (mime_fields == NULL) | ||
1050 | goto err; | ||
1051 | |||
1052 | content = mailmime_content_new_with_str(type); | ||
1053 | if (content == NULL) | ||
1054 | goto free_fields; | ||
1055 | |||
1056 | mp = mailmime_new_empty(content, mime_fields); | ||
1057 | if (mp == NULL) | ||
1058 | goto free_content; | ||
1059 | |||
1060 | return mp; | ||
1061 | |||
1062 | free_content: | ||
1063 | mailmime_content_free(content); | ||
1064 | free_fields: | ||
1065 | mailmime_fields_free(mime_fields); | ||
1066 | err: | ||
1067 | return NULL; | ||
1068 | } | ||
1069 | |||
1070 | |||
1071 | |||
1072 | void mailmime_set_imf_fields(struct mailmime * build_info, | ||
1073 | struct mailimf_fields * mm_fields) | ||
1074 | { | ||
1075 | build_info->mm_data.mm_message.mm_fields = mm_fields; | ||
1076 | } | ||
1077 | |||
1078 | #if 0 | ||
1079 | struct mailmime_content * mailmime_get_content(char * mime_type) | ||
1080 | { | ||
1081 | struct mailmime_content *content; | ||
1082 | int r; | ||
1083 | size_t cur_token; | ||
1084 | |||
1085 | cur_token = 0; | ||
1086 | r = mailmime_content_parse(mime_type, strlen(mime_type), | ||
1087 | &cur_token, &content); | ||
1088 | if (r != MAILIMF_NO_ERROR) | ||
1089 | return NULL; | ||
1090 | |||
1091 | return content; | ||
1092 | } | ||
1093 | #endif | ||
1094 | |||
1095 | |||
1096 | |||
1097 | |||
1098 | struct mailmime_disposition * | ||
1099 | mailmime_disposition_new_with_data(int type, | ||
1100 | char * filename, char * creation_date, char * modification_date, | ||
1101 | char * read_date, size_t size) | ||
1102 | { | ||
1103 | struct mailmime_disposition_type * dsp_type; | ||
1104 | clist * list; | ||
1105 | int r; | ||
1106 | struct mailmime_disposition_parm * parm; | ||
1107 | struct mailmime_disposition * dsp; | ||
1108 | |||
1109 | dsp_type = mailmime_disposition_type_new(type, NULL); | ||
1110 | if (dsp_type == NULL) | ||
1111 | goto err; | ||
1112 | |||
1113 | list = clist_new(); | ||
1114 | if (list == NULL) | ||
1115 | goto free_dsp_type; | ||
1116 | |||
1117 | if (filename != NULL) { | ||
1118 | parm = mailmime_disposition_parm_new(MAILMIME_DISPOSITION_PARM_FILENAME, | ||
1119 | filename, NULL, NULL, NULL, 0, NULL); | ||
1120 | if (parm == NULL) | ||
1121 | goto free_list; | ||
1122 | |||
1123 | r = clist_append(list, parm); | ||
1124 | if (r < 0) { | ||
1125 | mailmime_disposition_parm_free(parm); | ||
1126 | goto free_list; | ||
1127 | } | ||
1128 | } | ||
1129 | |||
1130 | if (creation_date != NULL) { | ||
1131 | parm = mailmime_disposition_parm_new(MAILMIME_DISPOSITION_PARM_CREATION_DATE, | ||
1132 | NULL, creation_date, NULL, NULL, 0, NULL); | ||
1133 | if (parm == NULL) | ||
1134 | goto free_list; | ||
1135 | |||
1136 | r = clist_append(list, parm); | ||
1137 | if (r < 0) { | ||
1138 | mailmime_disposition_parm_free(parm); | ||
1139 | goto free_list; | ||
1140 | } | ||
1141 | } | ||
1142 | |||
1143 | if (modification_date != NULL) { | ||
1144 | parm = mailmime_disposition_parm_new(MAILMIME_DISPOSITION_PARM_MODIFICATION_DATE, | ||
1145 | NULL, NULL, modification_date, NULL, 0, NULL); | ||
1146 | if (parm == NULL) | ||
1147 | goto free_list; | ||
1148 | |||
1149 | r = clist_append(list, parm); | ||
1150 | if (r < 0) { | ||
1151 | mailmime_disposition_parm_free(parm); | ||
1152 | goto free_list; | ||
1153 | } | ||
1154 | } | ||
1155 | |||
1156 | if (read_date != NULL) { | ||
1157 | parm = mailmime_disposition_parm_new(MAILMIME_DISPOSITION_PARM_READ_DATE, | ||
1158 | NULL, NULL, NULL, read_date, 0, NULL); | ||
1159 | if (parm == NULL) | ||
1160 | goto free_list; | ||
1161 | |||
1162 | r = clist_append(list, parm); | ||
1163 | if (r < 0) { | ||
1164 | mailmime_disposition_parm_free(parm); | ||
1165 | goto free_list; | ||
1166 | } | ||
1167 | } | ||
1168 | |||
1169 | if (size != (size_t) -1) { | ||
1170 | parm = mailmime_disposition_parm_new(MAILMIME_DISPOSITION_PARM_SIZE, | ||
1171 | NULL, NULL, NULL, NULL, size, NULL); | ||
1172 | if (parm == NULL) | ||
1173 | goto free_list; | ||
1174 | |||
1175 | r = clist_append(list, parm); | ||
1176 | if (r < 0) { | ||
1177 | mailmime_disposition_parm_free(parm); | ||
1178 | goto free_list; | ||
1179 | } | ||
1180 | } | ||
1181 | |||
1182 | dsp = mailmime_disposition_new(dsp_type, list); | ||
1183 | |||
1184 | return dsp; | ||
1185 | |||
1186 | free_list: | ||
1187 | clist_foreach(list, (clist_func) mailmime_disposition_parm_free, NULL); | ||
1188 | clist_free(list); | ||
1189 | free_dsp_type: | ||
1190 | mailmime_disposition_type_free(dsp_type); | ||
1191 | err: | ||
1192 | return NULL; | ||
1193 | } | ||
1194 | |||
1195 | |||
1196 | static void mailmime_disposition_single_fields_init(struct | ||
1197 | mailmime_single_fields * single_fields, | ||
1198 | struct mailmime_disposition * fld_disposition) | ||
1199 | { | ||
1200 | clistiter * cur; | ||
1201 | |||
1202 | single_fields->fld_disposition = fld_disposition; | ||
1203 | |||
1204 | for(cur = clist_begin(fld_disposition->dsp_parms) ; cur != NULL ; | ||
1205 | cur = clist_next(cur)) { | ||
1206 | struct mailmime_disposition_parm * param; | ||
1207 | |||
1208 | param = clist_content(cur); | ||
1209 | |||
1210 | switch (param->pa_type) { | ||
1211 | case MAILMIME_DISPOSITION_PARM_FILENAME: | ||
1212 | single_fields->fld_disposition_filename = param->pa_data.pa_filename; | ||
1213 | break; | ||
1214 | |||
1215 | case MAILMIME_DISPOSITION_PARM_CREATION_DATE: | ||
1216 | single_fields->fld_disposition_creation_date = | ||
1217 | param->pa_data.pa_creation_date; | ||
1218 | break; | ||
1219 | |||
1220 | case MAILMIME_DISPOSITION_PARM_MODIFICATION_DATE: | ||
1221 | single_fields->fld_disposition_modification_date = | ||
1222 | param->pa_data.pa_modification_date; | ||
1223 | break; | ||
1224 | |||
1225 | case MAILMIME_DISPOSITION_PARM_READ_DATE: | ||
1226 | single_fields->fld_disposition_read_date = | ||
1227 | param->pa_data.pa_read_date; | ||
1228 | break; | ||
1229 | |||
1230 | case MAILMIME_DISPOSITION_PARM_SIZE: | ||
1231 | single_fields->fld_disposition_size = param->pa_data.pa_size; | ||
1232 | break; | ||
1233 | } | ||
1234 | } | ||
1235 | } | ||
1236 | |||
1237 | static void mailmime_content_single_fields_init(struct | ||
1238 | mailmime_single_fields * single_fields, | ||
1239 | struct mailmime_content * fld_content) | ||
1240 | { | ||
1241 | clistiter * cur; | ||
1242 | |||
1243 | single_fields->fld_content = fld_content; | ||
1244 | |||
1245 | for(cur = clist_begin(fld_content->ct_parameters) ; | ||
1246 | cur != NULL ; cur = clist_next(cur)) { | ||
1247 | struct mailmime_parameter * param; | ||
1248 | |||
1249 | param = clist_content(cur); | ||
1250 | |||
1251 | if (strcasecmp(param->pa_name, "boundary") == 0) | ||
1252 | single_fields->fld_content_boundary = param->pa_value; | ||
1253 | |||
1254 | if (strcasecmp(param->pa_name, "charset") == 0) | ||
1255 | single_fields->fld_content_charset = param->pa_value; | ||
1256 | |||
1257 | if (strcasecmp(param->pa_name, "name") == 0) | ||
1258 | single_fields->fld_content_name = param->pa_value; | ||
1259 | } | ||
1260 | } | ||
1261 | |||
1262 | void mailmime_single_fields_init(struct mailmime_single_fields * single_fields, | ||
1263 | struct mailmime_fields * fld_fields, | ||
1264 | struct mailmime_content * fld_content) | ||
1265 | { | ||
1266 | clistiter * cur; | ||
1267 | |||
1268 | memset(single_fields, 0, sizeof(struct mailmime_single_fields)); | ||
1269 | |||
1270 | if (fld_content != NULL) | ||
1271 | mailmime_content_single_fields_init(single_fields, fld_content); | ||
1272 | |||
1273 | if (fld_fields == NULL) | ||
1274 | return; | ||
1275 | |||
1276 | for(cur = clist_begin(fld_fields->fld_list) ; cur != NULL ; | ||
1277 | cur = clist_next(cur)) { | ||
1278 | struct mailmime_field * field; | ||
1279 | |||
1280 | field = clist_content(cur); | ||
1281 | |||
1282 | switch (field->fld_type) { | ||
1283 | case MAILMIME_FIELD_TYPE: | ||
1284 | mailmime_content_single_fields_init(single_fields, | ||
1285 | field->fld_data.fld_content); | ||
1286 | break; | ||
1287 | |||
1288 | case MAILMIME_FIELD_TRANSFER_ENCODING: | ||
1289 | single_fields->fld_encoding = field->fld_data.fld_encoding; | ||
1290 | break; | ||
1291 | |||
1292 | case MAILMIME_FIELD_ID: | ||
1293 | single_fields->fld_id = field->fld_data.fld_id; | ||
1294 | break; | ||
1295 | |||
1296 | case MAILMIME_FIELD_DESCRIPTION: | ||
1297 | single_fields->fld_description = field->fld_data.fld_description; | ||
1298 | break; | ||
1299 | |||
1300 | case MAILMIME_FIELD_VERSION: | ||
1301 | single_fields->fld_version = field->fld_data.fld_version; | ||
1302 | break; | ||
1303 | |||
1304 | case MAILMIME_FIELD_DISPOSITION: | ||
1305 | mailmime_disposition_single_fields_init(single_fields, | ||
1306 | field->fld_data.fld_disposition); | ||
1307 | break; | ||
1308 | |||
1309 | case MAILMIME_FIELD_LANGUAGE: | ||
1310 | single_fields->fld_language = field->fld_data.fld_language; | ||
1311 | break; | ||
1312 | } | ||
1313 | } | ||
1314 | } | ||
1315 | |||
1316 | struct mailmime_single_fields * | ||
1317 | mailmime_single_fields_new(struct mailmime_fields * fld_fields, | ||
1318 | struct mailmime_content * fld_content) | ||
1319 | { | ||
1320 | struct mailmime_single_fields * single_fields; | ||
1321 | |||
1322 | single_fields = malloc(sizeof(struct mailmime_single_fields)); | ||
1323 | if (single_fields == NULL) | ||
1324 | goto err; | ||
1325 | |||
1326 | mailmime_single_fields_init(single_fields, fld_fields, fld_content); | ||
1327 | |||
1328 | return single_fields; | ||
1329 | |||
1330 | err: | ||
1331 | return NULL; | ||
1332 | } | ||
1333 | |||
1334 | |||
1335 | void mailmime_single_fields_free(struct mailmime_single_fields * | ||
1336 | single_fields) | ||
1337 | { | ||
1338 | free(single_fields); | ||
1339 | } | ||
1340 | |||
1341 | struct mailmime_fields * mailmime_fields_new_filename(int dsp_type, | ||
1342 | char * filename, int encoding_type) | ||
1343 | { | ||
1344 | struct mailmime_disposition * dsp; | ||
1345 | struct mailmime_mechanism * encoding; | ||
1346 | struct mailmime_fields * mime_fields; | ||
1347 | |||
1348 | dsp = mailmime_disposition_new_with_data(dsp_type, | ||
1349 | filename, NULL, NULL, NULL, (size_t) -1); | ||
1350 | if (dsp == NULL) | ||
1351 | goto err; | ||
1352 | |||
1353 | encoding = mailmime_mechanism_new(encoding_type, NULL); | ||
1354 | if (encoding == NULL) | ||
1355 | goto free_dsp; | ||
1356 | |||
1357 | mime_fields = mailmime_fields_new_with_data(encoding, | ||
1358 | NULL, NULL, dsp, NULL); | ||
1359 | if (mime_fields == NULL) | ||
1360 | goto free_encoding; | ||
1361 | |||
1362 | return mime_fields; | ||
1363 | |||
1364 | free_encoding: | ||
1365 | mailmime_encoding_free(encoding); | ||
1366 | free_dsp: | ||
1367 | mailmime_disposition_free(dsp); | ||
1368 | err: | ||
1369 | return NULL; | ||
1370 | } | ||
1371 | |||
1372 | struct mailmime_data * | ||
1373 | mailmime_data_new_data(int encoding, int encoded, | ||
1374 | const char * data, size_t length) | ||
1375 | { | ||
1376 | return mailmime_data_new(MAILMIME_DATA_TEXT, encoding, encoded, data, length, NULL); | ||
1377 | } | ||
1378 | |||
1379 | struct mailmime_data * | ||
1380 | mailmime_data_new_file(int encoding, int encoded, | ||
1381 | char * filename) | ||
1382 | { | ||
1383 | return mailmime_data_new(MAILMIME_DATA_FILE, encoding, encoded, NULL, 0, filename); | ||
1384 | } | ||
1385 | |||