...
authorvb
Mon, 09 Mar 2015 23:20:08 +0100
changeset 949ec29aa10b58
parent 93 6f3f781caaa0
child 95 546e631421b9
...
src/etpan_mime.c
src/etpan_mime.h
src/message_api.c
src/mime.c
src/pEpEngine.h
src/transport.c
src/transport.h
test/mime_test.cc
     1.1 --- a/src/etpan_mime.c	Sun Mar 08 12:18:20 2015 +0100
     1.2 +++ b/src/etpan_mime.c	Mon Mar 09 23:20:08 2015 +0100
     1.3 @@ -372,3 +372,66 @@
     1.4      return NULL;
     1.5  }
     1.6  
     1.7 +struct mailimf_field * create_optional_field(
     1.8 +        const char *field,
     1.9 +        const char *value
    1.10 +    )
    1.11 +{
    1.12 +    char *_field = NULL;
    1.13 +    char *_value = NULL;
    1.14 +    struct mailimf_optional_field *optional_field = NULL;
    1.15 +
    1.16 +    _field = strdup(field);
    1.17 +    if (_field == NULL)
    1.18 +        goto enomem;
    1.19 +
    1.20 +    _value = mailmime_encode_subject_header("utf-8", value, 0);
    1.21 +    if (_value == NULL)
    1.22 +        goto enomem;
    1.23 +
    1.24 +    optional_field = mailimf_optional_field_new(_field, _value);
    1.25 +    if (optional_field == NULL)
    1.26 +        goto enomem;
    1.27 +
    1.28 +    struct mailimf_field * result = calloc(1, sizeof(struct mailimf_field));
    1.29 +    assert(result);
    1.30 +    if (result == NULL)
    1.31 +        goto enomem;
    1.32 +
    1.33 +    result->fld_type = MAILIMF_FIELD_OPTIONAL_FIELD;
    1.34 +    result->fld_data.fld_optional_field = optional_field;
    1.35 +
    1.36 +    return result;
    1.37 +
    1.38 +enomem:
    1.39 +    if (optional_field) {
    1.40 +        mailimf_optional_field_free(optional_field);
    1.41 +    }
    1.42 +    else {
    1.43 +        free(_field);
    1.44 +        free(_value);
    1.45 +    }
    1.46 +
    1.47 +    return NULL;
    1.48 +}
    1.49 +
    1.50 +int _append_optional_field(
    1.51 +        clist *list,
    1.52 +        const char *field,
    1.53 +        const char *value
    1.54 +    )
    1.55 +{
    1.56 +    int r;
    1.57 +    struct mailimf_field * optional_field =
    1.58 +            create_optional_field(field, value);
    1.59 +
    1.60 +    if (optional_field == NULL)
    1.61 +        return -1;
    1.62 +
    1.63 +    r = clist_append(list, optional_field);
    1.64 +    if (r)
    1.65 +        mailimf_field_free(optional_field);
    1.66 +
    1.67 +    return r;
    1.68 +}
    1.69 +
     2.1 --- a/src/etpan_mime.h	Sun Mar 08 12:18:20 2015 +0100
     2.2 +++ b/src/etpan_mime.h	Mon Mar 09 23:20:08 2015 +0100
     2.3 @@ -1,6 +1,8 @@
     2.4  #pragma once
     2.5  
     2.6  #include <libetpan/libetpan.h>
     2.7 +#include <libetpan/mailmime.h>
     2.8 +#include <libetpan/mailmime_encode.h>
     2.9  
    2.10  struct mailmime * part_new_empty(
    2.11          struct mailmime_content * content,
    2.12 @@ -53,3 +55,14 @@
    2.13          const char *address
    2.14      );
    2.15  
    2.16 +struct mailimf_field * create_optional_field(
    2.17 +        const char *field,
    2.18 +        const char *value
    2.19 +    );
    2.20 +
    2.21 +int _append_optional_field(
    2.22 +        clist *list,
    2.23 +        const char *field,
    2.24 +        const char *value
    2.25 +    );
    2.26 +
     3.1 --- a/src/message_api.c	Sun Mar 08 12:18:20 2015 +0100
     3.2 +++ b/src/message_api.c	Mon Mar 09 23:20:08 2015 +0100
     3.3 @@ -132,7 +132,7 @@
     3.4      }
     3.5  
     3.6      if (src->reply_to) {
     3.7 -        msg->reply_to = identity_dup(src->reply_to);
     3.8 +        msg->reply_to = identity_list_dup(src->reply_to);
     3.9          if (msg->reply_to == NULL)
    3.10              goto enomem;
    3.11      }
     4.1 --- a/src/mime.c	Sun Mar 08 12:18:20 2015 +0100
     4.2 +++ b/src/mime.c	Mon Mar 09 23:20:08 2015 +0100
     4.3 @@ -1,6 +1,5 @@
     4.4  #include "mime.h"
     4.5  
     4.6 -#include <libetpan/mailmime.h>
     4.7  #include <string.h>
     4.8  #include <stdlib.h>
     4.9  #include <assert.h>
    4.10 @@ -10,6 +9,8 @@
    4.11  #include "etpan_mime.h"
    4.12  #include "wrappers.h"
    4.13  
    4.14 +#define NOT_IMPLEMENTED assert(0);
    4.15 +
    4.16  static PEP_STATUS render_mime(struct mailmime *mime, char **mimetext)
    4.17  {
    4.18      PEP_STATUS status = PEP_STATUS_OK;
    4.19 @@ -230,7 +231,31 @@
    4.20      return status;
    4.21  }
    4.22  
    4.23 -static struct mailimf_mailbox_list * mbl_from_identity(const pEp_identity *ident)
    4.24 +static struct mailimf_mailbox * identity_to_mailbox(const pEp_identity *ident)
    4.25 +{
    4.26 +    char *_username = NULL;
    4.27 +    struct mailimf_mailbox *mb;
    4.28 +
    4.29 +    _username = mailmime_encode_subject_header("utf-8", ident->username, 0);
    4.30 +    if (_username == NULL)
    4.31 +        goto enomem;
    4.32 +
    4.33 +    mb = mailbox_from_string(_username, ident->address);
    4.34 +    if (mb == NULL)
    4.35 +        goto enomem;
    4.36 +
    4.37 +    free(_username);
    4.38 +    _username = NULL;
    4.39 +
    4.40 +    return mb;
    4.41 +
    4.42 +enomem:
    4.43 +    free(_username);
    4.44 +    return NULL;
    4.45 +}
    4.46 +
    4.47 +static struct mailimf_mailbox_list * identity_to_mbl(
    4.48 +        const pEp_identity *ident)
    4.49  {
    4.50      struct mailimf_mailbox_list *mbl = NULL;
    4.51      struct mailimf_mailbox *mb = NULL;
    4.52 @@ -243,7 +268,7 @@
    4.53      if (list == NULL)
    4.54          goto enomem;
    4.55  
    4.56 -    mb = mailbox_from_string(ident->username, ident->address);
    4.57 +    mb = identity_to_mailbox(ident);
    4.58      if (mb == NULL)
    4.59          goto enomem;
    4.60  
    4.61 @@ -267,7 +292,7 @@
    4.62      return NULL;
    4.63  }
    4.64  
    4.65 -static struct mailimf_address_list * mal_from_identity_list(identity_list *il)
    4.66 +static struct mailimf_address_list * identity_list_to_mal(identity_list *il)
    4.67  {
    4.68      struct mailimf_address_list *mal = NULL;
    4.69      struct mailimf_mailbox *mb = NULL;
    4.70 @@ -283,7 +308,7 @@
    4.71  
    4.72      identity_list *_il;
    4.73      for (_il = il; _il; _il = _il->next) {
    4.74 -        mb = mailbox_from_string(_il->ident->username, _il->ident->address);
    4.75 +        mb = identity_to_mailbox(_il->ident);
    4.76          if (mb == NULL)
    4.77              goto enomem;
    4.78  
    4.79 @@ -316,7 +341,7 @@
    4.80      return NULL;
    4.81  }
    4.82  
    4.83 -static clist * clist_from_stringlist(stringlist_t *sl)
    4.84 +static clist * stringlist_to_clist(stringlist_t *sl)
    4.85  {
    4.86      clist * cl = clist_new();
    4.87      assert(cl);
    4.88 @@ -326,7 +351,7 @@
    4.89      stringlist_t *_sl;
    4.90      for (_sl = sl; _sl; _sl = _sl->next) {
    4.91          int r;
    4.92 -        char * value = strdup(_sl->value);
    4.93 +        char * value = mailmime_encode_subject_header("utf-8", _sl->value, 0);
    4.94          assert(value);
    4.95          if (value == NULL) {
    4.96              clist_free(cl);
    4.97 @@ -378,7 +403,7 @@
    4.98      }
    4.99  
   4.100      /* if (subject) */ {
   4.101 -        char *_subject = strdup(subject);
   4.102 +        char *_subject = mailmime_encode_subject_header("utf-8", subject, 1);
   4.103          if (_subject == NULL)
   4.104              goto enomem;
   4.105  
   4.106 @@ -405,7 +430,7 @@
   4.107      }
   4.108  
   4.109      /* if (msg->from) */ {
   4.110 -        struct mailimf_mailbox_list *from = mbl_from_identity(msg->from);
   4.111 +        struct mailimf_mailbox_list *from = identity_to_mbl(msg->from);
   4.112          if (from == NULL)
   4.113              goto enomem;
   4.114  
   4.115 @@ -418,7 +443,7 @@
   4.116      }
   4.117  
   4.118      if (msg->to) {
   4.119 -        struct mailimf_address_list *to = mal_from_identity_list(msg->to);
   4.120 +        struct mailimf_address_list *to = identity_list_to_mal(msg->to);
   4.121          if (to == NULL)
   4.122              goto enomem;
   4.123  
   4.124 @@ -431,7 +456,7 @@
   4.125      }
   4.126  
   4.127      if (msg->cc) {
   4.128 -        struct mailimf_address_list *cc = mal_from_identity_list(msg->cc);
   4.129 +        struct mailimf_address_list *cc = identity_list_to_mal(msg->cc);
   4.130          if (cc == NULL)
   4.131              goto enomem;
   4.132  
   4.133 @@ -444,7 +469,7 @@
   4.134      }
   4.135      
   4.136      if (msg->bcc) {
   4.137 -        struct mailimf_address_list *bcc = mal_from_identity_list(msg->bcc);
   4.138 +        struct mailimf_address_list *bcc = identity_list_to_mal(msg->bcc);
   4.139          if (bcc == NULL)
   4.140              goto enomem;
   4.141  
   4.142 @@ -457,33 +482,33 @@
   4.143      }
   4.144      
   4.145      if (msg->reply_to) {
   4.146 -        struct mailimf_mailbox_list *reply_to= mbl_from_identity(msg->reply_to);
   4.147 +        struct mailimf_address_list *reply_to = identity_list_to_mal(msg->reply_to);
   4.148          if (reply_to == NULL)
   4.149              goto enomem;
   4.150  
   4.151          r = _append_field(fields_list, MAILIMF_FIELD_REPLY_TO,
   4.152                  (_new_func_t) mailimf_reply_to_new, reply_to);
   4.153          if (r) {
   4.154 -            mailimf_mailbox_list_free(reply_to);
   4.155 +            mailimf_address_list_free(reply_to);
   4.156              goto enomem;
   4.157          }
   4.158      }
   4.159  
   4.160      if (msg->in_reply_to) {
   4.161 -        char *in_reply_to = strdup(msg->in_reply_to);
   4.162 +        clist *in_reply_to = stringlist_to_clist(msg->in_reply_to);
   4.163          if (in_reply_to == NULL)
   4.164              goto enomem;
   4.165  
   4.166          r = _append_field(fields_list, MAILIMF_FIELD_IN_REPLY_TO,
   4.167                  (_new_func_t) mailimf_in_reply_to_new, in_reply_to);
   4.168          if (r) {
   4.169 -            free(in_reply_to);
   4.170 +            clist_free(in_reply_to);
   4.171              goto enomem;
   4.172          }
   4.173      }
   4.174  
   4.175      if (msg->references) {
   4.176 -        clist *references = clist_from_stringlist(msg->references);
   4.177 +        clist *references = stringlist_to_clist(msg->references);
   4.178          if (references == NULL)
   4.179              goto enomem;
   4.180  
   4.181 @@ -496,7 +521,7 @@
   4.182      }
   4.183  
   4.184      if (msg->keywords) {
   4.185 -        clist *keywords = clist_from_stringlist(msg->keywords);
   4.186 +        clist *keywords = stringlist_to_clist(msg->keywords);
   4.187          if (keywords == NULL)
   4.188              goto enomem;
   4.189  
   4.190 @@ -509,7 +534,8 @@
   4.191      }
   4.192  
   4.193      if (msg->comments) {
   4.194 -        char *comments = strdup(msg->comments);
   4.195 +        char *comments = mailmime_encode_subject_header("utf-8", msg->comments,
   4.196 +                0);
   4.197          if (comments == NULL)
   4.198              goto enomem;
   4.199  
   4.200 @@ -521,6 +547,10 @@
   4.201          }
   4.202      }
   4.203  
   4.204 +    r = _append_optional_field(fields_list, "X-pEp-Version", PEP_VERSION);
   4.205 +    if (r)
   4.206 +        goto enomem;
   4.207 +
   4.208      fields = mailimf_fields_new(fields_list);
   4.209      assert(fields);
   4.210      if (fields == NULL)
   4.211 @@ -663,6 +693,293 @@
   4.212      return status;
   4.213  }
   4.214  
   4.215 +static pEp_identity *mailbox_to_identity(const struct mailimf_mailbox * mb)
   4.216 +{
   4.217 +    pEp_identity *ident;
   4.218 +    char *username = NULL;
   4.219 +    size_t index;
   4.220 +    int r;
   4.221 +
   4.222 +    index = 0;
   4.223 +    r = mailmime_encoded_phrase_parse("utf-8", mb->mb_display_name,
   4.224 +            strlen(mb->mb_display_name), &index, "utf-8", &username);
   4.225 +    if (r)
   4.226 +        goto enomem;
   4.227 +
   4.228 +    ident = new_identity(mb->mb_addr_spec, NULL, NULL, username);
   4.229 +    if (ident == NULL)
   4.230 +        goto enomem;
   4.231 +    free(username);
   4.232 +
   4.233 +    return ident;
   4.234 +
   4.235 +enomem:
   4.236 +    free(username);
   4.237 +
   4.238 +    return NULL;
   4.239 +}
   4.240 +
   4.241 +static pEp_identity * mbl_to_identity(const struct mailimf_mailbox_list * mbl)
   4.242 +{
   4.243 +    struct mailimf_mailbox * mb = clist_content(clist_begin(mbl->mb_list));
   4.244 +    return mailbox_to_identity(mb);
   4.245 +}
   4.246 +
   4.247 +static identity_list * mal_to_identity_list(
   4.248 +        const struct mailimf_address_list *mal
   4.249 +    )
   4.250 +{
   4.251 +    PEP_STATUS status = PEP_STATUS_OK;
   4.252 +    identity_list *il = NULL;
   4.253 +    clist *list = mal->ad_list;
   4.254 +    struct mailimf_address * addr = NULL;
   4.255 +    struct mailimf_mailbox *mb = NULL;
   4.256 +    clistiter *cur;
   4.257 +    int r;
   4.258 +
   4.259 +    assert(mal);
   4.260 +
   4.261 +    il = new_identity_list(NULL);
   4.262 +    if (il == NULL)
   4.263 +        goto enomem;
   4.264 +
   4.265 +    identity_list *_il = il;
   4.266 +    for (cur = clist_begin(list); cur != NULL ; cur = clist_next(cur)) {
   4.267 +        pEp_identity *ident;
   4.268 +
   4.269 +        addr = clist_content(cur);
   4.270 +        switch(addr->ad_type) {
   4.271 +            case MAILIMF_ADDRESS_MAILBOX:
   4.272 +                ident = mailbox_to_identity(addr->ad_data.ad_mailbox);
   4.273 +                if (ident == NULL)
   4.274 +                    goto enomem;
   4.275 +                _il = identity_list_add(_il, ident);
   4.276 +                if (_il == NULL)
   4.277 +                    goto enomem;
   4.278 +                break;
   4.279 +
   4.280 +            case MAILIMF_ADDRESS_GROUP:
   4.281 +                {
   4.282 +                    clistiter *cur2;
   4.283 +                    struct mailimf_mailbox_list * mbl =
   4.284 +                            addr->ad_data.ad_group->grp_mb_list;
   4.285 +                    for (cur2 = clist_begin(mbl->mb_list); cur2 != NULL;
   4.286 +                            cur2 = clist_next(cur2)) {
   4.287 +                        ident = mailbox_to_identity(clist_content(cur));
   4.288 +                        if (ident == NULL)
   4.289 +                            goto enomem;
   4.290 +                        _il = identity_list_add(_il, ident);
   4.291 +                        if (_il == NULL)
   4.292 +                            goto enomem;
   4.293 +                    }
   4.294 +                }
   4.295 +                break;
   4.296 +
   4.297 +            default:
   4.298 +                assert(0);
   4.299 +                goto enomem;
   4.300 +        }
   4.301 +    }
   4.302 +
   4.303 +    return il;
   4.304 +
   4.305 +enomem:
   4.306 +    free_identity_list(il);
   4.307 +
   4.308 +    return NULL;
   4.309 +}
   4.310 +
   4.311 +static stringlist_t * clist_to_stringlist(const clist *list)
   4.312 +{
   4.313 +    char *text = NULL;;
   4.314 +    stringlist_t * sl = new_stringlist(NULL);
   4.315 +    if (sl == NULL)
   4.316 +        return NULL;
   4.317 +
   4.318 +    clistiter *cur;
   4.319 +    stringlist_t *_sl = sl;
   4.320 +    for (cur = clist_begin(list); cur != NULL; cur = clist_next(cur)) {
   4.321 +        char *phrase = clist_content(cur);
   4.322 +        size_t index;
   4.323 +        int r;
   4.324 +
   4.325 +        index = 0;
   4.326 +        r = mailmime_encoded_phrase_parse("utf-8", phrase, strlen(phrase),
   4.327 +                &index, "utf-8", &text);
   4.328 +        if (r)
   4.329 +            goto enomem;
   4.330 +
   4.331 +        _sl = stringlist_add(_sl, text);
   4.332 +        if (_sl == NULL)
   4.333 +            goto enomem;
   4.334 +
   4.335 +        free(text);
   4.336 +        text = NULL;
   4.337 +    }
   4.338 +
   4.339 +    return _sl;
   4.340 +
   4.341 +enomem:
   4.342 +    free_stringlist(sl);
   4.343 +    free(text);
   4.344 +
   4.345 +    return NULL;
   4.346 +}
   4.347 +
   4.348 +static PEP_STATUS read_fields(message *msg, clist *fieldlist)
   4.349 +{
   4.350 +    PEP_STATUS status = PEP_STATUS_OK;
   4.351 +    struct mailimf_field * _field;
   4.352 +    clistiter *cur;
   4.353 +    size_t index;
   4.354 +    int r;
   4.355 +
   4.356 +    for (cur = clist_begin(fieldlist); cur != NULL; cur = clist_next(cur)) {
   4.357 +        _field = clist_content(cur);
   4.358 +
   4.359 +        switch (_field->fld_type) {
   4.360 +            case MAILIMF_FIELD_MESSAGE_ID:
   4.361 +                {
   4.362 +                    char * text = _field->fld_data.fld_message_id->mid_value;
   4.363 +                    index = 0;
   4.364 +                    r = mailmime_encoded_phrase_parse("utf-8", text,
   4.365 +                            strlen(text), &index, "utf-8", &msg->id);
   4.366 +                    if (r)
   4.367 +                        goto enomem;
   4.368 +                }
   4.369 +                break;
   4.370 +
   4.371 +            case MAILIMF_FIELD_SUBJECT:
   4.372 +                {
   4.373 +                    char * text = _field->fld_data.fld_subject->sbj_value;
   4.374 +                    index = 0;
   4.375 +                    r = mailmime_encoded_phrase_parse("utf-8", text,
   4.376 +                            strlen(text), &index, "utf-8", &msg->shortmsg);
   4.377 +                    if (r)
   4.378 +                        goto enomem;
   4.379 +                }
   4.380 +                break;
   4.381 +
   4.382 +            case MAILIMF_FIELD_ORIG_DATE:
   4.383 +                {
   4.384 +                    struct mailimf_date_time *date =
   4.385 +                        _field->fld_data.fld_orig_date->dt_date_time;
   4.386 +                    msg->sent = etpantime_to_timestamp(date);
   4.387 +                    if (msg->sent == NULL)
   4.388 +                        goto enomem;
   4.389 +                }
   4.390 +                break;
   4.391 +
   4.392 +            case MAILIMF_FIELD_FROM:
   4.393 +                {
   4.394 +                    struct mailimf_mailbox_list *mbl =
   4.395 +                            _field->fld_data.fld_from->frm_mb_list;
   4.396 +                    pEp_identity *ident;
   4.397 +
   4.398 +                    ident = mbl_to_identity(mbl);
   4.399 +                    if (ident == NULL)
   4.400 +                        goto pep_error;
   4.401 +
   4.402 +                    msg->from = ident;
   4.403 +                }
   4.404 +                break;
   4.405 +
   4.406 +            case MAILIMF_FIELD_TO:
   4.407 +                {
   4.408 +                    struct mailimf_address_list *mal =
   4.409 +                            _field->fld_data.fld_to->to_addr_list;
   4.410 +                    identity_list *il = mal_to_identity_list(mal);
   4.411 +                    if (il == NULL)
   4.412 +                        goto enomem;
   4.413 +                    msg->to = il;
   4.414 +                }
   4.415 +                break;
   4.416 +
   4.417 +            case MAILIMF_FIELD_CC:
   4.418 +                {
   4.419 +                    struct mailimf_address_list *mal =
   4.420 +                            _field->fld_data.fld_cc->cc_addr_list;
   4.421 +                    identity_list *il = mal_to_identity_list(mal);
   4.422 +                    if (il == NULL)
   4.423 +                        goto enomem;
   4.424 +                    msg->cc = il;
   4.425 +                }
   4.426 +                break;
   4.427 +
   4.428 +            case MAILIMF_FIELD_BCC:
   4.429 +                {
   4.430 +                    struct mailimf_address_list *mal =
   4.431 +                            _field->fld_data.fld_bcc->bcc_addr_list;
   4.432 +                    identity_list *il = mal_to_identity_list(mal);
   4.433 +                    if (il == NULL)
   4.434 +                        goto enomem;
   4.435 +                    msg->bcc = il;
   4.436 +                }
   4.437 +                break;
   4.438 +
   4.439 +            case MAILIMF_FIELD_REPLY_TO:
   4.440 +                {
   4.441 +                    struct mailimf_address_list *mal =
   4.442 +                            _field->fld_data.fld_reply_to->rt_addr_list;
   4.443 +                    identity_list *il = mal_to_identity_list(mal);
   4.444 +                    if (il == NULL)
   4.445 +                        goto enomem;
   4.446 +                    msg->reply_to = il;
   4.447 +                }
   4.448 +                break;
   4.449 +
   4.450 +            case MAILIMF_FIELD_IN_REPLY_TO:
   4.451 +                {
   4.452 +                    clist *list = _field->fld_data.fld_in_reply_to->mid_list;
   4.453 +                    stringlist_t *sl = clist_to_stringlist(list);
   4.454 +                    if (sl == NULL)
   4.455 +                        goto enomem;
   4.456 +                    msg->in_reply_to = sl;
   4.457 +                }
   4.458 +                break;
   4.459 +
   4.460 +            case MAILIMF_FIELD_REFERENCES:
   4.461 +                {
   4.462 +                    clist *list = _field->fld_data.fld_references->mid_list;
   4.463 +                    stringlist_t *sl = clist_to_stringlist(list);
   4.464 +                    if (sl == NULL)
   4.465 +                        goto enomem;
   4.466 +                    msg->references = sl;
   4.467 +                }
   4.468 +                break;
   4.469 +
   4.470 +            case MAILIMF_FIELD_KEYWORDS:
   4.471 +                {
   4.472 +                    clist *list = _field->fld_data.fld_keywords->kw_list;
   4.473 +                    stringlist_t *sl = clist_to_stringlist(list);
   4.474 +                    if (sl == NULL)
   4.475 +                        goto enomem;
   4.476 +                    msg->keywords = sl;
   4.477 +                }
   4.478 +                break;
   4.479 +
   4.480 +            case MAILIMF_FIELD_COMMENTS:
   4.481 +                {
   4.482 +                    char * text = _field->fld_data.fld_comments->cm_value;
   4.483 +                    index = 0;
   4.484 +                    r = mailmime_encoded_phrase_parse("utf-8", text,
   4.485 +                            strlen(text), &index, "utf-8", &msg->comments);
   4.486 +                    if (r)
   4.487 +                        goto enomem;
   4.488 +                }
   4.489 +                break;
   4.490 +        }
   4.491 +    }
   4.492 +
   4.493 +    return PEP_STATUS_OK;
   4.494 +
   4.495 +enomem:
   4.496 +    status = PEP_OUT_OF_MEMORY;
   4.497 +
   4.498 +pep_error:
   4.499 +    return status;
   4.500 +}
   4.501 +
   4.502  DYNAMIC_API PEP_STATUS mime_decode_message(
   4.503          const char *mimetext,
   4.504          message **msg
   4.505 @@ -671,13 +988,15 @@
   4.506      PEP_STATUS status = PEP_STATUS_OK;
   4.507      struct mailmime * mime = NULL;
   4.508      int r;
   4.509 +    message *_msg = NULL;
   4.510 +    size_t index;
   4.511  
   4.512      assert(mimetext);
   4.513      assert(msg);
   4.514  
   4.515      *msg = NULL;
   4.516      
   4.517 -    size_t index = 0;
   4.518 +    index = 0;
   4.519      r = mailmime_parse(mimetext, strlen(mimetext), &index, &mime);
   4.520      assert(r == 0);
   4.521      assert(mime);
   4.522 @@ -688,7 +1007,17 @@
   4.523              goto err_mime;
   4.524      }
   4.525  
   4.526 +    _msg = calloc(1, sizeof(message));
   4.527 +    if (_msg == NULL)
   4.528 +        goto enomem;
   4.529 +
   4.530 +    clist * _fieldlist = mime->mm_data.mm_message.mm_fields->fld_list;
   4.531 +    status = read_fields(_msg, _fieldlist);
   4.532 +    if (status != PEP_STATUS_OK)
   4.533 +        goto pep_error;
   4.534 +
   4.535      mailmime_free(mime);
   4.536 +    *msg = _msg;
   4.537  
   4.538      return status;
   4.539  
   4.540 @@ -700,6 +1029,8 @@
   4.541      status = PEP_OUT_OF_MEMORY;
   4.542  
   4.543  pep_error:
   4.544 +    free_message(_msg);
   4.545 +
   4.546      if (mime)
   4.547          mailmime_free(mime);
   4.548  
     5.1 --- a/src/pEpEngine.h	Sun Mar 08 12:18:20 2015 +0100
     5.2 +++ b/src/pEpEngine.h	Mon Mar 09 23:20:08 2015 +0100
     5.3 @@ -19,6 +19,8 @@
     5.4  #endif
     5.5  
     5.6  
     5.7 +#define PEP_VERSION "1.0"
     5.8 +
     5.9  // pEp Engine API
    5.10  
    5.11  //  caveat:
     6.1 --- a/src/transport.c	Sun Mar 08 12:18:20 2015 +0100
     6.2 +++ b/src/transport.c	Mon Mar 09 23:20:08 2015 +0100
     6.3 @@ -236,8 +236,8 @@
     6.4          free_identity(msg->recv_by);
     6.5          free_identity_list(msg->cc);
     6.6          free_identity_list(msg->bcc);
     6.7 -        free_identity(msg->reply_to);
     6.8 -        free(msg->in_reply_to);
     6.9 +        free_identity_list(msg->reply_to);
    6.10 +        free_stringlist(msg->in_reply_to);
    6.11          free_stringlist(msg->references);
    6.12          free_stringlist(msg->keywords);
    6.13          free(msg->comments);
    6.14 @@ -328,13 +328,13 @@
    6.15      }
    6.16  
    6.17      if (src->reply_to) {
    6.18 -        msg->reply_to = identity_dup(src->reply_to);
    6.19 +        msg->reply_to = identity_list_dup(src->reply_to);
    6.20          if (msg->reply_to == NULL)
    6.21              goto enomem;
    6.22      }
    6.23  
    6.24      if (src->in_reply_to) {
    6.25 -        msg->in_reply_to = strdup(src->in_reply_to);
    6.26 +        msg->in_reply_to = stringlist_dup(src->in_reply_to);
    6.27          assert(msg->in_reply_to);
    6.28          if (msg->in_reply_to == NULL)
    6.29              goto enomem;
     7.1 --- a/src/transport.h	Sun Mar 08 12:18:20 2015 +0100
     7.2 +++ b/src/transport.h	Mon Mar 09 23:20:08 2015 +0100
     7.3 @@ -197,9 +197,9 @@
     7.4                                              // is received
     7.5      identity_list *cc;                      // whom a CC is being sent
     7.6      identity_list *bcc;                     // whom a BCC is being sent
     7.7 -    pEp_identity *reply_to;                 // where a reply should go to
     7.8 -    char *in_reply_to;                      // UTF-8 string with MessageID of
     7.9 -                                            // refering message
    7.10 +    identity_list *reply_to;                // where a reply should go to
    7.11 +    stringlist_t *in_reply_to;              // list of UTF-8 strings with
    7.12 +                                            // MessageIDs ofrefering messages
    7.13      struct _message *refering_msg_ref;      // reference to refering message
    7.14      stringlist_t *references;               // list of UTF-8 strings with references
    7.15      struct _message_ref_list *refered_by;   // list of references to messages being
     8.1 --- a/test/mime_test.cc	Sun Mar 08 12:18:20 2015 +0100
     8.2 +++ b/test/mime_test.cc	Mon Mar 09 23:20:08 2015 +0100
     8.3 @@ -22,8 +22,8 @@
     8.4      // testing multipart/alternative
     8.5  
     8.6      message *msg2 = new_message(PEP_dir_incoming,
     8.7 -            new_identity("vb@dingens.org", NULL, NULL, NULL),
     8.8 -            new_identity_list(new_identity("trischa@dingens.org", NULL, NULL, NULL)),
     8.9 +            new_identity("vb@dingens.org", NULL, NULL, "Volker Birk"),
    8.10 +            new_identity_list(new_identity("trischa@dingens.org", NULL, NULL, "Patricia Bädnar")),
    8.11              "my sübject");
    8.12      assert(msg2);
    8.13      string text2 = "my mèssage to yoü";
    8.14 @@ -44,6 +44,23 @@
    8.15      free(result2);
    8.16      free_message(msg2);
    8.17  
    8.18 +    cout << "opening mime_sample.txt for reading\n";
    8.19 +    ifstream inFile3 ("mime_sample.txt");
    8.20 +    assert(inFile3.is_open());
    8.21 +
    8.22 +    string mimetext3;
    8.23 +
    8.24 +    cout << "reading mime sample\n";
    8.25 +    while (!inFile3.eof()) {
    8.26 +        static string line;
    8.27 +        getline(inFile3, line);
    8.28 +        mimetext3 += line + "\n";
    8.29 +    }
    8.30 +    inFile3.close();
    8.31 +
    8.32 +    message *msg3;
    8.33 +    PEP_STATUS status3 = mime_decode_message(mimetext3.c_str(), &msg3);
    8.34 +
    8.35      cout << "calling release()\n";
    8.36      release(session);
    8.37      return 0;