merge "default" into my branch and solve some minor merge conflicts roker-linux
authorRoker <roker@pep-project.org>
Sun, 10 Jul 2016 13:57:27 +0200
branchroker-linux
changeset 837bdff704cd921
parent 801 02da5655fa56
parent 836 8e7dac747b49
child 856 3061adc7e3c6
merge "default" into my branch and solve some minor merge conflicts
Makefile.conf
src/Makefile
sync/sync.fsm
     1.1 --- a/.hgignore	Mon Jul 04 13:38:14 2016 +0200
     1.2 +++ b/.hgignore	Sun Jul 10 13:57:27 2016 +0200
     1.3 @@ -33,4 +33,6 @@
     1.4  msg4.asc
     1.5  pep_Dokument_Titel.pdf
     1.6  pEpEngine.vcxproj.user
     1.7 -
     1.8 +*.skeleton
     1.9 +.skeletons
    1.10 +.statemachines
     2.1 --- a/Makefile	Mon Jul 04 13:38:14 2016 +0200
     2.2 +++ b/Makefile	Sun Jul 10 13:57:27 2016 +0200
     2.3 @@ -18,6 +18,7 @@
     2.4  	$(MAKE) -C src clean
     2.5  	$(MAKE) -C test clean
     2.6  	$(MAKE) -C db clean
     2.7 +	$(MAKE) -C sync clean
     2.8  	$(MAKE) -C asn.1 clean
     2.9  
    2.10  test: all
     3.1 --- a/Makefile.conf	Mon Jul 04 13:38:14 2016 +0200
     3.2 +++ b/Makefile.conf	Sun Jul 10 13:57:27 2016 +0200
     3.3 @@ -1,7 +1,7 @@
     3.4  BUILD_ON=$(shell uname)
     3.5  BUILD_FOR=$(BUILD_ON)
     3.6  OPTIMIZE=-g -O0 -Wall -fPIC -fstack-protector-strong
     3.7 -#OPTIMIZE=-O3 -DNDEBUG -std=c99
     3.8 +#OPTIMIZE=-O3 -Wall -DNDEBUG -std=c99
     3.9  LD=$(CC)
    3.10  #CC=gcc-mp-4.9 -std=c99 -fstrict-aliasing -Wstrict-aliasing=3
    3.11  #LD=gcc-mp-4.9
    3.12 @@ -11,9 +11,6 @@
    3.13  YML_PATH=$(HOME)/something/yml2
    3.14  ASN1C=/home/deb/local/bin/asn1c
    3.15  
    3.16 -# TODO: For brew this is /usr/local/share/asn1c
    3.17 -# On BSDs, it might be that as well. How to check?
    3.18 -# For now, it just works, even when it doesn't exist.
    3.19  ASN1C_INCLUDE=/usr/local/share/asn1c
    3.20  
    3.21  # C makros (not environment variables) to overwrite:
     4.1 --- a/README-OSX.md	Mon Jul 04 13:38:14 2016 +0200
     4.2 +++ b/README-OSX.md	Sun Jul 10 13:57:27 2016 +0200
     4.3 @@ -1,21 +1,119 @@
     4.4 -# Dependencies
     4.5 +# Building for OS X/macOS
     4.6  
     4.7 -You need a working [asn1c](https://lionet.info/asn1c/blog/).
     4.8 +See also README.txt for general information.
     4.9 +
    4.10 +## Dependencies
    4.11 +
    4.12 +### MacPorts
    4.13 +
    4.14 +Install [MacPorts](https://www.macports.org/) for your
    4.15 +[version of OS X/macOS](https://www.macports.org/install.php).
    4.16 +
    4.17 +Note that you need [Xcode installed](https://www.macports.org/install.php)
    4.18 +for MacPorts, and for building the engine. You also need to accept Xcode's EULA.
    4.19 +
    4.20 +*Note*: Use the script `macports_env.sh` (or a similar one) to set up a clean build environment
    4.21 +before building the engine:
    4.22  
    4.23  ```
    4.24 -brew install asn1c
    4.25 +. macports_env.sh
    4.26  ```
    4.27  
    4.28 -# Building for OS X
    4.29 +If you don't use that environment, please make sure you've set up all search paths correctly.
    4.30  
    4.31 -## Build libetpan
    4.32 +#### MacPorts dependencies
    4.33  
    4.34  ```
    4.35 -cd pEpEngine
    4.36 -autoreconf -vfi
    4.37 -./configure
    4.38 +sudo port install mercurial
    4.39 +sudo port install py27-lxml
    4.40 +sudo port install gpgme
    4.41 +sudo port install autoconf
    4.42 +sudo port install asn1c
    4.43 +sudo port install zlib
    4.44 +```
    4.45 +
    4.46 +### Other dependecies
    4.47 +
    4.48 +#### [yml2](https://fdik.org/yml/toolchain)
    4.49 +
    4.50 +Install into your home directory:
    4.51 +
    4.52 +```
    4.53 +pushd ~
    4.54 +curl -LO http://fdik.org/yml2.tar.bz2
    4.55 +tar xf yml2.tar.bz2
    4.56 +rm yml2.tar.bz2*
    4.57 +popd
    4.58 +```
    4.59 +
    4.60 +#### libetpan
    4.61 +
    4.62 +Note: libetpan needs libz and libiconv, but the libiconv from MacPorts is not compatible, some
    4.63 +functions seem to have been renamed there. Therefore the dynlib from OS X is used.
    4.64 +
    4.65 +```
    4.66 +git clone https://github.com/fdik/libetpan libetpan-osx
    4.67 +cd libetpan-osx/
    4.68 +./autogen.sh
    4.69  make
    4.70 +cp ./src/.libs/libetpan.a ~/lib/
    4.71 +```
    4.72 +
    4.73 +##### libetpan with xcodebuild
    4.74 +
    4.75 +The build with autoconf (see previous section) is preferred. This is just for completeness.
    4.76 +*Don't actually build libetpan with xcodebuild.*
    4.77 +
    4.78 +```
    4.79 +git clone https://github.com/fdik/libetpan libetpan-osx
    4.80 +cd libetpan-osx/build-mac
    4.81 +xcodebuild -project libetpan.xcodeproj/ -target "static libetpan"
    4.82 +mkdir ~/lib
    4.83 +cp build/Release/libetpan.a ~/lib/
    4.84 +```
    4.85 +
    4.86 +### Configuration
    4.87 +
    4.88 +You can change some defaults by editing `Makefile.conf`. But this readme assumes you don't.
    4.89 +
    4.90 +### Build
    4.91 +
    4.92 +```
    4.93 +make clean
    4.94 +make all
    4.95 +make db
    4.96 +```
    4.97 +
    4.98 +Done! The result should be (among others):
    4.99 +
   4.100 +```
   4.101 +./src/libpEpEngine.a
   4.102 +./src/libpEpEngine.dylib
   4.103 +```
   4.104 +
   4.105 +### Install
   4.106 +
   4.107 +Install (you might need sudo for some commands, depending on how your system is set up):
   4.108 +
   4.109 +```
   4.110  make install
   4.111 +make -C db install
   4.112 +```
   4.113 +
   4.114 +Since the `system.db` rarely changes, `make -C db install` is not needed for every build.
   4.115 +
   4.116 +### Run tests
   4.117 +
   4.118 +Make sure that you add `/opt/local/lib` to each definition of `LD_LIBRARY_PATH`
   4.119 +in `test/Makefile`. This ensures that libgpgme will be found:
   4.120 +
   4.121 +```
   4.122 +test: pEpEngineTest
   4.123 +        LD_LIBRARY_PATH=/opt/local/lib:~/lib:../src ./pEpEngineTest
   4.124 +```
   4.125 +
   4.126 +```
   4.127 +make test
   4.128  ```
   4.129  
   4.130  # Building for iOS
     5.1 --- a/README.txt	Mon Jul 04 13:38:14 2016 +0200
     5.2 +++ b/README.txt	Sun Jul 10 13:57:27 2016 +0200
     5.3 @@ -61,6 +61,7 @@
     5.4  * Asn1c, download from https://lionet.info/soft/asn1c-0.9.27.tar.gz
     5.5         (Debian's version 0.9.24 does not work)
     5.6  
     5.7 +* yml2, which needs lxml (where to get?)
     5.8  
     5.9  2. Building p≡p engine
    5.10  ----------------------
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/db/mkpass	Sun Jul 10 13:57:27 2016 +0200
     6.3 @@ -0,0 +1,13 @@
     6.4 +#!/bin/sh
     6.5 +
     6.6 +if [ $1/ == / ] ; then
     6.7 +    lang=en
     6.8 +else
     6.9 +    if [ $1/ == -h/ -o $2/ != / ] ; then
    6.10 +        echo usage: $0 [ISO 639 language code]
    6.11 +        exit 0
    6.12 +    fi
    6.13 +    lang=$1
    6.14 +fi
    6.15 +
    6.16 +trustwords.py -l $lang ` hexdump -vxn 10 /dev/random | sed -E 's/^[0-9a-z]+//'`
     7.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.2 +++ b/macports_env.sh	Sun Jul 10 13:57:27 2016 +0200
     7.3 @@ -0,0 +1,14 @@
     7.4 +# Typical pure MacPorts environment
     7.5 +
     7.6 +# Restrict to MacPorts
     7.7 +export PATH=/opt/local/bin:/opt/local/sbin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/X11/bin
     7.8 +
     7.9 +# Make sure the Apple python (which will be triggered by the makefile)
    7.10 +# has access to the Python libs installed for MacPorts
    7.11 +export PYTHONPATH=/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/
    7.12 +
    7.13 +# YML processing might complain about that. Make sure the locale exists (locale -a)
    7.14 +export LC_ALL=en_US.UTF-8
    7.15 +
    7.16 +# Search paths for includes used when doing YML processing
    7.17 +export YML_PATH=~/yml2/
     8.1 --- a/src/Makefile	Mon Jul 04 13:38:14 2016 +0200
     8.2 +++ b/src/Makefile	Sun Jul 10 13:57:27 2016 +0200
     8.3 @@ -59,8 +59,7 @@
     8.4  
     8.5  all: $(TARGET)
     8.6  
     8.7 -sync_fsm.c: ../sync/sync.fsm
     8.8 -	make -C ../sync
     8.9 +include Makefile.protocols
    8.10  
    8.11  %.d: %.c
    8.12  	@set -e; rm -f $@; \
     9.1 --- a/src/etpan_mime.c	Mon Jul 04 13:38:14 2016 +0200
     9.2 +++ b/src/etpan_mime.c	Sun Jul 10 13:57:27 2016 +0200
     9.3 @@ -136,7 +136,8 @@
     9.4      if (content->ct_parameters == NULL)
     9.5          if (parameters)
     9.6              clist_free(parameters);
     9.7 -
     9.8 +    if (param)
     9.9 +        mailmime_parameter_free(param);
    9.10  	return NULL;
    9.11  }
    9.12  
    10.1 --- a/src/keymanagement.c	Mon Jul 04 13:38:14 2016 +0200
    10.2 +++ b/src/keymanagement.c	Sun Jul 10 13:57:27 2016 +0200
    10.3 @@ -142,21 +142,23 @@
    10.4      
    10.5      assert(status != PEP_OUT_OF_MEMORY);
    10.6      if (status == PEP_OUT_OF_MEMORY)
    10.7 -        return PEP_OUT_OF_MEMORY;
    10.8 +        goto exit_free;
    10.9  
   10.10      if (stored_identity) {
   10.11          PEP_comm_type _comm_type_key;
   10.12          status = get_key_rating(session, stored_identity->fpr, &_comm_type_key);
   10.13          assert(status != PEP_OUT_OF_MEMORY);
   10.14          if (status == PEP_OUT_OF_MEMORY)
   10.15 -            return PEP_OUT_OF_MEMORY;
   10.16 +            goto exit_free;
   10.17  
   10.18          if (EMPTYSTR(identity->username)) {
   10.19              free(identity->username);
   10.20              identity->username = strdup(stored_identity->username);
   10.21              assert(identity->username);
   10.22 -            if (identity->username == NULL)
   10.23 -                return PEP_OUT_OF_MEMORY;
   10.24 +            if (identity->username == NULL){
   10.25 +                status = PEP_OUT_OF_MEMORY;
   10.26 +                goto exit_free;
   10.27 +            }
   10.28          }
   10.29  
   10.30          if (EMPTYSTR(identity->fpr)) {
   10.31 @@ -167,7 +169,7 @@
   10.32              if (_comm_type_key < PEP_ct_unconfirmed_encryption) {
   10.33                  PEP_STATUS status = elect_pubkey(session, identity);
   10.34                  if (status != PEP_STATUS_OK)
   10.35 -                    return status;
   10.36 +                    goto exit_free;
   10.37              }
   10.38              else {
   10.39                  identity->comm_type = stored_identity->comm_type;
   10.40 @@ -190,7 +192,7 @@
   10.41                  status = get_trust(session, identity);
   10.42                  assert(status != PEP_OUT_OF_MEMORY);
   10.43                  if (status == PEP_OUT_OF_MEMORY)
   10.44 -                    return PEP_OUT_OF_MEMORY;
   10.45 +                    goto exit_free;
   10.46                  if (identity->comm_type < stored_identity->comm_type)
   10.47                      identity->comm_type = PEP_ct_unknown;
   10.48              }
   10.49 @@ -209,14 +211,14 @@
   10.50              status = get_key_rating(session, identity->fpr, &_comm_type_key);
   10.51              assert(status != PEP_OUT_OF_MEMORY);
   10.52              if (status == PEP_OUT_OF_MEMORY)
   10.53 -                return PEP_OUT_OF_MEMORY;
   10.54 +                goto exit_free;
   10.55  
   10.56              identity->comm_type = _comm_type_key;
   10.57          }
   10.58          else /* EMPTYSTR(identity->fpr) */ {
   10.59              PEP_STATUS status = elect_pubkey(session, identity);
   10.60              if (status != PEP_STATUS_OK)
   10.61 -                return status;
   10.62 +                goto exit_free;
   10.63          }
   10.64      }
   10.65  
   10.66 @@ -228,8 +230,10 @@
   10.67          if (EMPTYSTR(identity->username)) { // mitigate
   10.68              free(identity->username);
   10.69              identity->username = strdup("anonymous");
   10.70 -            if (identity->username == NULL)
   10.71 -                return PEP_OUT_OF_MEMORY;
   10.72 +            if (identity->username == NULL){
   10.73 +                status = PEP_OUT_OF_MEMORY;
   10.74 +                goto exit_free;
   10.75 +            }
   10.76          }
   10.77  
   10.78          // Identity doesn't get stored if call was just about checking existing
   10.79 @@ -239,7 +243,7 @@
   10.80              status = set_identity(session, identity);
   10.81              assert(status == PEP_STATUS_OK);
   10.82              if (status != PEP_STATUS_OK) {
   10.83 -                return status;
   10.84 +                goto exit_free;
   10.85              }
   10.86          }
   10.87      }
   10.88 @@ -249,6 +253,12 @@
   10.89          if (session->examine_identity)
   10.90              session->examine_identity(identity, session->examine_management);
   10.91  
   10.92 +exit_free :
   10.93 +    
   10.94 +    if (stored_identity){
   10.95 +        free_identity(stored_identity);
   10.96 +    }
   10.97 +
   10.98      return status;
   10.99  }
  10.100  
    11.1 --- a/src/message_api.c	Mon Jul 04 13:38:14 2016 +0200
    11.2 +++ b/src/message_api.c	Sun Jul 10 13:57:27 2016 +0200
    11.3 @@ -64,7 +64,10 @@
    11.4  
    11.5          stringpair_list_t *field = stringpair_list_add(msg->opt_fields, pair);
    11.6          if (field == NULL)
    11.7 +        {
    11.8 +            free_stringpair(pair);
    11.9              return;
   11.10 +        }
   11.11  
   11.12          if (msg->opt_fields == NULL)
   11.13              msg->opt_fields = field;
    12.1 --- a/src/platform_unix.c	Mon Jul 04 13:38:14 2016 +0200
    12.2 +++ b/src/platform_unix.c	Sun Jul 10 13:57:27 2016 +0200
    12.3 @@ -65,7 +65,7 @@
    12.4          char *tw_env;
    12.5          if(tw_env = getenv("TRUSTWORDS")){
    12.6              char *p = stpncpy(buffer, tw_env, MAX_PATH);
    12.7 -            size_t len = MAX_PATH - (p - buffer) - 2;
    12.8 +            ssize_t len = MAX_PATH - (p - buffer) - 2;
    12.9  
   12.10              if (len < strlen(SYSTEM_DB_FILENAME)) {
   12.11                  assert(0);
   12.12 @@ -93,7 +93,7 @@
   12.13          char *home_env;
   12.14          if((home_env = getenv("HOME"))){
   12.15              char *p = stpncpy(buffer, home_env, MAX_PATH);
   12.16 -            size_t len = MAX_PATH - (p - buffer) - 2;
   12.17 +            ssize_t len = MAX_PATH - (p - buffer) - 2;
   12.18  
   12.19              if (len < strlen(LOCAL_DB_FILENAME)) {
   12.20                  assert(0);
   12.21 @@ -123,7 +123,7 @@
   12.22  
   12.23      if (!done) {
   12.24          char *p;
   12.25 -        size_t len;
   12.26 +        ssize_t len;
   12.27          char *gpg_home_env = getenv("GNUPGHOME");
   12.28          char *home_env = getenv("HOME");
   12.29  
   12.30 @@ -200,7 +200,7 @@
   12.31          char *p;
   12.32          p = stpncpy(agent_path, dirname, MAX_PATH);
   12.33          
   12.34 -        size_t len = MAX_PATH - (p - agent_path) - 2;
   12.35 +        ssize_t len = MAX_PATH - (p - agent_path) - 2;
   12.36  
   12.37          if (len < strlen(gpg_agent_conf_name))
   12.38          {
    13.1 --- a/src/stringlist.c	Mon Jul 04 13:38:14 2016 +0200
    13.2 +++ b/src/stringlist.c	Sun Jul 10 13:57:27 2016 +0200
    13.3 @@ -19,6 +19,7 @@
    13.4              free(result);
    13.5              return NULL;
    13.6          }
    13.7 +        result->next = NULL; // needed for one-element lists
    13.8      }
    13.9  
   13.10      return result;
   13.11 @@ -34,12 +35,13 @@
   13.12      if (dst == NULL)
   13.13          return NULL;
   13.14  
   13.15 -    if (src->next) {
   13.16 -        dst->next = stringlist_dup(src->next);
   13.17 -        if (dst->next == NULL) {
   13.18 -            free_stringlist(dst);
   13.19 -            return NULL;
   13.20 -        }
   13.21 +    stringlist_t* src_curr = src->next;
   13.22 +    stringlist_t** dst_curr_ptr = &dst->next;
   13.23 +    
   13.24 +    while (src_curr) {
   13.25 +        *dst_curr_ptr = new_stringlist(src_curr->value);
   13.26 +        src_curr = src_curr->next;
   13.27 +        dst_curr_ptr = &((*dst_curr_ptr)->next);
   13.28      }
   13.29  
   13.30      return dst;
   13.31 @@ -49,28 +51,35 @@
   13.32          stringlist_t *stringlist,
   13.33          const char *value
   13.34      )
   13.35 -{
   13.36 +{  
   13.37      assert(value);
   13.38  
   13.39      if (stringlist == NULL)
   13.40          return new_stringlist(value);
   13.41  
   13.42 -    if (stringlist->next != NULL)
   13.43 -        return stringlist_add(stringlist->next, value);
   13.44 -    if (stringlist->value == NULL) {
   13.45 -        stringlist->value = strdup(value);
   13.46 -        assert(stringlist->value);
   13.47 -        if (stringlist->value == NULL)
   13.48 +    stringlist_t* list_curr = stringlist;
   13.49 +    
   13.50 +    while (list_curr->next)
   13.51 +        list_curr = list_curr->next;
   13.52 + 
   13.53 +    // if list end exists without value,
   13.54 +    // we fill it in here instead of adding
   13.55 +    // a new node.
   13.56 +    if (list_curr->value == NULL) {
   13.57 +        list_curr->value = strdup(value);
   13.58 +        assert(list_curr->value);
   13.59 +        if (list_curr->value == NULL)
   13.60              return NULL;
   13.61 -        return stringlist;
   13.62 +        return list_curr;
   13.63      }
   13.64 +    
   13.65 +    list_curr->next = new_stringlist(value);
   13.66  
   13.67 -    stringlist->next = new_stringlist(value);
   13.68 -    assert(stringlist->next);
   13.69 -    if (stringlist->next == NULL)
   13.70 +    assert(list_curr->next);
   13.71 +    if (list_curr->next == NULL)
   13.72          return NULL;
   13.73  
   13.74 -    return stringlist->next;
   13.75 +    return list_curr->next;
   13.76  }
   13.77  
   13.78  DYNAMIC_API stringlist_t *stringlist_append(
   13.79 @@ -79,6 +88,8 @@
   13.80      )
   13.81  {
   13.82      assert(stringlist);
   13.83 +    if (stringlist == NULL)
   13.84 +        return NULL;
   13.85  
   13.86      if (second == NULL || second->value == NULL)
   13.87          return stringlist;
   13.88 @@ -139,10 +150,16 @@
   13.89  
   13.90  DYNAMIC_API void free_stringlist(stringlist_t *stringlist)
   13.91  {
   13.92 -    if (stringlist) {
   13.93 -        free_stringlist(stringlist->next);
   13.94 -        free(stringlist->value);
   13.95 -        free(stringlist);
   13.96 +    stringlist_t *curr;
   13.97 +    stringlist_t *next;
   13.98 +    
   13.99 +    curr = stringlist;
  13.100 +    
  13.101 +    while (curr) {
  13.102 +        next = curr->next;
  13.103 +        free(curr->value);
  13.104 +        free(curr);
  13.105 +        curr = next;
  13.106      }
  13.107  }
  13.108  
    14.1 --- a/src/stringlist.h	Mon Jul 04 13:38:14 2016 +0200
    14.2 +++ b/src/stringlist.h	Sun Jul 10 13:57:27 2016 +0200
    14.3 @@ -24,6 +24,7 @@
    14.4  //  caveat:
    14.5  //      the value is being copied before being added to the list
    14.6  //      the original string is still being owned by the caller
    14.7 +//      the "next" pointer of the returned object is explicitly set to NULL
    14.8  
    14.9  DYNAMIC_API stringlist_t *new_stringlist(const char *value);
   14.10  
   14.11 @@ -66,6 +67,7 @@
   14.12  //
   14.13  //  return value:
   14.14  //      pointer to last element in stringlist or NULL if out of memory
   14.15 +//      or stringpair_list is NULL
   14.16  //
   14.17  //  caveat:
   14.18  //      all values are being copied before being added to the list
    15.1 --- a/src/stringpair.c	Mon Jul 04 13:38:14 2016 +0200
    15.2 +++ b/src/stringpair.c	Sun Jul 10 13:57:27 2016 +0200
    15.3 @@ -58,6 +58,8 @@
    15.4      if (result && value)
    15.5          result->value = value;
    15.6  
    15.7 +    result->next = NULL;
    15.8 +    
    15.9      return result;
   15.10  }
   15.11  
   15.12 @@ -69,19 +71,24 @@
   15.13      if (src == NULL)
   15.14          return NULL;
   15.15  
   15.16 -    stringpair_list_t *dst = new_stringpair_list(src->value);
   15.17 +    stringpair_t* copy_pair = stringpair_dup(src->value);
   15.18 +    
   15.19 +    stringpair_list_t *dst = new_stringpair_list(copy_pair);
   15.20      if (dst == NULL)
   15.21          return NULL;
   15.22  
   15.23 -    if (src->next) {
   15.24 -        dst->next = stringpair_list_dup(src->next);
   15.25 -        if (dst->next == NULL) {
   15.26 -            free_stringpair_list(dst);
   15.27 -            return NULL;
   15.28 -        }
   15.29 +    stringpair_list_t* src_curr = src->next;
   15.30 +    stringpair_list_t** dst_curr_ptr = &dst->next;
   15.31 +
   15.32 +    while (src_curr) {
   15.33 +        copy_pair = stringpair_dup(src_curr->value);
   15.34 +        *dst_curr_ptr = new_stringpair_list(copy_pair);
   15.35 +        src_curr = src_curr->next;
   15.36 +        dst_curr_ptr = &((*dst_curr_ptr)->next);
   15.37      }
   15.38  
   15.39      return dst;
   15.40 +    
   15.41  }
   15.42  
   15.43  DYNAMIC_API stringpair_list_t *stringpair_list_add(
   15.44 @@ -94,20 +101,30 @@
   15.45      if (stringpair_list == NULL)
   15.46          return new_stringpair_list(value);
   15.47  
   15.48 -    if (stringpair_list->next)
   15.49 -        return stringpair_list_add(stringpair_list->next, value);
   15.50 +    stringpair_list_t* list_curr = stringpair_list;
   15.51 +    
   15.52 +    while (list_curr->next)
   15.53 +        list_curr = list_curr->next;
   15.54 + 
   15.55 +    // if list end exists without value,
   15.56 +    // we fill it in here instead of adding
   15.57 +    // a new node.
   15.58 +    if (list_curr->value == NULL) {
   15.59 +        list_curr->value = value; // ownership goes to us
   15.60 +        assert(list_curr->value);
   15.61 +        if (list_curr->value == NULL)
   15.62 +            return NULL;
   15.63 +        return list_curr;
   15.64 +    }
   15.65 +    
   15.66 +    list_curr->next = new_stringpair_list(value);
   15.67  
   15.68 -    if (stringpair_list->value == NULL) {
   15.69 -        assert(stringpair_list->next == NULL);
   15.70 -        stringpair_list->value = value;
   15.71 -        return stringpair_list;
   15.72 -    }
   15.73 -
   15.74 -    stringpair_list->next = new_stringpair_list(value);
   15.75 -    if (stringpair_list->next == NULL)
   15.76 +    assert(list_curr->next);
   15.77 +    if (list_curr->next == NULL)
   15.78          return NULL;
   15.79  
   15.80 -    return stringpair_list->next;
   15.81 +    return list_curr->next;
   15.82 +    
   15.83  }
   15.84  
   15.85  DYNAMIC_API stringpair_list_t *stringpair_list_append(
   15.86 @@ -116,6 +133,8 @@
   15.87      )
   15.88  {
   15.89      assert(stringpair_list);
   15.90 +    if (stringpair_list == NULL)
   15.91 +        return NULL;
   15.92  
   15.93      if (second == NULL || second->value == NULL)
   15.94          return stringpair_list;
   15.95 @@ -123,9 +142,14 @@
   15.96      stringpair_list_t *_s = stringpair_list;
   15.97      stringpair_list_t *_s2;
   15.98      for (_s2 = second; _s2 != NULL; _s2 = _s2->next) {
   15.99 -        _s = stringpair_list_add(_s, _s2->value);
  15.100 -        if (_s == NULL)
  15.101 +        stringpair_t *_sp = stringpair_dup(_s2->value);
  15.102 +        if (_sp == NULL)
  15.103              return NULL;
  15.104 +        _s = stringpair_list_add(_s, _sp);
  15.105 +        if (_s == NULL){
  15.106 +            free_stringpair(_sp);
  15.107 +            return NULL;
  15.108 +        }
  15.109      }
  15.110      return _s;
  15.111  }
    16.1 --- a/src/stringpair.h	Mon Jul 04 13:38:14 2016 +0200
    16.2 +++ b/src/stringpair.h	Sun Jul 10 13:57:27 2016 +0200
    16.3 @@ -63,17 +63,19 @@
    16.4  //
    16.5  //  caveat:
    16.6  //      the ownership of the value goes to the stringpair_list
    16.7 +//      next pointer explicitly set to NULL
    16.8  
    16.9  DYNAMIC_API stringpair_list_t *new_stringpair_list(stringpair_t *value);
   16.10  
   16.11  
   16.12 -// stringpair_list_dup() - duplicate a stringpair_list
   16.13 +// stringpair_list_dup() - duplicate a stringpair_list (deep copy)
   16.14  //
   16.15  //  parameters:
   16.16  //      src (in)                stringpair_list to copy
   16.17  //
   16.18  //  return value:
   16.19  //      pointer to stringpair_list_t object or NULL if out of memory
   16.20 +//      stringpair value copies created by this function belong to the returned list
   16.21  
   16.22  DYNAMIC_API stringpair_list_t *stringpair_list_dup(
   16.23          const stringpair_list_t *src
   16.24 @@ -107,6 +109,7 @@
   16.25  //
   16.26  //  return value:
   16.27  //      pointer to last element in stringpair_list or NULL if out of memory
   16.28 +//      or stringpair_list is NULL
   16.29  //
   16.30  //  caveat:
   16.31  //      all values are being copied before being added to the list
    17.1 --- a/src/sync_actions.c	Mon Jul 04 13:38:14 2016 +0200
    17.2 +++ b/src/sync_actions.c	Sun Jul 10 13:57:27 2016 +0200
    17.3 @@ -108,7 +108,7 @@
    17.4  //  params:
    17.5  //      session (in)        session handle
    17.6  //      state (in)          state the state machine is in
    17.7 -//      partner (in)        partner in sync
    17.8 +//      partner (in)        partner to communicate with
    17.9  //
   17.10  //  returns:
   17.11  //      PEP_STATUS_OK or any other value on error
   17.12 @@ -202,7 +202,7 @@
   17.13  //  params:
   17.14  //      session (in)        session handle
   17.15  //      state (in)          state the state machine is in
   17.16 -//      partner (in)        partner in sync
   17.17 +//      partner (in)        partner to communicate with
   17.18  //
   17.19  //  returns:
   17.20  //      PEP_STATUS_OK or any other value on error
   17.21 @@ -238,7 +238,7 @@
   17.22  //  params:
   17.23  //      session (in)        session handle
   17.24  //      state (in)          state the state machine is in
   17.25 -//      partner (in)        partner in sync
   17.26 +//      partner (in)        partner to communicate with
   17.27  //
   17.28  //  returns:
   17.29  //      PEP_STATUS_OK or any other value on error
   17.30 @@ -274,7 +274,7 @@
   17.31  //  params:
   17.32  //      session (in)        session handle
   17.33  //      state (in)          state the state machine is in
   17.34 -//      partner (in)        partner in sync
   17.35 +//      partner (in)        partner to communicate with
   17.36  //
   17.37  //  returns:
   17.38  //      PEP_STATUS_OK or any other value on error
   17.39 @@ -395,3 +395,4 @@
   17.40      return status;
   17.41  }
   17.42  
   17.43 +
    18.1 --- a/src/sync_fsm.c	Mon Jul 04 13:38:14 2016 +0200
    18.2 +++ b/src/sync_fsm.c	Sun Jul 10 13:57:27 2016 +0200
    18.3 @@ -98,3 +98,4 @@
    18.4  
    18.5      return state;
    18.6  }
    18.7 +
    19.1 --- a/sync/Makefile	Mon Jul 04 13:38:14 2016 +0200
    19.2 +++ b/sync/Makefile	Sun Jul 10 13:57:27 2016 +0200
    19.3 @@ -1,16 +1,16 @@
    19.4  include ../Makefile.conf
    19.5  
    19.6 -all: ../src/sync_fsm.c
    19.7 +all: .statemachines
    19.8  
    19.9 -skeleton: ../src/sync_actions.c.skeleton
   19.10 +skeleton: .skeletons
   19.11  
   19.12 -../src/sync_actions.c.skeleton: sync.fsm gen_actions_skeleton.ysl2 fsm.yml2 functions.ysl2
   19.13 +.skeletons: devicegroup.fsm gen_actions_skeleton.ysl2 fsm.yml2 functions.ysl2
   19.14  	$(YML2PROC) -y gen_actions_skeleton.ysl2 $< -o $@
   19.15  
   19.16 -../src/sync_fsm.c: sync.fsm gen_statemachine.ysl2 fsm.yml2 functions.ysl2
   19.17 +.statemachines: devicegroup.fsm gen_statemachine.ysl2 fsm.yml2 functions.ysl2
   19.18  	$(YML2PROC) -y gen_statemachine.ysl2 $< -o $@
   19.19  
   19.20  .PHONY: clean
   19.21  
   19.22  clean:
   19.23 -	rm -f *.xml *.xsl ../src/sync_fsm.* ../src/*.skeleton
   19.24 +	rm -f *.xml *.xsl ../src/sync_fsm.* ../src/*.skeleton .statemachines .skeletons
    20.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    20.2 +++ b/sync/devicegroup.fsm	Sun Jul 10 13:57:27 2016 +0200
    20.3 @@ -0,0 +1,87 @@
    20.4 +// DeviceGroup protocol for p≡p
    20.5 +
    20.6 +// Copyleft (c) 2016, p≡p foundation
    20.7 +
    20.8 +// Written by Volker Birk
    20.9 +
   20.10 +include ./fsm.yml2
   20.11 +
   20.12 +protocol DeviceGroup {
   20.13 +    // all messages have a timestamp, time out and are removed after timeout
   20.14 +
   20.15 +    fsm DeviceState filename=sync {
   20.16 +        state InitState {
   20.17 +            on Init {
   20.18 +                if (storedGroupKeys)
   20.19 +                    go Grouped;
   20.20 +                go Sole;
   20.21 +            }
   20.22 +        }
   20.23 +
   20.24 +        state Sole {
   20.25 +            on KeyGen
   20.26 +                do sendBeacon;
   20.27 +            on CannotDecrypt
   20.28 +                do sendBeacon;  // cry, baby
   20.29 +            on Beacon(Identity partner) // this event will not happen for already
   20.30 +                                        // rejected partners
   20.31 +                do sendHandshakeRequest(partner);
   20.32 +            on HandshakeRequest(Identity partner) {
   20.33 +                do sendHandshakeRequest(partner);
   20.34 +                go HandshakingSole(partner);
   20.35 +            }
   20.36 +        }
   20.37 +
   20.38 +        state HandshakingSole(Identity partner) {
   20.39 +            on Init
   20.40 +                do showHandshake(partner);
   20.41 +            on HandshakeRejected(Identity partner) {
   20.42 +                do reject(partner);             // sends Reject to partner and
   20.43 +                                                // stores rejection of partner
   20.44 +                go Sole;
   20.45 +            }
   20.46 +            on HandshakeAccepted(Identity partner) {
   20.47 +                if keyElectionWon(partner) {    // an already existing group
   20.48 +                                                // always wins
   20.49 +                    ownGroupKeys;
   20.50 +                    sendGroupKeys(partner);
   20.51 +                    go Grouped;
   20.52 +                }
   20.53 +                go WaitForGroupKeys(Identity partner);
   20.54 +            }
   20.55 +        }
   20.56 +    
   20.57 +        state WaitForGroupKeys(Identity partner) {
   20.58 +            on GroupKeys(Identity partner, Stringlist keys) {
   20.59 +                do storeGroupKeys(partner, keys);
   20.60 +                go Grouped;
   20.61 +            }
   20.62 +            on Cancel go Sole;
   20.63 +            on Reject(Identity partner) {
   20.64 +                do reject(partner);
   20.65 +                go Sole;
   20.66 +            }
   20.67 +        }
   20.68 +
   20.69 +        state Grouped {
   20.70 +            on KeyGen
   20.71 +                do sendGroupKeys; // always send all keys
   20.72 +            on HandshakeRequest(Identity partner) {
   20.73 +                do sendHandshakeRequest(partner);
   20.74 +                do showHandshake(partner);
   20.75 +            }
   20.76 +            on HandshakeRejected(Identity partner)
   20.77 +                do reject(partner);
   20.78 +            on HandshakeAccepted(Identity partner)
   20.79 +                do sendGroupKeys(partner);
   20.80 +            on Reject(Identity partner)
   20.81 +                do reject partner;
   20.82 +        }
   20.83 +
   20.84 +        tag InitState 0;
   20.85 +        tag Beacon 1;
   20.86 +        tag HandshakeRequest 2;
   20.87 +        tag GroupKeys 3;
   20.88 +    }
   20.89 +}
   20.90 +
    21.1 --- a/sync/gen_actions_skeleton.ysl2	Mon Jul 04 13:38:14 2016 +0200
    21.2 +++ b/sync/gen_actions_skeleton.ysl2	Sun Jul 10 13:57:27 2016 +0200
    21.3 @@ -9,35 +9,42 @@
    21.4  tstylesheet {
    21.5      include ./functions.ysl2
    21.6  
    21.7 -    template "/protocol/fsm" {
    21.8 -    ||
    21.9 -    `` const "name", "@name"
   21.10 -    // Actions for «@name» state machine
   21.11 +    template "/protocol/fsm" document "../src/{@filename}_actions.c.skeleton", "text" {
   21.12 +        const "name", "@name";
   21.13 +        const "filename", "@filename";
   21.14 +        ||
   21.15 +        // Actions for «@name» state machine
   21.16  
   21.17 -    #include <assert.h>
   21.18 -    #include "pEp_internal.h"
   21.19 -    #include "keymanagement.h"
   21.20 -    #include "message.h"
   21.21 -    #include "sync_fsm.h"
   21.22 -    #include "baseprotocol.h"
   21.23 -    #include "map_asn1.h"
   21.24 -    `` for "func:distinctName(//action)" if "substring(@name, 1, 4) = 'send'" | #include "../asn.1/«substring(@name, 5, 255)».h"
   21.25 -
   21.26 -    `` for "func:distinctName(//action)" call "action" with "action", ".", with "fsm", "$name";
   21.27 -
   21.28 -    ||
   21.29 +        #include <assert.h>
   21.30 +        #include "pEp_internal.h"
   21.31 +        #include "keymanagement.h"
   21.32 +        #include "message.h"
   21.33 +        #include "«@filename»_fsm.h"
   21.34 +        #include "baseprotocol.h"
   21.35 +        #include "map_asn1.h"
   21.36 +        ||
   21.37 +        for "func:distinctName(//action)"
   21.38 +            if "substring(@name, 1, 4) = 'send'"
   21.39 +                | #include "../asn.1/«substring(@name, 5, 255)».h"
   21.40 +        |
   21.41 +        for "func:distinctName(//action)"
   21.42 +            call "action"
   21.43 +                with "action", ".",
   21.44 +                with "fsm", "$name",
   21.45 +                with "filename", "$filename";
   21.46      }
   21.47  
   21.48      function "action" {
   21.49          param "action";
   21.50          param "fsm";
   21.51 +        param "filename", "'###'";
   21.52          choose {
   21.53              when "substring($action/@name, 1, 4) = 'send'"
   21.54                  call "send_action" with "action", "$action",
   21.55 -                     with "fsm", "$fsm";
   21.56 +                     with "fsm", "$fsm", with "filename", "$filename";
   21.57              otherwise
   21.58                  call "other_action" with "action", "$action",
   21.59 -                     with "fsm", "$fsm";
   21.60 +                     with "fsm", "$fsm", with "filename", "$filename";
   21.61          }
   21.62      }
   21.63  
   21.64 @@ -63,6 +70,7 @@
   21.65      function "other_action" {
   21.66          param "action";
   21.67          param "fsm";
   21.68 +        param "filename", "'###'";
   21.69  
   21.70          ||
   21.71  
   21.72 @@ -71,7 +79,7 @@
   21.73          //  params:
   21.74          //      session (in)        session handle
   21.75          //      state (in)          state the state machine is in
   21.76 -        `` if "parm"        | //      partner (in)        partner in sync
   21.77 +        `` if "parm"        | //      partner (in)        partner to communicate with
   21.78          `` if "not(parm)"   | //      partner (in)        (must be NULL)
   21.79          //
   21.80          //  returns:
   21.81 @@ -105,6 +113,7 @@
   21.82      function "send_action" {
   21.83          param "action";
   21.84          param "fsm";
   21.85 +        param "filename", "'###'";
   21.86          const "name", "substring($action/@name, 5, 255)";
   21.87  
   21.88          ||
   21.89 @@ -114,7 +123,7 @@
   21.90          //  params:
   21.91          //      session (in)        session handle
   21.92          //      state (in)          state the state machine is in
   21.93 -        `` if "parm"        | //      partner (in)        partner in sync
   21.94 +        `` if "parm"        | //      partner (in)        partner to communicate with
   21.95          `` if "not(parm)"   | //      partner (in)        (must be NULL)
   21.96          //
   21.97          //  returns:
   21.98 @@ -159,15 +168,15 @@
   21.99                  goto error;
  21.100              if (Identity_from_Struct(me, &msg->me) == NULL)
  21.101                  goto enomem;
  21.102 -         `` if "parm or $name='OwnKeys'" |
  21.103 -         `` if "parm/partner"   |> if (Identity_from_Struct(partner, &msg->partner) == NULL)
  21.104 -         `` if "parm/partner"   |>> goto enomem;
  21.105 -         `` if "$name='OwnKeys'"|> stringlist_t *sl;
  21.106 -         `` if "$name='OwnKeys'"|> status = own_key_retrieve(session, &sl);
  21.107 -         `` if "$name='OwnKeys'"|> if (status != PEP_STATUS_OK)
  21.108 -         `` if "$name='OwnKeys'"|>> goto error;
  21.109 -         `` if "$name='OwnKeys'"|> if (KeyList_from_stringlist(sl, &msg->keylist) == NULL)
  21.110 -         `` if "$name='OwnKeys'"|>> goto enomem;
  21.111 +            if "parm or $name='OwnKeys'" |
  21.112 +            if "parm/partner"   |> if (Identity_from_Struct(partner, &msg->partner) == NULL)
  21.113 +            if "parm/partner"   |>> goto enomem;
  21.114 +            if "$name='OwnKeys'"|> stringlist_t *sl;
  21.115 +            if "$name='OwnKeys'"|> status = own_key_retrieve(session, &sl);
  21.116 +            if "$name='OwnKeys'"|> if (status != PEP_STATUS_OK)
  21.117 +            if "$name='OwnKeys'"|>> goto error;
  21.118 +            if "$name='OwnKeys'"|> if (KeyList_from_stringlist(sl, &msg->keylist) == NULL)
  21.119 +            if "$name='OwnKeys'"|>> goto enomem;
  21.120  
  21.121              if (asn_check_constraints(&asn_DEF_«$name», msg, NULL, NULL)) {
  21.122                  status = PEP_CONTRAINTS_VIOLATED;
  21.123 @@ -189,7 +198,7 @@
  21.124              free_identity(me);
  21.125              me = NULL;
  21.126  
  21.127 -            status = session->messageToSend(session->sync_obj, _message);
  21.128 +            status = session->messageToSend(session->«$filename»_obj, _message);
  21.129  
  21.130              free_message(_message);
  21.131              ASN_STRUCT_FREE(asn_DEF_«$name», msg);
    22.1 --- a/sync/gen_statemachine.ysl2	Mon Jul 04 13:38:14 2016 +0200
    22.2 +++ b/sync/gen_statemachine.ysl2	Sun Jul 10 13:57:27 2016 +0200
    22.3 @@ -9,8 +9,20 @@
    22.4  tstylesheet {
    22.5      include ./functions.ysl2
    22.6  
    22.7 -    template "/protocol/fsm" {
    22.8 -        document "../src/sync_fsm.h", "text" {
    22.9 +    template "/protocol" {
   22.10 +        document "../src/Makefile.protocols", "text"
   22.11 +            apply "fsm", 0, mode="make";
   22.12 +        apply "fsm", 0, mode=gen;
   22.13 +    }
   22.14 +
   22.15 +    template "fsm", mode=make
   22.16 +    ||
   22.17 +    «@filename»_fsm.c: ../sync/devicegroup.fsm
   22.18 +    \tmake -C ../«@filename»
   22.19 +    ||
   22.20 +
   22.21 +    template "fsm", mode=gen {
   22.22 +        document "../src/{@filename}_fsm.h", "text" {
   22.23          ||
   22.24          #pragma once
   22.25  
   22.26 @@ -85,7 +97,7 @@
   22.27  
   22.28          ||
   22.29          }
   22.30 -        document "../src/sync_driver.c", "text"
   22.31 +        document "../src/{@filename}_driver.c", "text"
   22.32          ||
   22.33          // Driver for «@name» state machine
   22.34  
   22.35 @@ -102,15 +114,16 @@
   22.36          {
   22.37              PEP_STATUS status = PEP_STATUS_OK;
   22.38  
   22.39 -            session->sync_state = fsm_«@name»(session, session->sync_state,
   22.40 +            session->«@filename»_state = fsm_«@name»(session, session->«@filename»_state,
   22.41                      event, partner, state_partner);
   22.42  
   22.43              return status;
   22.44          }
   22.45  
   22.46          ||
   22.47 +        document "../src/{@filename}_fsm.c", "text"
   22.48          ||
   22.49 -        #include "sync_fsm.h"
   22.50 +        #include "«@filename»_fsm.h"
   22.51  
   22.52          // state machine for «@name»
   22.53  
    23.1 --- a/sync/sync.fsm	Mon Jul 04 13:38:14 2016 +0200
    23.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    23.3 @@ -1,87 +0,0 @@
    23.4 -// DeviceGroup protocol for p≡p
    23.5 -
    23.6 -// Copyleft (c) 2016, p≡p foundation
    23.7 -
    23.8 -// Written by Volker Birk
    23.9 -
   23.10 -include ./fsm.yml2
   23.11 -
   23.12 -protocol DeviceGroup {
   23.13 -    // all messages have a timestamp, time out and are removed after timeout
   23.14 -
   23.15 -    fsm DeviceState {
   23.16 -        state InitState {
   23.17 -            on Init {
   23.18 -                if (storedGroupKeys)
   23.19 -                    go Grouped;
   23.20 -                go Sole;
   23.21 -            }
   23.22 -        }
   23.23 -
   23.24 -        state Sole {
   23.25 -            on KeyGen
   23.26 -                do sendBeacon;
   23.27 -            on CannotDecrypt
   23.28 -                do sendBeacon;  // cry, baby
   23.29 -            on Beacon(Identity partner) // this event will not happen for already
   23.30 -                                        // rejected partners
   23.31 -                do sendHandshakeRequest(partner);
   23.32 -            on HandshakeRequest(Identity partner) {
   23.33 -                do sendHandshakeRequest(partner);
   23.34 -                go HandshakingSole(partner);
   23.35 -            }
   23.36 -        }
   23.37 -
   23.38 -        state HandshakingSole(Identity partner) {
   23.39 -            on Init
   23.40 -                do showHandshake(partner);
   23.41 -            on HandshakeRejected(Identity partner) {
   23.42 -                do reject(partner);             // sends Reject to partner and
   23.43 -                                                // stores rejection of partner
   23.44 -                go Sole;
   23.45 -            }
   23.46 -            on HandshakeAccepted(Identity partner) {
   23.47 -                if keyElectionWon(partner) {    // an already existing group
   23.48 -                                                // always wins
   23.49 -                    ownGroupKeys;
   23.50 -                    sendGroupKeys(partner);
   23.51 -                    go Grouped;
   23.52 -                }
   23.53 -                go WaitForGroupKeys(Identity partner);
   23.54 -            }
   23.55 -        }
   23.56 -    
   23.57 -        state WaitForGroupKeys(Identity partner) {
   23.58 -            on GroupKeys(Identity partner, Stringlist keys) {
   23.59 -                do storeGroupKeys(partner, keys);
   23.60 -                go Grouped;
   23.61 -            }
   23.62 -            on Cancel go Sole;
   23.63 -            on Reject(Identity partner) {
   23.64 -                do reject(partner);
   23.65 -                go Sole;
   23.66 -            }
   23.67 -        }
   23.68 -
   23.69 -        state Grouped {
   23.70 -            on KeyGen
   23.71 -                do sendGroupKeys; // always send all keys
   23.72 -            on HandshakeRequest(Identity partner) {
   23.73 -                do sendHandshakeRequest(partner);
   23.74 -                do showHandshake(partner);
   23.75 -            }
   23.76 -            on HandshakeRejected(Identity partner)
   23.77 -                do reject(partner);
   23.78 -            on HandshakeAccepted(Identity partner)
   23.79 -                do sendGroupKeys(partner);
   23.80 -            on Reject(Identity partner)
   23.81 -                do reject partner;
   23.82 -        }
   23.83 -
   23.84 -        tag InitState 0;
   23.85 -        tag Beacon 1;
   23.86 -        tag HandshakeRequest 2;
   23.87 -        tag GroupKeys 3;
   23.88 -    }
   23.89 -}
   23.90 -
    24.1 --- a/test/message_api_test.cc	Mon Jul 04 13:38:14 2016 +0200
    24.2 +++ b/test/message_api_test.cc	Sun Jul 10 13:57:27 2016 +0200
    24.3 @@ -23,10 +23,10 @@
    24.4      // message_api test code
    24.5  
    24.6      cout << "creating message…\n";
    24.7 -    pEp_identity * me2 = new_identity("outlooktest@dingens.org", NULL, PEP_OWN_USERID, "Outlook Test");
    24.8 +    pEp_identity * me2 = new_identity("pep.test.alice@pep-project.org", NULL, PEP_OWN_USERID, "Alice Test");
    24.9      // pEp_identity * me2 = new_identity("test@nokey.plop", NULL, PEP_OWN_USERID, "Test no key");
   24.10      me2->me = true;
   24.11 -    identity_list *to2 = new_identity_list(new_identity("vb@dingens.org", NULL, "42", "Volker Birk"));
   24.12 +    identity_list *to2 = new_identity_list(new_identity("pep.test.bob@pep-project.org", NULL, "42", "Bob Test"));
   24.13      // identity_list *to2 = new_identity_list(new_identity("still@nokey.blup", NULL, "42", "Still no key"));
   24.14      message *msg2 = new_message(PEP_dir_outgoing);
   24.15      assert(msg2);
   24.16 @@ -84,7 +84,7 @@
   24.17      assert(keylist4);
   24.18      assert(color);
   24.19      PEP_comm_type ct = enc_msg2->from->comm_type;
   24.20 -    assert(ct == PEP_ct_pEp || ct == PEP_ct_pEp_unconfirmed);
   24.21 +    assert(ct == PEP_ct_pEp || ct == PEP_ct_pEp_unconfirmed || ct == PEP_ct_OpenPGP || ct == PEP_ct_OpenPGP_unconfirmed );
   24.22  
   24.23      free_stringpair_list(enc_msg2->opt_fields);
   24.24      enc_msg2->opt_fields = NULL;
    25.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    25.2 +++ b/test/stringlist_test.cc	Sun Jul 10 13:57:27 2016 +0200
    25.3 @@ -0,0 +1,137 @@
    25.4 +#include <stdlib.h>
    25.5 +#include <string.h>
    25.6 +#include "platform.h"
    25.7 +#include <iostream>
    25.8 +#include <fstream>
    25.9 +#include <assert.h>
   25.10 +
   25.11 +#include "stringlist.h"
   25.12 +
   25.13 +using namespace std;
   25.14 +
   25.15 +int main() {
   25.16 +    cout << "\n*** data structures: stringlist_test ***\n\n";
   25.17 +
   25.18 +    const char* str0 = "I am your father, Luke\n";
   25.19 +    
   25.20 +    // new_stringlist test code
   25.21 +    cout << "creating one-element stringlist…\n";
   25.22 +    
   25.23 +    stringlist_t* src = new_stringlist(str0);
   25.24 +    assert(src);
   25.25 +    assert(strcmp(src->value,str0) == 0);
   25.26 +    cout << "Value: " << src->value;
   25.27 +    assert(src->next == NULL);
   25.28 +    cout << "one-element stringlist created, next element is NULL\n";
   25.29 +    
   25.30 +    cout << "freeing stringlist…\n\n";
   25.31 +    free_stringlist(src);
   25.32 +    src = NULL;
   25.33 +    
   25.34 +    // test stringlist_add with four-element list
   25.35 +    cout << "creating four-element stringlist…\n";
   25.36 +    const char* str1 = "String 1";
   25.37 +    const char* str2 = "\tString 2";
   25.38 +    const char* str3 = "\tString 3";
   25.39 +    const char* str4 = "\tString 4\n";
   25.40 +    const char* strarr[4] = {str1, str2, str3, str4};
   25.41 +    cout << "stringlist_add on empty list…\n";
   25.42 +    src = stringlist_add(src, str1); // src is NULL
   25.43 +    assert(src);
   25.44 +    assert(stringlist_add(src, str2)); // returns ptr to new elt
   25.45 +    assert(stringlist_add(src, str3));
   25.46 +    assert(stringlist_add(src, str4));
   25.47 +    
   25.48 +    cout << "checking contents\n";
   25.49 +    stringlist_t* p = src;
   25.50 +    int i = 0;
   25.51 +    while (p) {
   25.52 +        assert(p->value);
   25.53 +        assert(strcmp(p->value, strarr[i++]) == 0);
   25.54 +        assert(p->value != *(strarr + i)); // ensure this is a copy
   25.55 +        cout << p->value;
   25.56 +        p = p->next;
   25.57 +    }
   25.58 +    assert(p == NULL); // list ends properly
   25.59 +    
   25.60 +    cout << "\nduplicating four-element stringlist…\n";
   25.61 +    stringlist_t* dst = stringlist_dup(src);
   25.62 +    assert(dst);
   25.63 +    
   25.64 +    stringlist_t* p_dst = dst;
   25.65 +    p = src;
   25.66 +
   25.67 +    cout << "checking contents\n";    
   25.68 +    while (p_dst) {
   25.69 +        assert(p_dst->value);
   25.70 +        assert(strcmp(p->value, p_dst->value) == 0);
   25.71 +        assert(p->value != p_dst->value); // ensure this is a copy
   25.72 +        cout << p_dst->value;
   25.73 +        p = p->next;
   25.74 +        p_dst = p_dst->next;
   25.75 +        assert((p == NULL) == (p_dst == NULL));
   25.76 +    }
   25.77 +    assert(p_dst == NULL);
   25.78 +    
   25.79 +    cout << "\nAdd to 4-element stringlist with tail with no value…\n";
   25.80 +    // get tail
   25.81 +    p = src;
   25.82 +    while (p->next)
   25.83 +        p = p->next;
   25.84 +    
   25.85 +    if (p->value)
   25.86 +        free(p->value);
   25.87 +    p->value = NULL;
   25.88 +    
   25.89 +    strarr[3] = str0;
   25.90 +    stringlist_add(src, str0);
   25.91 +    
   25.92 +    cout << "checking contents\n";
   25.93 +    p = src;
   25.94 +    i = 0;
   25.95 +    while (p) {
   25.96 +        assert(p->value);
   25.97 +        assert(strcmp(p->value, strarr[i++]) == 0);
   25.98 +        assert(p->value != *(strarr + i)); // ensure this is a copy
   25.99 +        cout << p->value;
  25.100 +        p = p->next;
  25.101 +    }
  25.102 +    assert(p == NULL); // list ends properly
  25.103 +    
  25.104 +    cout << "freeing stringlists…\n\n";
  25.105 +    free_stringlist(src);
  25.106 +    free_stringlist(dst);
  25.107 +    src = NULL;
  25.108 +    dst = NULL;
  25.109 +
  25.110 +    cout << "duplicating one-element stringlist…\n";    
  25.111 +    src = new_stringlist(str0);
  25.112 +    assert(src);
  25.113 +    dst = stringlist_dup(src);
  25.114 +    assert(strcmp(dst->value, str0) == 0);
  25.115 +    cout << "Value: " << src->value;
  25.116 +    assert(dst->next == NULL);
  25.117 +    cout << "one-element stringlist duped, next element is NULL\n";
  25.118 +    
  25.119 +    cout << "\nAdd to one-element stringlist with no value…\n";
  25.120 +    if (src->value)
  25.121 +        free(src->value);
  25.122 +    src->value = NULL;
  25.123 +    stringlist_add(src, str2);
  25.124 +    assert(src->value);
  25.125 +    assert(strcmp(src->value, str2) == 0);
  25.126 +    assert(src->value != str2); // ensure this is a copy
  25.127 +    cout << src->value;
  25.128 +
  25.129 +    cout << "\nfreeing stringlists…\n\n";
  25.130 +    free_stringlist(src);
  25.131 +    free_stringlist(dst);
  25.132 +    
  25.133 +    src = NULL;
  25.134 +    dst = NULL;
  25.135 +    
  25.136 +    cout << "done.\n";
  25.137 +
  25.138 +    return 0;
  25.139 +}
  25.140 +
    26.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    26.2 +++ b/test/stringpair_list_test.cc	Sun Jul 10 13:57:27 2016 +0200
    26.3 @@ -0,0 +1,138 @@
    26.4 +#include <stdlib.h>
    26.5 +#include <string.h>
    26.6 +#include "platform.h"
    26.7 +#include <iostream>
    26.8 +#include <fstream>
    26.9 +#include <assert.h>
   26.10 +
   26.11 +#include "stringpair.h"
   26.12 +
   26.13 +using namespace std;
   26.14 +
   26.15 +int test_stringpair_equals(stringpair_t* val1, stringpair_t* val2) {
   26.16 +    assert(val1);
   26.17 +    assert(val2);
   26.18 +    assert(val1->key);
   26.19 +    assert(val2->key);
   26.20 +    assert(val1->value);
   26.21 +    assert(val2->value);
   26.22 +    return((strcmp(val1->key, val2->key) == 0) && (strcmp(val1->value, val2->value) == 0));
   26.23 +}
   26.24 +
   26.25 +int main() {
   26.26 +    cout << "\n*** data structures: stringpair_list_test ***\n\n";
   26.27 +
   26.28 +    const char* val_1_arr[4] = {"I am your father, Luke",
   26.29 +                                "These are not the droids you're looking for",
   26.30 +                                "Swooping is bad",
   26.31 +                                "I should go."};
   26.32 +    const char* val_2_arr[4] = {"Had to be me.",
   26.33 +                                "Someone else might have gotten it wrong",
   26.34 +                                "Na via lerno victoria",
   26.35 +                                "I was told that there would be cake."};
   26.36 +                                
   26.37 +//    const stringpair_t* stringpair_arr[4];
   26.38 +    
   26.39 +    int i;
   26.40 +    
   26.41 +//    for (i = 0; i < 4; i++) {
   26.42 +//        stringpair_arr[i] = new stringpair(val_1_arr[i], val_2_arr[i]);
   26.43 +//    }
   26.44 +    
   26.45 +    cout << "creating one-element stringpair_list...\n";
   26.46 +    
   26.47 +    stringpair_t* strpair = new_stringpair(val_1_arr[0], val_2_arr[0]);
   26.48 +    assert(strpair);
   26.49 +    stringpair_list_t* pairlist = new_stringpair_list(strpair);
   26.50 +    assert(pairlist->value);
   26.51 +    assert(test_stringpair_equals(strpair, pairlist->value));
   26.52 +    assert(pairlist->next == NULL);
   26.53 +    cout << "one-element stringpair_list created, next element is NULL\n\n";
   26.54 +    
   26.55 +    cout << "duplicating one-element list...\n";
   26.56 +    stringpair_list_t* duplist = stringpair_list_dup(pairlist);
   26.57 +    stringpair_t* srcpair = pairlist->value;
   26.58 +    stringpair_t* dstpair = duplist->value;
   26.59 +    assert(dstpair);
   26.60 +    assert(dstpair->value);
   26.61 +    assert(test_stringpair_equals(srcpair, dstpair));
   26.62 +    assert(srcpair->key != dstpair->key);   // test deep copies (to be fixed in next 2 commits)
   26.63 +    assert(srcpair->value != dstpair->value);
   26.64 +    assert(duplist->next == NULL);
   26.65 +    cout << "one-element stringpair_list duplicated.\n\n";
   26.66 +    
   26.67 +    cout << "freeing stringpair_lists...\n";
   26.68 +    free_stringpair_list(pairlist); // will free strpair
   26.69 +    free_stringpair_list(duplist);
   26.70 +    pairlist = NULL;
   26.71 +    duplist = NULL;
   26.72 +    strpair = NULL;
   26.73 +    
   26.74 +    stringpair_list_t* p;
   26.75 +    cout << "\ncreating four-element list...\n";
   26.76 +    pairlist = stringpair_list_add(pairlist, new_stringpair(val_1_arr[0], val_2_arr[0]));
   26.77 +    for (i = 1; i < 4; i++) {
   26.78 +        p = stringpair_list_add(pairlist, new_stringpair(val_1_arr[i], val_2_arr[i]));
   26.79 +        assert(p);
   26.80 +    }
   26.81 +    
   26.82 +    p = pairlist;
   26.83 +    
   26.84 +    for (i = 0; i < 4; i++) {
   26.85 +        assert(p);
   26.86 +        
   26.87 +        strpair = p->value;
   26.88 +        assert(strpair);
   26.89 +        
   26.90 +        assert(strpair->key);
   26.91 +        assert(strcmp(val_1_arr[i], strpair->key) == 0);
   26.92 +        
   26.93 +        assert(strpair->value);
   26.94 +        assert(strcmp(val_2_arr[i], strpair->value) == 0);
   26.95 +        
   26.96 +        assert(val_1_arr[i] != strpair->key);
   26.97 +        assert(val_2_arr[i] != strpair->value);
   26.98 +        
   26.99 +        p = p->next;
  26.100 +    }
  26.101 +    assert(p == NULL);
  26.102 +    
  26.103 +    cout << "\nduplicating four-element list...\n\n";
  26.104 +    duplist = stringpair_list_dup(pairlist);
  26.105 +    
  26.106 +    p = pairlist;
  26.107 +    stringpair_list_t* dup_p = duplist;
  26.108 +    
  26.109 +    while (dup_p) {
  26.110 +        srcpair = p->value;
  26.111 +        dstpair = dup_p->value;
  26.112 +
  26.113 +        assert(dstpair);
  26.114 +        assert(dstpair->value);
  26.115 +        
  26.116 +        cout << srcpair->key << ":" << srcpair->value << " / " << dstpair->key << ":" << dstpair->value << "\n";
  26.117 +        assert(test_stringpair_equals(srcpair, dstpair));
  26.118 +
  26.119 +        assert(srcpair->key != dstpair->key);   // test deep copies (to be fixed in next 2 commits)
  26.120 +        assert(srcpair->value != dstpair->value);
  26.121 +
  26.122 +        i++;
  26.123 +        p = p->next;
  26.124 +
  26.125 +        dup_p = dup_p->next;
  26.126 +        assert((p == NULL) == (dup_p == NULL));
  26.127 +    }
  26.128 +    cout << "\nfour-element stringpair_list successfully duplicated.\n\n";
  26.129 +
  26.130 +    cout << "freeing stringpair_lists...\n";
  26.131 +    free_stringpair_list(pairlist); // will free strpair
  26.132 +    free_stringpair_list(duplist);
  26.133 +    pairlist = NULL;
  26.134 +    duplist = NULL;
  26.135 +    
  26.136 +    cout << "done.\n";
  26.137 +        
  26.138 +    
  26.139 +    return 0;
  26.140 +}
  26.141 +