1 #include "pEp_internal.h"
9 #include "etpan_mime.h"
12 static bool is_whitespace(char c)
26 DYNAMIC_API bool is_PGP_message_text(const char *text)
31 for (; *text && is_whitespace(*text); text++);
33 return strncmp(text, "-----BEGIN PGP MESSAGE-----", 27) == 0;
36 #define TMP_TEMPLATE "pEp.XXXXXXXXXXXXXXXXXXXX"
43 static PEP_STATUS render_mime(struct mailmime *mime, char **mimetext)
45 PEP_STATUS status = PEP_STATUS_OK;
53 char *template = NULL;
54 char *env_tmp = getenv("TEMP");
57 unsigned long tmp_l = strlen(env_tmp);
61 int need_sep = (env_tmp[tmp_l-1] != PATH_SEP);
62 template = calloc(1, tmp_l +
64 sizeof(TMP_TEMPLATE));
68 memcpy(template, env_tmp, tmp_l);
70 template[tmp_l] = PATH_SEP;
71 memcpy(template + tmp_l + (need_sep ? 1 : 0), TMP_TEMPLATE, sizeof(TMP_TEMPLATE));
74 template = strdup("/tmp/" TMP_TEMPLATE);
82 fd = Mkstemp(template);
95 file = Fdopen(fd, "w+");
109 r = mailmime_write_file(file, &col, mime);
110 assert(r == MAILIMF_NO_ERROR);
111 if (r == MAILIMF_ERROR_MEMORY)
113 else if (r != MAILIMF_NO_ERROR)
116 off_t len = ftello(file);
118 if (len == -1 && errno == EOVERFLOW)
121 if (len + 1 > SIZE_MAX)
138 buf = calloc(1, size + 1);
144 _read = Fread(buf, size, 1, file);
145 assert(_read == size);
151 return PEP_STATUS_OK;
154 status = PEP_BUFFER_TOO_SMALL;
158 status = PEP_CANNOT_CREATE_TEMP_FILE;
162 status = PEP_OUT_OF_MEMORY;
180 static PEP_STATUS mime_html_text(
181 const char *plaintext,
182 const char *htmltext,
183 struct mailmime **result
186 PEP_STATUS status = PEP_STATUS_OK;
187 struct mailmime * mime = NULL;
188 struct mailmime * submime = NULL;
197 mime = part_multiple_new("multipart/alternative");
202 submime = get_text_part("msg.txt", "text/plain", plaintext, strlen(plaintext),
203 MAILMIME_MECHANISM_QUOTED_PRINTABLE);
208 r = mailmime_smart_add_part(mime, submime);
209 assert(r == MAILIMF_NO_ERROR);
210 if (r == MAILIMF_ERROR_MEMORY) {
214 // mailmime_smart_add_part() takes ownership of submime
218 submime = get_text_part("msg.html", "text/html", htmltext, strlen(htmltext),
219 MAILMIME_MECHANISM_QUOTED_PRINTABLE);
224 r = mailmime_smart_add_part(mime, submime);
225 assert(r == MAILIMF_NO_ERROR);
226 if (r == MAILIMF_ERROR_MEMORY)
229 // mailmime_smart_add_part() takes ownership of submime
234 return PEP_STATUS_OK;
237 status = PEP_OUT_OF_MEMORY;
243 mailmime_free(submime);
248 static PEP_STATUS mime_attachment(
250 struct mailmime **result
253 PEP_STATUS status = PEP_STATUS_OK;
254 struct mailmime * mime = NULL;
262 if (blob->mime_type == NULL)
263 mime_type = "application/octet-stream";
265 mime_type = blob->mime_type;
267 mime = get_file_part(blob->filename, mime_type, blob->value, blob->size);
273 return PEP_STATUS_OK;
276 status = PEP_OUT_OF_MEMORY;
284 static struct mailimf_mailbox * identity_to_mailbox(const pEp_identity *ident)
286 char *_username = NULL;
287 struct mailimf_mailbox *mb;
289 _username = mailmime_encode_subject_header("utf-8", ident->username, 0);
290 if (_username == NULL)
293 mb = mailbox_from_string(_username, ident->address);
307 static struct mailimf_mailbox_list * identity_to_mbl(
308 const pEp_identity *ident)
310 struct mailimf_mailbox_list *mbl = NULL;
311 struct mailimf_mailbox *mb = NULL;
321 mb = identity_to_mailbox(ident);
325 r = clist_append(list, mb);
329 mbl = mailimf_mailbox_list_new(list);
337 mailimf_mailbox_free(mb);
345 static struct mailimf_address_list * identity_list_to_mal(identity_list *il)
347 struct mailimf_address_list *mal = NULL;
348 struct mailimf_mailbox *mb = NULL;
349 struct mailimf_address * addr = NULL;
360 for (_il = il; _il; _il = _il->next) {
361 mb = identity_to_mailbox(_il->ident);
365 addr = mailimf_address_new(MAILIMF_ADDRESS_MAILBOX, mb, NULL);
370 r = clist_append(list, addr);
375 mal = mailimf_address_list_new(list);
383 mailimf_mailbox_free(mb);
386 mailimf_address_free(addr);
394 static clist * stringlist_to_clist(stringlist_t *sl)
396 clist * cl = clist_new();
402 for (_sl = sl; _sl; _sl = _sl->next) {
404 char * value = mailmime_encode_subject_header("utf-8", _sl->value, 0);
410 r = clist_append(cl, value);
422 static PEP_STATUS build_fields(const message *msg, struct mailimf_fields **result)
424 PEP_STATUS status = PEP_STATUS_OK;
425 struct mailimf_fields * fields = NULL;
427 clist * fields_list = NULL;
428 char *subject = msg->shortmsg ? msg->shortmsg : "pEp";
432 assert(msg->from->address);
437 fields_list = clist_new();
439 if (fields_list == NULL)
443 char *_msgid = strdup(msg->id);
447 r = _append_field(fields_list, MAILIMF_FIELD_MESSAGE_ID,
448 (_new_func_t) mailimf_message_id_new, _msgid);
456 struct mailimf_date_time * dt = timestamp_to_etpantime(msg->sent);
460 r = _append_field(fields_list, MAILIMF_FIELD_ORIG_DATE,
461 (_new_func_t) mailimf_orig_date_new, dt);
463 mailimf_date_time_free(dt);
469 /* if (msg->from) */ {
470 struct mailimf_mailbox_list *from = identity_to_mbl(msg->from);
474 r = _append_field(fields_list, MAILIMF_FIELD_FROM,
475 (_new_func_t) mailimf_from_new, from);
477 mailimf_mailbox_list_free(from);
483 struct mailimf_address_list *to = identity_list_to_mal(msg->to);
487 r = _append_field(fields_list, MAILIMF_FIELD_TO,
488 (_new_func_t) mailimf_to_new, to);
490 mailimf_address_list_free(to);
496 char *_subject = mailmime_encode_subject_header("utf-8", subject, 1);
497 if (_subject == NULL)
500 r = _append_field(fields_list, MAILIMF_FIELD_SUBJECT,
501 (_new_func_t) mailimf_subject_new, _subject);
509 struct mailimf_address_list *cc = identity_list_to_mal(msg->cc);
513 r = _append_field(fields_list, MAILIMF_FIELD_CC,
514 (_new_func_t) mailimf_cc_new, cc);
516 mailimf_address_list_free(cc);
522 struct mailimf_address_list *bcc = identity_list_to_mal(msg->bcc);
526 r = _append_field(fields_list, MAILIMF_FIELD_BCC,
527 (_new_func_t) mailimf_bcc_new, bcc);
529 mailimf_address_list_free(bcc);
535 struct mailimf_address_list *reply_to = identity_list_to_mal(msg->reply_to);
536 if (reply_to == NULL)
539 r = _append_field(fields_list, MAILIMF_FIELD_REPLY_TO,
540 (_new_func_t) mailimf_reply_to_new, reply_to);
542 mailimf_address_list_free(reply_to);
547 if (msg->in_reply_to) {
548 clist *in_reply_to = stringlist_to_clist(msg->in_reply_to);
549 if (in_reply_to == NULL)
552 r = _append_field(fields_list, MAILIMF_FIELD_IN_REPLY_TO,
553 (_new_func_t) mailimf_in_reply_to_new, in_reply_to);
555 clist_free(in_reply_to);
560 if (msg->references) {
561 clist *references = stringlist_to_clist(msg->references);
562 if (references == NULL)
565 r = _append_field(fields_list, MAILIMF_FIELD_REFERENCES,
566 (_new_func_t) mailimf_references_new, references);
568 clist_free(references);
574 clist *keywords = stringlist_to_clist(msg->keywords);
575 if (keywords == NULL)
578 r = _append_field(fields_list, MAILIMF_FIELD_KEYWORDS,
579 (_new_func_t) mailimf_keywords_new, keywords);
581 clist_free(keywords);
587 char *comments = mailmime_encode_subject_header("utf-8", msg->comments,
589 if (comments == NULL)
592 r = _append_field(fields_list, MAILIMF_FIELD_COMMENTS,
593 (_new_func_t) mailimf_comments_new, comments);
600 if (msg->opt_fields) {
601 stringpair_list_t *_l;
602 for (_l = msg->opt_fields; _l && _l->value; _l = _l->next) {
603 char *key = _l->value->key;
604 char *value = _l->value->value;
606 char *_value = mailmime_encode_subject_header("utf-8", value, 0);
610 r = _append_optional_field(fields_list, key, _value);
618 fields = mailimf_fields_new(fields_list);
625 return PEP_STATUS_OK;
628 status = PEP_OUT_OF_MEMORY;
631 clist_free(fields_list);
634 mailimf_fields_free(fields);
639 static PEP_STATUS mime_encode_message_plain(
642 struct mailmime **result
645 struct mailmime * mime = NULL;
646 struct mailmime * submime = NULL;
656 subject = (msg->shortmsg) ? msg->shortmsg : "pEp";
657 plaintext = (msg->longmsg) ? msg->longmsg : "";
658 htmltext = msg->longmsg_formatted;
661 status = mime_html_text(plaintext, htmltext, &mime);
662 if (status != PEP_STATUS_OK)
666 if (is_PGP_message_text(plaintext))
667 mime = get_text_part("msg.asc", "application/octet-stream", plaintext,
668 strlen(plaintext), MAILMIME_MECHANISM_7BIT);
670 mime = get_text_part("msg.txt", "text/plain", plaintext, strlen(plaintext),
671 MAILMIME_MECHANISM_QUOTED_PRINTABLE);
677 if (msg->attachments) {
679 mime = part_multiple_new("multipart/mixed");
684 r = mailmime_smart_add_part(mime, submime);
685 assert(r == MAILIMF_NO_ERROR);
686 if (r == MAILIMF_ERROR_MEMORY) {
690 // mailmime_smart_add_part() takes ownership of submime
695 for (_a = msg->attachments; _a != NULL; _a = _a->next) {
699 status = mime_attachment(_a, &submime);
700 if (status != PEP_STATUS_OK)
703 r = mailmime_smart_add_part(mime, submime);
704 assert(r == MAILIMF_NO_ERROR);
705 if (r == MAILIMF_ERROR_MEMORY) {
709 // mailmime_smart_add_part() takes ownership of submime
716 return PEP_STATUS_OK;
719 status = PEP_OUT_OF_MEMORY;
726 mailmime_free(submime);
731 static PEP_STATUS mime_encode_message_PGP_MIME(
734 struct mailmime **result
737 struct mailmime * mime = NULL;
738 struct mailmime * submime = NULL;
739 struct mailmime_parameter * param;
745 assert(msg->attachments && msg->attachments->next &&
746 msg->attachments->next->value);
748 subject = (msg->shortmsg) ? msg->shortmsg : "pEp";
749 plaintext = msg->attachments->next->value;
751 mime = part_multiple_new("multipart/encrypted");
756 param = mailmime_param_new_with_data("protocol", "application/pgp-encrypted");
757 clist_append(mime->mm_content_type->ct_parameters, param);
759 submime = get_pgp_encrypted_part();
764 r = mailmime_smart_add_part(mime, submime);
765 assert(r == MAILIMF_NO_ERROR);
766 if (r == MAILIMF_ERROR_MEMORY) {
770 // mailmime_smart_add_part() takes ownership of submime
774 submime = get_text_part("PGPexch.htm.pgp", "application/octet-stream", plaintext,
775 strlen(plaintext), MAILMIME_MECHANISM_7BIT);
780 r = mailmime_smart_add_part(mime, submime);
781 assert(r == MAILIMF_NO_ERROR);
782 if (r == MAILIMF_ERROR_MEMORY) {
786 // mailmime_smart_add_part() takes ownership of submime
791 return PEP_STATUS_OK;
794 status = PEP_OUT_OF_MEMORY;
800 mailmime_free(submime);
805 DYNAMIC_API PEP_STATUS mime_encode_message(
811 PEP_STATUS status = PEP_STATUS_OK;
812 struct mailmime * msg_mime = NULL;
813 struct mailmime * mime = NULL;
814 struct mailimf_fields * fields = NULL;
821 if (!(msg && mimetext))
822 return PEP_ILLEGAL_VALUE;
826 switch (msg->enc_format) {
828 status = mime_encode_message_plain(msg, omit_fields, &mime);
832 status = mime_encode_message_plain(msg, omit_fields, &mime);
838 case PEP_enc_PGP_MIME:
839 status = mime_encode_message_PGP_MIME(msg, omit_fields, &mime);
846 if (status != PEP_STATUS_OK)
849 msg_mime = mailmime_new_message_data(NULL);
851 if (msg_mime == NULL)
854 r = mailmime_add_part(msg_mime, mime);
862 status = build_fields(msg, &fields);
863 if (status != PEP_STATUS_OK)
866 mailmime_set_imf_fields(msg_mime, fields);
869 status = render_mime(msg_mime, &buf);
870 if (status != PEP_STATUS_OK)
873 mailmime_free(msg_mime);
876 return PEP_STATUS_OK;
879 status = PEP_OUT_OF_MEMORY;
883 mailmime_free(msg_mime);
891 static pEp_identity *mailbox_to_identity(const struct mailimf_mailbox * mb)
894 char *username = NULL;
899 assert(mb->mb_addr_spec);
901 if (mb->mb_addr_spec == NULL)
904 if (mb->mb_display_name) {
906 r = mailmime_encoded_phrase_parse("utf-8", mb->mb_display_name,
907 strlen(mb->mb_display_name), &index, "utf-8", &username);
912 ident = new_identity(mb->mb_addr_spec, NULL, NULL, username);
925 static pEp_identity * mbl_to_identity(const struct mailimf_mailbox_list * mbl)
927 struct mailimf_mailbox * mb = clist_content(clist_begin(mbl->mb_list));
928 return mailbox_to_identity(mb);
931 static identity_list * mal_to_identity_list(
932 const struct mailimf_address_list *mal
935 identity_list *il = NULL;
936 clist *list = mal->ad_list;
937 struct mailimf_address * addr = NULL;
942 il = new_identity_list(NULL);
946 identity_list *_il = il;
947 for (cur = clist_begin(list); cur != NULL ; cur = clist_next(cur)) {
950 addr = clist_content(cur);
951 switch(addr->ad_type) {
952 case MAILIMF_ADDRESS_MAILBOX:
953 ident = mailbox_to_identity(addr->ad_data.ad_mailbox);
956 _il = identity_list_add(_il, ident);
961 case MAILIMF_ADDRESS_GROUP:
964 struct mailimf_mailbox_list * mbl =
965 addr->ad_data.ad_group->grp_mb_list;
966 for (cur2 = clist_begin(mbl->mb_list); cur2 != NULL;
967 cur2 = clist_next(cur2)) {
968 ident = mailbox_to_identity(clist_content(cur));
971 _il = identity_list_add(_il, ident);
987 free_identity_list(il);
992 static stringlist_t * clist_to_stringlist(const clist *list)
995 stringlist_t * sl = new_stringlist(NULL);
1000 stringlist_t *_sl = sl;
1001 for (cur = clist_begin(list); cur != NULL; cur = clist_next(cur)) {
1002 char *phrase = clist_content(cur);
1007 r = mailmime_encoded_phrase_parse("utf-8", phrase, strlen(phrase),
1008 &index, "utf-8", &text);
1012 _sl = stringlist_add(_sl, text);
1023 free_stringlist(sl);
1029 static PEP_STATUS read_fields(message *msg, clist *fieldlist)
1031 PEP_STATUS status = PEP_STATUS_OK;
1032 struct mailimf_field * _field;
1036 stringpair_list_t *opt = msg->opt_fields;
1038 for (cur = clist_begin(fieldlist); cur != NULL; cur = clist_next(cur)) {
1039 _field = clist_content(cur);
1041 switch (_field->fld_type) {
1042 case MAILIMF_FIELD_MESSAGE_ID:
1044 char * text = _field->fld_data.fld_message_id->mid_value;
1048 r = mailmime_encoded_phrase_parse("utf-8", text,
1049 strlen(text), &index, "utf-8", &msg->id);
1055 case MAILIMF_FIELD_SUBJECT:
1057 char * text = _field->fld_data.fld_subject->sbj_value;
1059 free(msg->shortmsg);
1061 r = mailmime_encoded_phrase_parse("utf-8", text,
1062 strlen(text), &index, "utf-8", &msg->shortmsg);
1068 case MAILIMF_FIELD_ORIG_DATE:
1070 struct mailimf_date_time *date =
1071 _field->fld_data.fld_orig_date->dt_date_time;
1073 free_timestamp(msg->sent);
1074 msg->sent = etpantime_to_timestamp(date);
1075 if (msg->sent == NULL)
1080 case MAILIMF_FIELD_FROM:
1082 struct mailimf_mailbox_list *mbl =
1083 _field->fld_data.fld_from->frm_mb_list;
1084 pEp_identity *ident;
1086 ident = mbl_to_identity(mbl);
1090 free_identity(msg->from);
1095 case MAILIMF_FIELD_TO:
1097 struct mailimf_address_list *mal =
1098 _field->fld_data.fld_to->to_addr_list;
1099 identity_list *il = mal_to_identity_list(mal);
1103 free_identity_list(msg->to);
1108 case MAILIMF_FIELD_CC:
1110 struct mailimf_address_list *mal =
1111 _field->fld_data.fld_cc->cc_addr_list;
1112 identity_list *il = mal_to_identity_list(mal);
1116 free_identity_list(msg->cc);
1121 case MAILIMF_FIELD_BCC:
1123 struct mailimf_address_list *mal =
1124 _field->fld_data.fld_bcc->bcc_addr_list;
1125 identity_list *il = mal_to_identity_list(mal);
1129 free_identity_list(msg->bcc);
1134 case MAILIMF_FIELD_REPLY_TO:
1136 struct mailimf_address_list *mal =
1137 _field->fld_data.fld_reply_to->rt_addr_list;
1138 identity_list *il = mal_to_identity_list(mal);
1142 free_identity_list(msg->reply_to);
1147 case MAILIMF_FIELD_IN_REPLY_TO:
1149 clist *list = _field->fld_data.fld_in_reply_to->mid_list;
1150 stringlist_t *sl = clist_to_stringlist(list);
1154 free_stringlist(msg->in_reply_to);
1155 msg->in_reply_to = sl;
1159 case MAILIMF_FIELD_REFERENCES:
1161 clist *list = _field->fld_data.fld_references->mid_list;
1162 stringlist_t *sl = clist_to_stringlist(list);
1166 free_stringlist(msg->references);
1167 msg->references = sl;
1171 case MAILIMF_FIELD_KEYWORDS:
1173 clist *list = _field->fld_data.fld_keywords->kw_list;
1174 stringlist_t *sl = clist_to_stringlist(list);
1178 free_stringlist(msg->keywords);
1183 case MAILIMF_FIELD_COMMENTS:
1185 char * text = _field->fld_data.fld_comments->cm_value;
1187 free(msg->comments);
1189 r = mailmime_encoded_phrase_parse("utf-8", text,
1190 strlen(text), &index, "utf-8", &msg->comments);
1196 case MAILIMF_FIELD_OPTIONAL_FIELD:
1199 _field->fld_data.fld_optional_field->fld_name;
1201 _field->fld_data.fld_optional_field->fld_value;
1205 r = mailmime_encoded_phrase_parse("utf-8", value,
1206 strlen(value), &index, "utf-8", &_value);
1210 stringpair_t *pair = new_stringpair(name, _value);
1214 opt = stringpair_list_add(opt, pair);
1219 if (msg->opt_fields == NULL)
1220 msg->opt_fields = opt;
1226 return PEP_STATUS_OK;
1229 status = PEP_OUT_OF_MEMORY;
1235 static PEP_STATUS interpret_body(struct mailmime *part, char **longmsg, size_t *size)
1245 char *charset = NULL;
1254 if (part->mm_body == NULL)
1255 return PEP_ILLEGAL_VALUE;
1257 text = part->mm_body-> dt_data.dt_text.dt_data;
1259 return PEP_ILLEGAL_VALUE;
1261 length = part->mm_body->dt_data.dt_text.dt_length;
1263 if (part->mm_body->dt_encoded) {
1264 code = part->mm_body->dt_encoding;
1266 r = mailmime_part_parse(text, length, &index, code, &_longmsg, &_size);
1268 case MAILIMF_NO_ERROR:
1270 case MAILIMF_ERROR_MEMORY:
1271 return PEP_OUT_OF_MEMORY;
1273 return PEP_ILLEGAL_VALUE;
1278 _longmsg = strndup(text, length);
1279 if (_longmsg == NULL)
1280 return PEP_OUT_OF_MEMORY;
1283 if (part->mm_content_type) {
1284 if (_get_content_type(part->mm_content_type, &type, &charset) == 0) {
1285 if (charset && strncasecmp(charset, "utf-8", 5) != 0) {
1287 int r = charconv("utf-8", charset, _longmsg, _size, &_text);
1289 case MAILIMF_NO_ERROR:
1291 case MAILIMF_ERROR_MEMORY:
1292 return PEP_OUT_OF_MEMORY;
1294 return PEP_ILLEGAL_VALUE;
1302 *longmsg = _longmsg;
1306 return PEP_STATUS_OK;
1309 static PEP_STATUS interpret_MIME(
1310 struct mailmime *mime,
1314 PEP_STATUS status = PEP_STATUS_OK;
1319 struct mailmime_content *content = mime->mm_content_type;
1321 if (_is_multipart(content, "alternative")) {
1322 clist *partlist = mime->mm_data.mm_multipart.mm_mp_list;
1323 if (partlist == NULL)
1324 return PEP_ILLEGAL_VALUE;
1327 for (cur = clist_begin(partlist); cur; cur = clist_next(cur)) {
1328 struct mailmime *part = clist_content(cur);
1330 return PEP_ILLEGAL_VALUE;
1332 content = part->mm_content_type;
1334 if (content == NULL)
1335 return PEP_ILLEGAL_VALUE;
1337 if (_is_text_part(content, "plain") && msg->longmsg == NULL) {
1338 status = interpret_body(part, &msg->longmsg, NULL);
1342 else if (_is_text_part(content, "html") &&
1343 msg->longmsg_formatted == NULL) {
1344 status = interpret_body(part, &msg->longmsg_formatted,
1349 else /* add as attachment */ {
1350 status = interpret_MIME(part, msg);
1356 else if (_is_multipart(content, "encrypted")) {
1357 if (msg->longmsg == NULL)
1358 msg->longmsg = strdup("");
1360 clist *partlist = mime->mm_data.mm_multipart.mm_mp_list;
1361 if (partlist == NULL)
1362 return PEP_ILLEGAL_VALUE;
1365 for (cur = clist_begin(partlist); cur; cur = clist_next(cur)) {
1366 struct mailmime *part= clist_content(cur);
1368 return PEP_ILLEGAL_VALUE;
1370 status = interpret_MIME(part, msg);
1371 if (status != PEP_STATUS_OK)
1375 else if (_is_multipart(content, NULL)) {
1376 clist *partlist = mime->mm_data.mm_multipart.mm_mp_list;
1377 if (partlist == NULL)
1378 return PEP_ILLEGAL_VALUE;
1381 for (cur = clist_begin(partlist); cur; cur = clist_next(cur)) {
1382 struct mailmime *part= clist_content(cur);
1384 return PEP_ILLEGAL_VALUE;
1386 status = interpret_MIME(part, msg);
1387 if (status != PEP_STATUS_OK)
1392 if (_is_text_part(content, NULL) && msg->longmsg == NULL) {
1393 status = interpret_body(mime, &msg->longmsg, NULL);
1405 r = _get_content_type(content, &mime_type, &charset);
1410 return PEP_ILLEGAL_VALUE;
1412 return PEP_OUT_OF_MEMORY;
1414 return PEP_UNKNOWN_ERROR;
1419 status = interpret_body(mime, &data, &size);
1423 filename = _get_filename(mime);
1425 bloblist_t *_a = bloblist_add(msg->attachments, data, size,
1426 mime_type, filename);
1428 return PEP_OUT_OF_MEMORY;
1429 if (msg->attachments == NULL)
1430 msg->attachments = _a;
1435 return PEP_STATUS_OK;
1438 DYNAMIC_API PEP_STATUS mime_decode_message(
1439 const char *mimetext,
1444 PEP_STATUS status = PEP_STATUS_OK;
1445 struct mailmime * mime = NULL;
1447 message *_msg = NULL;
1453 if (!(mimetext && msg))
1454 return PEP_ILLEGAL_VALUE;
1459 r = mailmime_parse(mimetext, size, &index, &mime);
1463 if (r == MAILIMF_ERROR_MEMORY)
1469 _msg = calloc(1, sizeof(message));
1474 clist * _fieldlist = _get_fields(mime);
1476 status = read_fields(_msg, _fieldlist);
1477 if (status != PEP_STATUS_OK)
1481 struct mailmime_content *content = _get_content(mime);
1484 status = interpret_MIME(mime->mm_data.mm_message.mm_msg_mime,
1486 if (status != PEP_STATUS_OK)
1490 mailmime_free(mime);
1496 status = PEP_ILLEGAL_VALUE;
1500 status = PEP_OUT_OF_MEMORY;
1506 mailmime_free(mime);