...
authorvb
Tue, 30 Dec 2014 13:04:17 +0100
changeset 3966b5cc6cb987
parent 38 271bea5552dc
child 40 3e7aa2f67b7e
...
src/keymanagement.h
src/message_api.c
src/message_api.h
src/pEpEngine.c
src/pEpEngine.h
src/transport.c
src/transport.h
test/Makefile
test/message_api_test.cc
     1.1 --- a/src/keymanagement.h	Mon Dec 29 20:48:30 2014 +0100
     1.2 +++ b/src/keymanagement.h	Tue Dec 30 13:04:17 2014 +0100
     1.3 @@ -1,3 +1,5 @@
     1.4 +#pragma once
     1.5 +
     1.6  #ifdef __cplusplus
     1.7  extern "C" {
     1.8  #endif
     2.1 --- a/src/message_api.c	Mon Dec 29 20:48:30 2014 +0100
     2.2 +++ b/src/message_api.c	Tue Dec 30 13:04:17 2014 +0100
     2.3 @@ -4,6 +4,9 @@
     2.4  #include <libetpan/libetpan.h>
     2.5  #include <assert.h>
     2.6  #include <string.h>
     2.7 +#include <stdlib.h>
     2.8 +
     2.9 +#define NOT_IMPLEMENTED assert(0);
    2.10  
    2.11  PEP_STATUS encrypt_message(
    2.12          PEP_SESSION session,
    2.13 @@ -40,25 +43,30 @@
    2.14          return PEP_OUT_OF_MEMORY;
    2.15      }
    2.16  
    2.17 -    stringlist_t *_x;
    2.18 -    for (_x = extra; _x && _x->value; _x = _x->next) {
    2.19 -        if (stringlist_add(keys, _x->value) == NULL) {
    2.20 +    stringlist_t *_k = keys;
    2.21 +
    2.22 +    if (extra) {
    2.23 +        _k = stringlist_append(_k, extra);
    2.24 +        if (_k == NULL) {
    2.25 +            free_stringlist(keys);
    2.26              free_message(msg);
    2.27 -            free_stringlist(keys);
    2.28              return PEP_OUT_OF_MEMORY;
    2.29          }
    2.30      }
    2.31 -    
    2.32 +
    2.33 +    bool dest_keys_found = false;
    2.34      identity_list * _il;
    2.35      for (_il = msg->to; _il && _il->ident; _il = _il->next) {
    2.36 -        status = update_identity(session, _il->ident);
    2.37 -        if (status != PEP_STATUS_OK) {
    2.38 +        PEP_STATUS _status = update_identity(session, _il->ident);
    2.39 +        if (_status != PEP_STATUS_OK) {
    2.40              free_message(msg);
    2.41              free_stringlist(keys);
    2.42 -            return status;
    2.43 +            return _status;
    2.44          }
    2.45          if (_il->ident->fpr) {
    2.46 -            if (stringlist_add(keys, _il->ident->fpr) == NULL) {
    2.47 +            dest_keys_found = true;
    2.48 +            _k = stringlist_add(_k, _il->ident->fpr);
    2.49 +            if (_k == NULL) {
    2.50                  free_message(msg);
    2.51                  free_stringlist(keys);
    2.52                  return PEP_OUT_OF_MEMORY;
    2.53 @@ -68,22 +76,20 @@
    2.54              status = PEP_KEY_NOT_FOUND;
    2.55      }
    2.56  
    2.57 -    int _own_keys = 1;
    2.58 -    if (extra)
    2.59 -        _own_keys += stringlist_length(extra);
    2.60 -    
    2.61 -    if (stringlist_length(keys) > _own_keys) {
    2.62 +    if (dest_keys_found) {
    2.63          char *ptext;
    2.64          char *ctext = NULL;
    2.65          size_t csize = 0;
    2.66  
    2.67          switch (format) {
    2.68          case PEP_enc_MIME_multipart:
    2.69 +            NOT_IMPLEMENTED
    2.70              break;
    2.71  
    2.72          case PEP_enc_pieces:
    2.73              if (src->shortmsg && src->longmsg) {
    2.74 -                ptext = calloc(1, strlen(src->shortmsg) + strlen(src->longmsg) + 12);
    2.75 +                ptext = calloc(1, strlen(src->shortmsg) + strlen(src->longmsg)
    2.76 +                        + 12);
    2.77                  if (ptext == NULL) {
    2.78                      free_message(msg);
    2.79                      free_stringlist(keys);
    2.80 @@ -93,10 +99,10 @@
    2.81                  strcat(ptext, src->shortmsg);
    2.82                  strcat(ptext, "\n\n");
    2.83                  strcat(ptext, src->longmsg);
    2.84 -                status = encrypt_and_sign(session, keys, ptext, strlen(ptext), &ctext, &csize);
    2.85 +                status = encrypt_and_sign(session, keys, ptext, strlen(ptext),
    2.86 +                        &ctext, &csize);
    2.87                  if (ctext) {
    2.88                      msg->longmsg = ctext;
    2.89 -                    msg->longmsg_size = csize;
    2.90                      msg->shortmsg = strdup("pEp");
    2.91                  }
    2.92                  else {
    2.93 @@ -106,10 +112,10 @@
    2.94              }
    2.95              else if (src->shortmsg) {
    2.96                  ptext = src->shortmsg;
    2.97 -                status = encrypt_and_sign(session, keys, ptext, strlen(ptext), &ctext, &csize);
    2.98 +                status = encrypt_and_sign(session, keys, ptext, strlen(ptext),
    2.99 +                        &ctext, &csize);
   2.100                  if (ctext) {
   2.101                      msg->shortmsg = ctext;
   2.102 -                    msg->shortmsg_size = csize;
   2.103                  }
   2.104                  else {
   2.105                      free_message(msg);
   2.106 @@ -118,10 +124,10 @@
   2.107              }
   2.108              else if (src->longmsg) {
   2.109                  ptext = src->longmsg;
   2.110 -                status = encrypt_and_sign(session, keys, ptext, strlen(ptext), &ctext, &csize);
   2.111 +                status = encrypt_and_sign(session, keys, ptext, strlen(ptext),
   2.112 +                        &ctext, &csize);
   2.113                  if (ctext) {
   2.114                      msg->longmsg = ctext;
   2.115 -                    msg->longmsg_size = csize;
   2.116                      msg->shortmsg = strdup("pEp");
   2.117                  }
   2.118                  else {
   2.119 @@ -131,10 +137,10 @@
   2.120              }
   2.121              if (msg && msg->longmsg_formatted) {
   2.122                  ptext = src->longmsg_formatted;
   2.123 -                status = encrypt_and_sign(session, keys, ptext, strlen(ptext), &ctext, &csize);
   2.124 +                status = encrypt_and_sign(session, keys, ptext, strlen(ptext),
   2.125 +                        &ctext, &csize);
   2.126                  if (ctext) {
   2.127                      msg->longmsg_formatted = ctext;
   2.128 -                    msg->longmsg_formatted_size = csize;
   2.129                  }
   2.130                  else {
   2.131                      free_message(msg);
   2.132 @@ -143,7 +149,7 @@
   2.133              }
   2.134              if (msg) {
   2.135                  bloblist_t *_s;
   2.136 -                bloblist_t *_d = new_bloblist(NULL, 0);
   2.137 +                bloblist_t *_d = new_bloblist(NULL, 0, NULL, NULL);
   2.138                  if (_d == NULL) {
   2.139                      free_message(msg);
   2.140                      free_stringlist(keys);
   2.141 @@ -153,9 +159,16 @@
   2.142                  for (_s = src->attachments; _s && _s->data_ref; _s = _s->next) {
   2.143                      int psize = _s->size;
   2.144                      ptext = _s->data_ref;
   2.145 -                    status = encrypt_and_sign(session, keys, ptext, psize, &ctext, &csize);
   2.146 +                    status = encrypt_and_sign(session, keys, ptext, psize,
   2.147 +                            &ctext, &csize);
   2.148                      if (ctext) {
   2.149 -                        _d = bloblist_add(_d, ctext, csize);
   2.150 +                        _d = bloblist_add(_d, ctext, csize, _s->mime_type,
   2.151 +                                _s->file_name);
   2.152 +                        if (_d == NULL) {
   2.153 +                            free_message(msg);
   2.154 +                            free_stringlist(keys);
   2.155 +                            return PEP_OUT_OF_MEMORY;
   2.156 +                        }
   2.157                      }
   2.158                      else {
   2.159                          free_message(msg);
   2.160 @@ -163,6 +176,7 @@
   2.161                          break;
   2.162                      }
   2.163                  }
   2.164 +                msg->enc_format = PEP_enc_pieces;
   2.165                  *dst = msg;
   2.166              }
   2.167              break;
   2.168 @@ -186,6 +200,8 @@
   2.169  {
   2.170      PEP_STATUS status = PEP_STATUS_OK;
   2.171  
   2.172 +    NOT_IMPLEMENTED
   2.173 +
   2.174      return status;
   2.175  }
   2.176  
     3.1 --- a/src/message_api.h	Mon Dec 29 20:48:30 2014 +0100
     3.2 +++ b/src/message_api.h	Tue Dec 30 13:04:17 2014 +0100
     3.3 @@ -1,14 +1,25 @@
     3.4 +#pragma once
     3.5 +
     3.6  #ifdef __cplusplus
     3.7  extern "C" {
     3.8  #endif
     3.9  
    3.10  #include "transport.h"
    3.11  
    3.12 -typedef enum _PEP_enc_format {
    3.13 -    PEP_enc_none = 0,
    3.14 -    PEP_enc_MIME_multipart,
    3.15 -    PEP_enc_pieces
    3.16 -} PEP_enc_format;
    3.17 +
    3.18 +// encrypt_message() - encrypt message in memory
    3.19 +//
    3.20 +//  parameters:
    3.21 +//      session             session handle
    3.22 +//      src                 message to encrypt
    3.23 +//      extra               extra keys for encryption
    3.24 +//      dst                 pointer to encrypted message or NULL on failure
    3.25 +//      format              encryption format
    3.26 +//
    3.27 +//  return value:
    3.28 +//      error status or PEP_STATUS_OK on success; PEP_KEY_NOT_FOUND if one
    3.29 +//      or more keys couldn't be found, but the message could be encrypted
    3.30 +//      with other keys
    3.31  
    3.32  PEP_STATUS encrypt_message(
    3.33          PEP_SESSION session,
    3.34 @@ -18,6 +29,17 @@
    3.35          PEP_enc_format format
    3.36      );
    3.37  
    3.38 +
    3.39 +// decrypt_message() - decrypt message in memory
    3.40 +//
    3.41 +//  parameters:
    3.42 +//      session             session handle
    3.43 +//      src                 message to decrypt
    3.44 +//      dst                 pointer to decrypted message or NULL on failure
    3.45 +//
    3.46 +//  return value:
    3.47 +//      error status or PEP_STATUS_OK on success
    3.48 +
    3.49  PEP_STATUS decrypt_message(
    3.50          PEP_SESSION session,
    3.51          const message *src,
     4.1 --- a/src/pEpEngine.c	Mon Dec 29 20:48:30 2014 +0100
     4.2 +++ b/src/pEpEngine.c	Tue Dec 30 13:04:17 2014 +0100
     4.3 @@ -269,6 +269,27 @@
     4.4      return result;
     4.5  }
     4.6  
     4.7 +DYNAMIC_API stringlist_t *stringlist_dup(const stringlist_t *src)
     4.8 +{
     4.9 +    assert(src);
    4.10 +    if (src == NULL)
    4.11 +        return NULL;
    4.12 +
    4.13 +    stringlist_t *dst = new_stringlist(src->value);
    4.14 +    if (dst == NULL)
    4.15 +        return NULL;
    4.16 +
    4.17 +    if (src->next) {
    4.18 +        dst->next = stringlist_dup(src->next);
    4.19 +        if (dst->next == NULL) {
    4.20 +            free(dst);
    4.21 +            return NULL;
    4.22 +        }
    4.23 +    }
    4.24 +
    4.25 +    return dst;
    4.26 +}
    4.27 +
    4.28  stringlist_t *stringlist_add(stringlist_t *stringlist, const char *value)
    4.29  {
    4.30      assert(value);
    4.31 @@ -294,6 +315,24 @@
    4.32      return stringlist->next;
    4.33  }
    4.34  
    4.35 +DYNAMIC_API stringlist_t *stringlist_append(stringlist_t *stringlist,
    4.36 +        stringlist_t *second)
    4.37 +{
    4.38 +    assert(stringlist);
    4.39 +
    4.40 +    if (second == NULL || second->value == NULL)
    4.41 +        return stringlist;
    4.42 +
    4.43 +    stringlist_t *_s = stringlist;
    4.44 +    stringlist_t *_s2;
    4.45 +    for (_s2 = second; _s2 != NULL; _s2 = _s2->next) {
    4.46 +        _s = stringlist_add(_s, _s2->value);
    4.47 +        if (_s == NULL)
    4.48 +            return NULL;
    4.49 +    }
    4.50 +    return _s;
    4.51 +}
    4.52 +
    4.53  int stringlist_length(const stringlist_t *stringlist)
    4.54  {
    4.55      int len = 1;
     5.1 --- a/src/pEpEngine.h	Mon Dec 29 20:48:30 2014 +0100
     5.2 +++ b/src/pEpEngine.h	Tue Dec 30 13:04:17 2014 +0100
     5.3 @@ -126,6 +126,17 @@
     5.4  DYNAMIC_API stringlist_t *new_stringlist(const char *value);
     5.5  
     5.6  
     5.7 +// stringlist_dup() - duplicate a stringlist
     5.8 +//
     5.9 +//  parameters:
    5.10 +//      src (in)            stringlist to copy
    5.11 +//
    5.12 +//  return value:
    5.13 +//      pointer to stringlist_t object or NULL if out of memory
    5.14 +
    5.15 +DYNAMIC_API stringlist_t *stringlist_dup(const stringlist_t *src);
    5.16 +
    5.17 +
    5.18  // stringlist_add() - add key to stringlist
    5.19  //
    5.20  //  parameters:
    5.21 @@ -142,6 +153,23 @@
    5.22  DYNAMIC_API stringlist_t *stringlist_add(stringlist_t *stringlist, const char *value);
    5.23  
    5.24  
    5.25 +// stringlist_append() - append stringlist to stringlist
    5.26 +//
    5.27 +//  parameters:
    5.28 +//      stringlist (in)     stringlist struct to append to
    5.29 +//      second (in)         stringlist struct to append
    5.30 +//
    5.31 +//  return value:
    5.32 +//      pointer to last element in stringlist or NULL if out of memory
    5.33 +//
    5.34 +//  caveat:
    5.35 +//      all values are being copied before being added to the list
    5.36 +//      the original values are still being owned by the caller
    5.37 +
    5.38 +DYNAMIC_API stringlist_t *stringlist_append(stringlist_t *stringlist,
    5.39 +        stringlist_t *second);
    5.40 +
    5.41 +
    5.42  // stringlist_length() - get length of stringlist
    5.43  //
    5.44  //  parameters:
     6.1 --- a/src/transport.c	Mon Dec 29 20:48:30 2014 +0100
     6.2 +++ b/src/transport.c	Tue Dec 30 13:04:17 2014 +0100
     6.3 @@ -24,21 +24,14 @@
     6.4      // nothing yet
     6.5  }
     6.6  
     6.7 -identity_list *new_identity_list(const pEp_identity *ident)
     6.8 +identity_list *new_identity_list(pEp_identity *ident)
     6.9  {
    6.10      identity_list *id_list = calloc(1, sizeof(identity_list));
    6.11      assert(id_list);
    6.12      if (id_list == NULL)
    6.13          return NULL;
    6.14  
    6.15 -    if (ident) {
    6.16 -        id_list->ident = identity_dup(ident);
    6.17 -        assert(id_list->ident);
    6.18 -        if (id_list->ident == NULL) {
    6.19 -            free(id_list);
    6.20 -            return NULL;
    6.21 -        }
    6.22 -    }
    6.23 +    id_list->ident = ident;
    6.24  
    6.25      return id_list;
    6.26  }
    6.27 @@ -72,7 +65,7 @@
    6.28      }
    6.29  }
    6.30  
    6.31 -identity_list *identity_list_add(identity_list *id_list, const pEp_identity *ident)
    6.32 +identity_list *identity_list_add(identity_list *id_list, pEp_identity *ident)
    6.33  {
    6.34      assert(ident);
    6.35  
    6.36 @@ -80,16 +73,11 @@
    6.37          return new_identity_list(ident);
    6.38  
    6.39      if (id_list->ident == NULL) {
    6.40 -        id_list->ident = identity_dup(ident);
    6.41 -        assert(id_list->ident);
    6.42 -        if (id_list->ident == NULL)
    6.43 -            return NULL;
    6.44 -        else
    6.45 -            return id_list;
    6.46 +        id_list->ident = ident;
    6.47 +        return id_list;
    6.48      }
    6.49      else if (id_list->next == NULL) {
    6.50          id_list->next = new_identity_list(ident);
    6.51 -        assert(id_list->next);
    6.52          return id_list->next;
    6.53      }
    6.54      else {
    6.55 @@ -97,13 +85,29 @@
    6.56      }
    6.57  }
    6.58  
    6.59 -bloblist_t *new_bloblist(char *blob, size_t size)
    6.60 +bloblist_t *new_bloblist(char *blob, size_t size, const char *mime_type,
    6.61 +        const char *file_name)
    6.62  {
    6.63      bloblist_t * bloblist = calloc(1, sizeof(bloblist_t));
    6.64      if (bloblist == NULL)
    6.65          return NULL;
    6.66      bloblist->data_ref = blob;
    6.67      bloblist->size = size;
    6.68 +    if (mime_type) {
    6.69 +        bloblist->mime_type = strdup(mime_type);
    6.70 +        if (bloblist->mime_type == NULL) {
    6.71 +            free(bloblist);
    6.72 +            return NULL;
    6.73 +        }
    6.74 +    }
    6.75 +    if (file_name) {
    6.76 +        bloblist->file_name = strdup(file_name);
    6.77 +        if (bloblist->file_name == NULL) {
    6.78 +            free(bloblist->mime_type);
    6.79 +            free(bloblist);
    6.80 +            return NULL;
    6.81 +        }
    6.82 +    }
    6.83      return bloblist;
    6.84  }
    6.85  
    6.86 @@ -112,7 +116,8 @@
    6.87      assert(src);
    6.88  
    6.89      if (src) {
    6.90 -        bloblist_t * dst = new_bloblist(src->data_ref, src->size);
    6.91 +        bloblist_t * dst = new_bloblist(src->data_ref, src->size,
    6.92 +                src->mime_type, src->file_name);
    6.93          if (dst == NULL)
    6.94              return NULL;
    6.95          dst->next = bloblist_dup(src->next);
    6.96 @@ -124,36 +129,58 @@
    6.97  
    6.98  void free_bloblist(bloblist_t *bloblist)
    6.99  {
   6.100 -    if (bloblist && bloblist->next)
   6.101 -        free_bloblist(bloblist->next);
   6.102 -    free(bloblist);
   6.103 +    if (bloblist) {
   6.104 +        if (bloblist->next)
   6.105 +            free_bloblist(bloblist->next);
   6.106 +        if (bloblist->mime_type)
   6.107 +            free(bloblist->mime_type);
   6.108 +        if (bloblist->file_name)
   6.109 +            free(bloblist->file_name);
   6.110 +        free(bloblist);
   6.111 +    }
   6.112  }
   6.113  
   6.114 -bloblist_t *bloblist_add(bloblist_t *bloblist, char *blob, size_t size)
   6.115 +bloblist_t *bloblist_add(bloblist_t *bloblist, char *blob, size_t size,
   6.116 +        const char *mime_type, const char *file_name)
   6.117  {
   6.118      assert(blob);
   6.119  
   6.120      if (bloblist == NULL)
   6.121 -        return new_bloblist(blob, size);
   6.122 +        return new_bloblist(blob, size, mime_type, file_name);
   6.123  
   6.124      if (bloblist->data_ref == NULL) {
   6.125          bloblist->data_ref = blob;
   6.126          bloblist->size = size;
   6.127 +        if (mime_type) {
   6.128 +            bloblist->mime_type = strdup(mime_type);
   6.129 +            if (bloblist->mime_type == NULL) {
   6.130 +                free(bloblist);
   6.131 +                return NULL;
   6.132 +            }
   6.133 +        }
   6.134 +        if (file_name) {
   6.135 +            bloblist->file_name = strdup(file_name);
   6.136 +            if (bloblist->file_name == NULL) {
   6.137 +                free(bloblist->mime_type);
   6.138 +                free(bloblist);
   6.139 +                return NULL;
   6.140 +            }
   6.141 +        }
   6.142          return bloblist;
   6.143      }
   6.144  
   6.145      if (bloblist->next == NULL) {
   6.146 -        bloblist->next = new_bloblist(blob, size);
   6.147 +        bloblist->next = new_bloblist(blob, size, mime_type, file_name);
   6.148          return bloblist->next;
   6.149      }
   6.150  
   6.151 -    return bloblist_add(bloblist->next, blob, size);
   6.152 +    return bloblist_add(bloblist->next, blob, size, mime_type, file_name);
   6.153  }
   6.154  
   6.155  message *new_message(
   6.156          PEP_msg_direction dir,
   6.157 -        const pEp_identity *from,
   6.158 -        const identity_list *to,
   6.159 +        pEp_identity *from,
   6.160 +        identity_list *to,
   6.161          const char *shortmsg
   6.162      )
   6.163  {
   6.164 @@ -162,31 +189,18 @@
   6.165      if (msg == NULL)
   6.166          return NULL;
   6.167  
   6.168 -    if (msg->shortmsg) {
   6.169 +    if (shortmsg) {
   6.170          msg->shortmsg = strdup(shortmsg);
   6.171          assert(msg->shortmsg);
   6.172          if (msg->shortmsg == NULL) {
   6.173              free(msg);
   6.174              return NULL;
   6.175          }
   6.176 -        msg->shortmsg_size = strlen(msg->shortmsg);
   6.177      }
   6.178  
   6.179      msg->dir = dir;
   6.180 -
   6.181 -    msg->from = identity_dup(from);
   6.182 -    assert(msg->from);
   6.183 -    if (msg->from == NULL) {
   6.184 -        free_message(msg);
   6.185 -        return NULL;
   6.186 -    }
   6.187 -
   6.188 -    msg->to = identity_list_dup(to);
   6.189 -    assert(msg->to);
   6.190 -    if (msg->to == NULL) {
   6.191 -        free_message(msg);
   6.192 -        return NULL;
   6.193 -    }
   6.194 +    msg->from = from;
   6.195 +    msg->to = to;
   6.196  
   6.197      return msg;
   6.198  }
   6.199 @@ -198,7 +212,6 @@
   6.200      free(msg->longmsg);
   6.201      free(msg->longmsg_formatted);
   6.202      free_bloblist(msg->attachments);
   6.203 -    free(msg->rawmsg);
   6.204      free_identity_list(msg->to);
   6.205      free_identity_list(msg->cc);
   6.206      free_identity_list(msg->bcc);
     7.1 --- a/src/transport.h	Mon Dec 29 20:48:30 2014 +0100
     7.2 +++ b/src/transport.h	Tue Dec 30 13:04:17 2014 +0100
     7.3 @@ -2,7 +2,6 @@
     7.4  
     7.5  #include "pEpEngine.h"
     7.6  #include <time.h>
     7.7 -#include <stdlib.h>
     7.8  
     7.9  // all functions are using POSIX struct tm
    7.10  
    7.11 @@ -24,10 +23,57 @@
    7.12      struct _identity_list *next;
    7.13  } identity_list;
    7.14  
    7.15 -identity_list *new_identity_list(const pEp_identity *ident);
    7.16 +
    7.17 +// new_identity_list() - allocate a new identity list
    7.18 +//
    7.19 +//  parameters:
    7.20 +//      ident               identity to move for first element
    7.21 +//
    7.22 +//  return value:
    7.23 +//      new identity_list or NULL if out of memory
    7.24 +//
    7.25 +//  caveat:
    7.26 +//      ident is being moved, the caller loses ownership
    7.27 +
    7.28 +identity_list *new_identity_list(pEp_identity *ident);
    7.29 +
    7.30 +
    7.31 +// identity_list_dup() - duplicate identity_list (deep copy)
    7.32 +//
    7.33 +//  parameters:
    7.34 +//      id_list             identity_list to copy
    7.35 +//
    7.36 +//  return value:
    7.37 +//      new identity_list or NULL if out of memory
    7.38 +
    7.39  identity_list *identity_list_dup(const identity_list *src);
    7.40 +
    7.41 +
    7.42 +// free_identity_list() - free memory allocated by identity_list
    7.43 +//
    7.44 +//  parameters:
    7.45 +//      id_list             identity_list to free
    7.46 +//
    7.47 +//  caveat:
    7.48 +//      this function frees all identities in the list additional to the
    7.49 +//      identity_list itself
    7.50 +
    7.51  void free_identity_list(identity_list *id_list);
    7.52 -identity_list *identity_list_add(identity_list *id_list, const pEp_identity *ident);
    7.53 +
    7.54 +
    7.55 +// identity_list_add - add identity to an identity_list
    7.56 +//
    7.57 +//  parameters:
    7.58 +//      id_list             identity_list to add to
    7.59 +//      ident               identity being added
    7.60 +//
    7.61 +//  return value:
    7.62 +//      pointer to the last element in identity_list or NULL if out of memory
    7.63 +//
    7.64 +//  caveat:
    7.65 +//      ident is being moved, the caller loses ownership
    7.66 +
    7.67 +identity_list *identity_list_add(identity_list *id_list, pEp_identity *ident);
    7.68  
    7.69  typedef enum _PEP_msg_format {
    7.70      PEP_format_plain = 0,
    7.71 @@ -40,73 +86,210 @@
    7.72  } PEP_msg_direction;
    7.73  
    7.74  typedef struct _bloblist_t {
    7.75 -    char *data_ref;
    7.76 -    size_t size;
    7.77 +    char *data_ref;                 // reference to blob
    7.78 +    size_t size;                    // size of blob
    7.79 +    char *mime_type;                // UTF-8 string of MIME type of blob or
    7.80 +                                    // NULL if unknown
    7.81 +    char *file_name;                // UTF-8 string of file name of blob or
    7.82 +                                    // NULL if unknown
    7.83      struct _bloblist_t *next;
    7.84  } bloblist_t;
    7.85  
    7.86 -bloblist_t *new_bloblist(char *blob, size_t size);
    7.87 +
    7.88 +// new_bloblist() - allocate a new bloblist
    7.89 +//
    7.90 +//  parameters:
    7.91 +//      blob            pointer to blob to add to the list
    7.92 +//      size            size of the blob
    7.93 +//      mime_type       MIME type of the blob data or NULL if unknown
    7.94 +//      file_name       file name of origin of blob data or NULL if unknown
    7.95 +//
    7.96 +//  return value:
    7.97 +//      pointer to new bloblist_t or NULL if out of memory
    7.98 +//
    7.99 +//  caveat:
   7.100 +//      the blob isn't copied, but only a reference is handled; the blob
   7.101 +//      remains in the ownership of the caller and must not be deleted until
   7.102 +//      the bloblist is deleted first; mime_type and file_name are being
   7.103 +//      copied, the originals remain in the ownership of the caller
   7.104 +
   7.105 +bloblist_t *new_bloblist(char *blob, size_t size, const char *mime_type,
   7.106 +        const char *file_name);
   7.107 +
   7.108 +
   7.109 +// bloblist_dup() - duplicate bloblist (deep copy)
   7.110 +//
   7.111 +//  paramters:
   7.112 +//      src             bloblist to duplicate
   7.113 +//
   7.114 +//  return value:
   7.115 +//      new bloblist or NULL if out of memory
   7.116 +//
   7.117 +//  caveat:
   7.118 +//      the blobs referenced by the lists aren't copied, so both bloblists
   7.119 +//      reference the same blob data; mime_types and file_names are duplicated
   7.120 +//      as well, though
   7.121 +
   7.122  bloblist_t *bloblist_dup(const bloblist_t *src);
   7.123 +
   7.124 +
   7.125 +// free_bloblist() - free bloblist
   7.126 +//
   7.127 +//  parameters:
   7.128 +//      bloblist        bloblist to free
   7.129 +//
   7.130 +//  caveat:
   7.131 +//      the blobs in the bloblist aren't freed and remain in the ownership of
   7.132 +//      the caller; all other data is being freed
   7.133 +
   7.134  void free_bloblist(bloblist_t *bloblist);
   7.135 -bloblist_t *bloblist_add(bloblist_t *bloblist, char *blob, size_t size);
   7.136 +
   7.137 +
   7.138 +// bloblist_add() - add reference to a blob to bloblist
   7.139 +//
   7.140 +//  parameters:
   7.141 +//      bloblist        bloblist to add to
   7.142 +//      blob            reference to a blob
   7.143 +//      size            size of the blob
   7.144 +//      mime_type       MIME type of the blob or NULL if unknown
   7.145 +//      file_name       file name of the blob or NULL if unknown
   7.146 +//
   7.147 +//  return value:
   7.148 +//      pointer to the last element of bloblist or NULL if out of memory
   7.149 +//
   7.150 +//  caveat:
   7.151 +//      the blob isn't copied, instead a reference is added to bloblist;
   7.152 +//      mime_type and file_name are copied, the originals remain in the
   7.153 +//      ownership of the caller
   7.154 +
   7.155 +bloblist_t *bloblist_add(bloblist_t *bloblist, char *blob, size_t size,
   7.156 +        const char *mime_type, const char *file_name);
   7.157 +
   7.158 +
   7.159 +typedef enum _PEP_enc_format {
   7.160 +    PEP_enc_none = 0,
   7.161 +    PEP_enc_MIME_multipart,
   7.162 +    PEP_enc_pieces
   7.163 +} PEP_enc_format;
   7.164  
   7.165  struct _message_ref_list;
   7.166  
   7.167  typedef struct _message {
   7.168      PEP_msg_direction dir;
   7.169 -    char * id;
   7.170 -    size_t id_size;
   7.171 -    char * shortmsg;
   7.172 -    size_t shortmsg_size;
   7.173 -    char * longmsg;
   7.174 -    size_t longmsg_size;
   7.175 -    char * longmsg_formatted;
   7.176 -    size_t longmsg_formatted_size;
   7.177 -    PEP_msg_format format;
   7.178 -    bloblist_t * attachments;
   7.179 -    char * rawmsg;
   7.180 -    size_t rawmsg_size;
   7.181 -    timestamp sent;
   7.182 -    timestamp recv;
   7.183 -    pEp_identity *from;
   7.184 -    identity_list *to;
   7.185 -    pEp_identity *recv_by;
   7.186 -    identity_list *cc;
   7.187 -    identity_list *bcc;
   7.188 -    char * refering_id;
   7.189 -    size_t refering_id_size;
   7.190 -    struct _message *refering_msg;
   7.191 -    struct _message_ref_list *refered_by;
   7.192 -    bool encrypted;
   7.193 +    char * id;                              // UTF-8 string of message ID
   7.194 +    char * shortmsg;                        // UTF-8 string of short message
   7.195 +    char * longmsg;                         // UTF-8 string of long message
   7.196 +                                            // (plain)
   7.197 +    char * longmsg_formatted;               // UTF-8 string of long message
   7.198 +                                            // (formatted)
   7.199 +    PEP_msg_format format;                  // format type
   7.200 +    bloblist_t * attachments;               // blobs with attachements
   7.201 +    char * rawmsg_ref;                      // reference to raw message data
   7.202 +    size_t rawmsg_size;                     // size of raw message data
   7.203 +    timestamp sent;                         // when the message is sent
   7.204 +    timestamp recv;                         // when the message is received
   7.205 +    pEp_identity *from;                     // whom the message is from
   7.206 +    identity_list *to;                      // whom the message is to
   7.207 +    pEp_identity *recv_by;                  // via which identity the message
   7.208 +                                            // is received
   7.209 +    identity_list *cc;                      // whom a CC is being sent
   7.210 +    identity_list *bcc;                     // whom a BCC is being sent
   7.211 +    char * refering_id;                     // UTF-8 string of refering message ID
   7.212 +    struct _message *refering_msg_ref;      // reference to refering message
   7.213 +    struct _message_ref_list *refered_by;   // list of references to messages being
   7.214 +                                            // refered
   7.215 +    PEP_enc_format enc_format;              // format of encrypted data
   7.216  } message;
   7.217  
   7.218  typedef struct _message_ref_list {
   7.219 -    message *msg_ref;
   7.220 +    message *msg_ref;                       // reference to message
   7.221      struct _message_ref_list *next;
   7.222  } message_ref_list;
   7.223  
   7.224 +
   7.225 +// new_message() - allocate new message
   7.226 +//
   7.227 +//  parameters:
   7.228 +//      dir             PEP_dir_incoming or PEP_dir_outgoing
   7.229 +//      from            identity whom the message is from
   7.230 +//      to              identity list whom the message is sent to
   7.231 +//      shortmsg        UTF-8 string of short message
   7.232 +//
   7.233 +//  return value:
   7.234 +//      pointer to new message or NULL if out of memory
   7.235 +//
   7.236 +//  caveat:
   7.237 +//      from and to are moved into the message, the caller loses ownership for
   7.238 +//      them; shortmsg is being copied, the ownership of the original remains
   7.239 +//      with the caller
   7.240 +
   7.241  message *new_message(
   7.242          PEP_msg_direction dir,
   7.243 -        const pEp_identity *from,
   7.244 -        const identity_list *to,
   7.245 +        pEp_identity *from,
   7.246 +        identity_list *to,
   7.247          const char *shortmsg
   7.248      );
   7.249  
   7.250 +
   7.251 +// free_message() - free message struct
   7.252 +//
   7.253 +//  parameters:
   7.254 +//      msg             message struct to free
   7.255 +//
   7.256 +//  caveat:
   7.257 +//      raw data as well as referenced other messages aren't freed and remain
   7.258 +//      in the ownership of the caller
   7.259 +
   7.260  void free_message(message *msg);
   7.261  
   7.262 +
   7.263 +// new_message_ref_list() - allocate new message reference list
   7.264 +//
   7.265 +//  parameters:
   7.266 +//      msg             message to add a reference to or NULL
   7.267 +//
   7.268 +//  return value:
   7.269 +//      pointer to new message_ref_list or NULL if out of memory
   7.270 +
   7.271  message_ref_list *new_message_ref_list(message *msg);
   7.272 +
   7.273 +
   7.274 +// free_message_ref_list() - free message reference list
   7.275 +//
   7.276 +//  parameters:
   7.277 +//      msg_list        message_ref_list to free
   7.278 +
   7.279  void free_message_ref_list(message_ref_list *msg_list);
   7.280 -message_ref_list *message_ref_list_add(message_ref_list *msg_list, message *msg);
   7.281 +
   7.282 +
   7.283 +// message_ref_list_add() - add a reference to a message to a message reference
   7.284 +// list
   7.285 +//
   7.286 +//  parameters:
   7.287 +//      msg_list        message_ref_list to add to
   7.288 +//      msg             message to add a reference to
   7.289 +//
   7.290 +//  return value:
   7.291 +//      pointer to the last element of message_ref_list or NULL if out of
   7.292 +//      memory
   7.293 +
   7.294 +message_ref_list *message_ref_list_add(message_ref_list *msg_list,
   7.295 +        message *msg);
   7.296 +
   7.297  
   7.298  typedef PEP_STATUS (*sendto_t)(PEP_SESSION session, const message *msg);
   7.299 -typedef PEP_STATUS (*readnext_t)(PEP_SESSION session, message **msg, PEP_transport_t **via);
   7.300 +typedef PEP_STATUS (*readnext_t)(PEP_SESSION session, message **msg,
   7.301 +        PEP_transport_t **via);
   7.302  
   7.303  struct _PEP_transport_t {
   7.304 -    uint8_t id;
   7.305 -    sendto_t sendto;
   7.306 -    readnext_t readnext;
   7.307 -    bool long_message_supported;
   7.308 -    PEP_msg_format native_format;
   7.309 +    uint8_t id;                             // transport ID
   7.310 +    sendto_t sendto;                        // sendto function
   7.311 +    readnext_t readnext;                    // readnext function
   7.312 +    bool long_message_supported;            // flag if this transport supports
   7.313 +                                            // long messages
   7.314 +    bool formatted_message_supported;       // flag if this transport supports
   7.315 +                                            // formatted messages
   7.316 +    PEP_msg_format native_format;           // native format of the transport
   7.317  };
   7.318  
   7.319  typedef uint64_t transports_mask;
     8.1 --- a/test/Makefile	Mon Dec 29 20:48:30 2014 +0100
     8.2 +++ b/test/Makefile	Tue Dec 30 13:04:17 2014 +0100
     8.3 @@ -9,11 +9,12 @@
     8.4  LD=g++
     8.5  LDFLAGS=-pthread -L../src -lpEpEngine -lstdc++
     8.6  else
     8.7 +CC=g++ -std=gnu++11
     8.8  CXX=g++ -std=gnu++11
     8.9  LD=g++
    8.10 -LDFLAGS=-L~/lib -pthread -L../src -lpEpEngine -lstdc++
    8.11 +LDFLAGS=-L$(HOME)/lib -pthread -lpEpEngine -lstdc++
    8.12  endif
    8.13 -CXXFLAGS=-g -O0
    8.14 +CXXFLAGS=-g -O0 -I../src
    8.15  # CXXFLAGS=-O3 -DNDEBUG
    8.16  
    8.17  TARGET=pEpEngineTest
    8.18 @@ -44,8 +45,11 @@
    8.19  .PHONY: clean
    8.20  
    8.21  clean:
    8.22 -	rm -f *.o $(TARGET) *.exe *.a *~ pEpEngine.dll
    8.23 +	rm -f *.o $(TARGET) *.exe *.a *~ pEpEngine.dll message_api_test
    8.24  
    8.25  test: all
    8.26  	LD_LIBRARY_PATH=~/lib:../src ./pEpEngineTest
    8.27  
    8.28 +message_api_test: message_api_test.o
    8.29 +	$(CXX) $(LDFLAGS) -o message_api_test message_api_test.o
    8.30 +
     9.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.2 +++ b/test/message_api_test.cc	Tue Dec 30 13:04:17 2014 +0100
     9.3 @@ -0,0 +1,28 @@
     9.4 +#include <iostream>
     9.5 +#include <assert.h>
     9.6 +#include "message_api.h"
     9.7 +
     9.8 +using namespace std;
     9.9 +
    9.10 +int main() {
    9.11 +    PEP_SESSION session;
    9.12 +    
    9.13 +    cout << "calling init()\n";
    9.14 +    PEP_STATUS status1 = init(&session);   
    9.15 +    assert(status1 == PEP_STATUS_OK);
    9.16 +    assert(session);
    9.17 +    cout << "init() completed.\n";
    9.18 +
    9.19 +    pEp_identity * me = new_identity("outlooktest@dingens.org", NULL, "23", "Outlook Test");
    9.20 +    me->me = true;
    9.21 +    identity_list *to = new_identity_list(new_identity("vb@dingens.org", NULL, "42", "Volker Birk"));
    9.22 +
    9.23 +    message *msg = new_message(PEP_dir_outgoing, me, to, "hello, world");
    9.24 +
    9.25 +    free_message(msg);
    9.26 +
    9.27 +    cout << "calling release()\n";
    9.28 +    release(session);
    9.29 +    return 0;
    9.30 +}
    9.31 +