merge "ENGINE-199" into "default" branch
authorRoker <roker@pep-project.org>
Tue, 09 May 2017 14:00:24 +0200
changeset 1767bca5879ada6e
parent 1763 8428975706d9
parent 1766 f8f5f3dba9d7
child 1769 07b5567daaee
child 1770 9d19fa238f63
merge "ENGINE-199" into "default" branch
     1.1 --- a/Makefile.conf	Mon May 08 22:09:00 2017 +0200
     1.2 +++ b/Makefile.conf	Tue May 09 14:00:24 2017 +0200
     1.3 @@ -2,7 +2,7 @@
     1.4  
     1.5  BUILD_ON=$(shell uname)
     1.6  BUILD_FOR=$(BUILD_ON)
     1.7 -OPTIMIZE=-g -Wall -O0 -fPIC
     1.8 +OPTIMIZE=-g -Wall -O0 -fPIC -DDEBUG_ERRORSTACK
     1.9  #OPTIMIZE=-O3 -Wall -DNDEBUG -std=c99
    1.10  LD=$(CC)
    1.11  #CC=gcc-mp-4.9 -std=c99 -fstrict-aliasing -Wstrict-aliasing=3
     2.1 --- a/src/keymanagement.c	Mon May 08 22:09:00 2017 +0200
     2.2 +++ b/src/keymanagement.c	Tue May 09 14:00:24 2017 +0200
     2.3 @@ -91,7 +91,7 @@
     2.4      assert(!EMPTYSTR(identity->address));
     2.5  
     2.6      if (!(session && identity && !EMPTYSTR(identity->address)))
     2.7 -        return PEP_ILLEGAL_VALUE;
     2.8 +        return ERROR(PEP_ILLEGAL_VALUE);
     2.9  
    2.10      if (identity->me || (identity->user_id && strcmp(identity->user_id, PEP_OWN_USERID) == 0)) {
    2.11          identity->me = true;
    2.12 @@ -312,7 +312,7 @@
    2.13      free_identity(stored_identity);
    2.14      free_identity(temp_id);
    2.15      
    2.16 -    return status;
    2.17 +    return ERROR(status);
    2.18  }
    2.19  
    2.20  PEP_STATUS elect_ownkey(
    2.21 @@ -402,7 +402,7 @@
    2.22      
    2.23      *is_usable = !dont_use_fpr;
    2.24      
    2.25 -    return status;
    2.26 +    return ERROR(status);
    2.27  }
    2.28  
    2.29  PEP_STATUS _myself(PEP_SESSION session, pEp_identity * identity, bool do_keygen, bool ignore_flags)
    2.30 @@ -420,7 +420,7 @@
    2.31      if (!(session && identity && !EMPTYSTR(identity->address) &&
    2.32              (EMPTYSTR(identity->user_id) ||
    2.33              strcmp(identity->user_id, PEP_OWN_USERID) == 0)))
    2.34 -        return PEP_ILLEGAL_VALUE;
    2.35 +        return ERROR(PEP_ILLEGAL_VALUE);
    2.36  
    2.37      identity->comm_type = PEP_ct_pEp;
    2.38      identity->me = true;
    2.39 @@ -508,7 +508,7 @@
    2.40          status = elect_ownkey(session, identity);
    2.41          assert(status == PEP_STATUS_OK);
    2.42          if (status != PEP_STATUS_OK) {
    2.43 -            return status;
    2.44 +            return ERROR(status);
    2.45          }
    2.46  
    2.47          bool has_private = false;
    2.48 @@ -540,16 +540,16 @@
    2.49  
    2.50          if (status != PEP_STATUS_OK) 
    2.51          {
    2.52 -            return status;
    2.53 +            return ERROR(status);
    2.54          }
    2.55      }
    2.56     
    2.57      bool new_key_generated = false;
    2.58  
    2.59      if (EMPTYSTR(identity->fpr) || revoked)
    2.60 -    {        
    2.61 +    {
    2.62          if(!do_keygen){
    2.63 -            return PEP_GET_KEY_FAILED;
    2.64 +            return ERROR(PEP_GET_KEY_FAILED);
    2.65          }
    2.66  
    2.67          if(revoked)
    2.68 @@ -567,7 +567,7 @@
    2.69              DEBUG_LOG("generating key pair failed", "debug", buf);
    2.70              if(revoked && r_fpr)
    2.71                  free(r_fpr);
    2.72 -            return status;
    2.73 +            return ERROR(status);
    2.74          }
    2.75  
    2.76          new_key_generated = true;
    2.77 @@ -578,7 +578,7 @@
    2.78                                   identity->fpr, time(NULL));
    2.79              free(r_fpr);
    2.80              if (status != PEP_STATUS_OK) {
    2.81 -                return status;
    2.82 +                return ERROR(status);
    2.83              }
    2.84          }
    2.85      }
    2.86 @@ -591,7 +591,7 @@
    2.87  
    2.88          assert(status == PEP_STATUS_OK);
    2.89          if (status != PEP_STATUS_OK) {
    2.90 -            return status;
    2.91 +            return ERROR(status);
    2.92          }
    2.93  
    2.94          if (status == PEP_STATUS_OK && expired) {
    2.95 @@ -619,12 +619,12 @@
    2.96          }
    2.97      }
    2.98  
    2.99 -    return PEP_STATUS_OK;
   2.100 +    return ERROR(PEP_STATUS_OK);
   2.101  }
   2.102  
   2.103  DYNAMIC_API PEP_STATUS myself(PEP_SESSION session, pEp_identity * identity)
   2.104  {
   2.105 -    return _myself(session, identity, true, false);
   2.106 +    return ERROR(_myself(session, identity, true, false));
   2.107  }
   2.108  
   2.109  DYNAMIC_API PEP_STATUS register_examine_function(
     3.1 --- a/src/message_api.c	Mon May 08 22:09:00 2017 +0200
     3.2 +++ b/src/message_api.c	Tue May 09 14:00:24 2017 +0200
     3.3 @@ -1101,20 +1101,20 @@
     3.4      assert(enc_format != PEP_enc_none);
     3.5  
     3.6      if (!(session && src && dst && enc_format != PEP_enc_none))
     3.7 -        return PEP_ILLEGAL_VALUE;
     3.8 +        return ERROR(PEP_ILLEGAL_VALUE);
     3.9  
    3.10      if (src->dir == PEP_dir_incoming)
    3.11 -        return PEP_ILLEGAL_VALUE;
    3.12 +        return ERROR(PEP_ILLEGAL_VALUE);
    3.13  
    3.14      determine_encryption_format(src);
    3.15      if (src->enc_format != PEP_enc_none)
    3.16 -        return PEP_ILLEGAL_VALUE;
    3.17 +        return ERROR(PEP_ILLEGAL_VALUE);
    3.18  
    3.19      *dst = NULL;
    3.20  
    3.21      status = myself(session, src->from);
    3.22      if (status != PEP_STATUS_OK)
    3.23 -        goto pep_error;
    3.24 +        GOTO(pep_error);
    3.25  
    3.26      keys = new_stringlist(src->from->fpr);
    3.27      if (keys == NULL)
    3.28 @@ -1148,7 +1148,7 @@
    3.29          PEP_STATUS _status = update_identity(session, _il->ident);
    3.30          if (_status != PEP_STATUS_OK) {
    3.31              status = _status;
    3.32 -            goto pep_error;
    3.33 +            GOTO(pep_error);
    3.34          }
    3.35  
    3.36          if (_il->ident->fpr && _il->ident->fpr[0]) {
    3.37 @@ -1169,7 +1169,7 @@
    3.38              PEP_STATUS _status = update_identity(session, _il->ident);
    3.39              if (_status != PEP_STATUS_OK) {
    3.40                  status = _status;
    3.41 -                goto pep_error;
    3.42 +                GOTO(pep_error);
    3.43              }
    3.44  
    3.45              if (_il->ident->fpr && _il->ident->fpr[0]) {
    3.46 @@ -1190,7 +1190,7 @@
    3.47              if (_status != PEP_STATUS_OK)
    3.48              {
    3.49                  status = _status;
    3.50 -                goto pep_error;
    3.51 +                GOTO(pep_error);
    3.52              }
    3.53  
    3.54              if (_il->ident->fpr && _il->ident->fpr[0]) {
    3.55 @@ -1215,7 +1215,7 @@
    3.56          free_stringlist(keys);
    3.57          if (!session->passive_mode && !(flags & PEP_encrypt_flag_force_no_attached_key))
    3.58              attach_own_key(session, src);
    3.59 -        return PEP_UNENCRYPTED;
    3.60 +        return ERROR(PEP_UNENCRYPTED);
    3.61      }
    3.62      else {
    3.63          msg = clone_to_empty_message(src);
    3.64 @@ -1242,14 +1242,14 @@
    3.65          default:
    3.66              assert(0);
    3.67              status = PEP_ILLEGAL_VALUE;
    3.68 -            goto pep_error;
    3.69 +            GOTO(pep_error);
    3.70          }
    3.71  
    3.72          if (status == PEP_OUT_OF_MEMORY)
    3.73              goto enomem;
    3.74  
    3.75          if (status != PEP_STATUS_OK)
    3.76 -            goto pep_error;
    3.77 +            GOTO(pep_error);
    3.78      }
    3.79  
    3.80      free_stringlist(keys);
    3.81 @@ -1272,7 +1272,7 @@
    3.82      }
    3.83  
    3.84      *dst = msg;
    3.85 -    return status;
    3.86 +    return ERROR(status);
    3.87  
    3.88  enomem:
    3.89      status = PEP_OUT_OF_MEMORY;
    3.90 @@ -1281,7 +1281,7 @@
    3.91      free_stringlist(keys);
    3.92      free_message(msg);
    3.93  
    3.94 -    return status;
    3.95 +    return ERROR(status);
    3.96  }
    3.97  
    3.98  DYNAMIC_API PEP_STATUS encrypt_message_for_self(
    3.99 @@ -1303,18 +1303,18 @@
   3.100      assert(enc_format != PEP_enc_none);
   3.101  
   3.102      if (!(session && src && dst && enc_format != PEP_enc_none))
   3.103 -        return PEP_ILLEGAL_VALUE;
   3.104 +        return ERROR(PEP_ILLEGAL_VALUE);
   3.105  
   3.106      if (src->dir == PEP_dir_incoming)
   3.107 -        return PEP_ILLEGAL_VALUE;
   3.108 +        return ERROR(PEP_ILLEGAL_VALUE);
   3.109  
   3.110      determine_encryption_format(src);
   3.111      if (src->enc_format != PEP_enc_none)
   3.112 -        return PEP_ILLEGAL_VALUE;
   3.113 +        return ERROR(PEP_ILLEGAL_VALUE);
   3.114  
   3.115      status = myself(session, target_id);
   3.116      if (status != PEP_STATUS_OK)
   3.117 -        goto pep_error;
   3.118 +        GOTO(pep_error);
   3.119  
   3.120      *dst = NULL;
   3.121  
   3.122 @@ -1391,7 +1391,7 @@
   3.123      free_stringlist(keys);
   3.124      free_message(msg);
   3.125  
   3.126 -    return status;
   3.127 +    return ERROR(status);
   3.128  }
   3.129  
   3.130  static bool is_a_pEpmessage(const message *msg)
   3.131 @@ -1617,7 +1617,7 @@
   3.132      assert(flags);
   3.133  
   3.134      if (!(session && src && dst && keylist && rating && flags))
   3.135 -        return PEP_ILLEGAL_VALUE;
   3.136 +        return ERROR(PEP_ILLEGAL_VALUE);
   3.137  
   3.138      *flags = 0;
   3.139  
   3.140 @@ -1628,7 +1628,7 @@
   3.141      // we would need to check signature
   3.142      status = _update_identity_for_incoming_message(session, src);
   3.143      if(status != PEP_STATUS_OK)
   3.144 -        return status;
   3.145 +        return ERROR(status);
   3.146  
   3.147      // Get detached signature, if any
   3.148      bloblist_t* detached_sig = NULL;
   3.149 @@ -1662,7 +1662,7 @@
   3.150                                  PEP_decrypt_flag_consume;
   3.151                  }
   3.152                  else if (status != PEP_STATUS_OK) {
   3.153 -                    return status;
   3.154 +                    return ERROR(status);
   3.155                  }
   3.156              }
   3.157              
   3.158 @@ -1694,7 +1694,7 @@
   3.159                  }
   3.160              }
   3.161              
   3.162 -            return PEP_UNENCRYPTED;
   3.163 +            return ERROR(PEP_UNENCRYPTED);
   3.164  
   3.165          case PEP_enc_PGP_MIME:
   3.166              ctext = src->attachments->next->value;
   3.167 @@ -1718,7 +1718,7 @@
   3.168                                                     csize, dsig_text, dsig_size,
   3.169                                                     &ptext, &psize, &_keylist);
   3.170      if (status > PEP_CANNOT_DECRYPT_UNKNOWN){
   3.171 -        goto pep_error;
   3.172 +        GOTO(pep_error);
   3.173      }
   3.174  
   3.175      decrypt_status = status;
   3.176 @@ -1894,7 +1894,9 @@
   3.177              case PEP_enc_PGP_MIME_Outlook1:
   3.178                  status = copy_fields(msg, src);
   3.179                  if (status != PEP_STATUS_OK)
   3.180 -                    goto pep_error;
   3.181 +                {
   3.182 +                    GOTO(pep_error);
   3.183 +                }
   3.184  
   3.185                  if (src->shortmsg == NULL || strcmp(src->shortmsg, "pEp") == 0)
   3.186                  {
   3.187 @@ -1952,7 +1954,9 @@
   3.188  
   3.189              status = _update_identity_for_incoming_message(session, src);
   3.190              if(status != PEP_STATUS_OK)
   3.191 -                goto pep_error;
   3.192 +            {
   3.193 +                GOTO(pep_error);
   3.194 +            }
   3.195  
   3.196              char *re_ptext = NULL;
   3.197              size_t re_psize;
   3.198 @@ -1966,7 +1970,9 @@
   3.199              free(re_ptext);
   3.200  
   3.201              if (status > PEP_CANNOT_DECRYPT_UNKNOWN)
   3.202 -                goto pep_error;
   3.203 +            {
   3.204 +                GOTO(pep_error);
   3.205 +            }
   3.206  
   3.207              decrypt_status = status;
   3.208          }
   3.209 @@ -2006,7 +2012,9 @@
   3.210                      if (status == PEP_CANNOT_FIND_IDENTITY)
   3.211                         status = PEP_STATUS_OK;
   3.212                      if (status != PEP_STATUS_OK)
   3.213 -                        goto pep_error;
   3.214 +                    {
   3.215 +                        GOTO(pep_error);
   3.216 +                    }
   3.217                  }
   3.218              }
   3.219          }
   3.220 @@ -2064,7 +2072,7 @@
   3.221      *dst = msg;
   3.222      *keylist = _keylist;
   3.223  
   3.224 -    return status;
   3.225 +    return ERROR(status);
   3.226  
   3.227  enomem:
   3.228      status = PEP_OUT_OF_MEMORY;
   3.229 @@ -2074,7 +2082,7 @@
   3.230      free_message(msg);
   3.231      free_stringlist(_keylist);
   3.232  
   3.233 -    return status;
   3.234 +    return ERROR(status);
   3.235  }
   3.236  
   3.237  DYNAMIC_API PEP_STATUS decrypt_message(
   3.238 @@ -2123,8 +2131,7 @@
   3.239  
   3.240      free_identity_list(private_il);
   3.241  
   3.242 -    return status;
   3.243 -
   3.244 +    return ERROR(status);
   3.245  }
   3.246  
   3.247  static void _max_comm_type_from_identity_list(
   3.248 @@ -2165,10 +2172,10 @@
   3.249      assert(rating);
   3.250  
   3.251      if (!(session && msg && rating))
   3.252 -        return PEP_ILLEGAL_VALUE;
   3.253 +        return ERROR(PEP_ILLEGAL_VALUE);
   3.254  
   3.255      if (msg->dir != PEP_dir_outgoing)
   3.256 -        return PEP_ILLEGAL_VALUE;
   3.257 +        return ERROR(PEP_ILLEGAL_VALUE);
   3.258  
   3.259      *rating = PEP_rating_undefined;
   3.260  
   3.261 @@ -2252,7 +2259,7 @@
   3.262  
   3.263      // this should never happen
   3.264      assert(false);
   3.265 -	return PEP_color_no_color;
   3.266 +    return PEP_color_no_color;
   3.267  }
   3.268  
   3.269  DYNAMIC_API PEP_STATUS get_trustwords(
   3.270 @@ -2315,7 +2322,7 @@
   3.271                  goto error_release;
   3.272              break;
   3.273          default:
   3.274 -            return PEP_UNKNOWN_ERROR; // shouldn't be possible
   3.275 +            return ERROR(PEP_UNKNOWN_ERROR); // shouldn't be possible
   3.276      }
   3.277  
   3.278      size_t _wsize = first_wsize + second_wsize;
   3.279 @@ -2357,7 +2364,7 @@
   3.280      the_end:
   3.281      free(first_set);
   3.282      free(second_set);
   3.283 -    return status;
   3.284 +    return ERROR(status);
   3.285  }
   3.286  
   3.287  DYNAMIC_API PEP_STATUS get_message_trustwords(
   3.288 @@ -2443,7 +2450,7 @@
   3.289  
   3.290      if (status != PEP_STATUS_OK) {
   3.291          free_identity(partner);
   3.292 -        return status;
   3.293 +        return ERROR(status);
   3.294      }
   3.295     
   3.296      // Find own identity corresponding to given account address.
   3.297 @@ -2456,7 +2463,7 @@
   3.298  
   3.299      if (status != PEP_STATUS_OK) {
   3.300          free_identity(stored_identity);
   3.301 -        return status;
   3.302 +        return ERROR(status);
   3.303      }
   3.304  
   3.305      // get the trustwords
   3.306 @@ -2465,7 +2472,7 @@
   3.307                              partner, received_by, 
   3.308                              lang, words, &wsize, full);
   3.309  
   3.310 -    return status;
   3.311 +    return ERROR(status);
   3.312  }
   3.313  
   3.314  DYNAMIC_API PEP_STATUS MIME_decrypt_message(
   3.315 @@ -2490,7 +2497,7 @@
   3.316  
   3.317      status = mime_decode_message(mimetext, size, &tmp_msg);
   3.318      if (status != PEP_STATUS_OK)
   3.319 -        goto pep_error;
   3.320 +        GOTO(pep_error);
   3.321  
   3.322      PEP_STATUS decrypt_status = decrypt_message(session,
   3.323                                                  tmp_msg,
   3.324 @@ -2506,14 +2513,14 @@
   3.325      if (decrypt_status > PEP_CANNOT_DECRYPT_UNKNOWN)
   3.326      {
   3.327          status = decrypt_status;
   3.328 -        goto pep_error;
   3.329 +        GOTO(pep_error);
   3.330      }
   3.331  
   3.332      assert(dec_msg);
   3.333      
   3.334      if (!dec_msg) {
   3.335          status = PEP_UNKNOWN_ERROR;
   3.336 -        goto pep_error;
   3.337 +        GOTO(pep_error);
   3.338      }
   3.339  
   3.340      status = mime_encode_message(dec_msg, false, mime_plaintext);
   3.341 @@ -2522,14 +2529,14 @@
   3.342      {
   3.343          free(tmp_msg);
   3.344          free(dec_msg);
   3.345 -        return decrypt_status;
   3.346 +        return ERROR(decrypt_status);
   3.347      }
   3.348      
   3.349  pep_error:
   3.350      free_message(tmp_msg);
   3.351      free_message(dec_msg);
   3.352  
   3.353 -    return status;
   3.354 +    return ERROR(status);
   3.355  }
   3.356  
   3.357  
   3.358 @@ -2549,7 +2556,7 @@
   3.359  
   3.360      status = mime_decode_message(mimetext, size, &tmp_msg);
   3.361      if (status != PEP_STATUS_OK)
   3.362 -        goto pep_error;
   3.363 +        GOTO(pep_error);
   3.364  
   3.365      // This isn't incoming, though... so we need to reverse the direction
   3.366      tmp_msg->dir = PEP_dir_outgoing;
   3.367 @@ -2560,12 +2567,12 @@
   3.368                               enc_format,
   3.369                               flags);
   3.370      if (status != PEP_STATUS_OK)
   3.371 -        goto pep_error;
   3.372 +        GOTO(pep_error);
   3.373  
   3.374  
   3.375      if (!enc_msg) {
   3.376          status = PEP_UNKNOWN_ERROR;
   3.377 -        goto pep_error;
   3.378 +        GOTO(pep_error);
   3.379      }
   3.380  
   3.381      status = mime_encode_message(enc_msg, false, mime_ciphertext);
   3.382 @@ -2574,7 +2581,7 @@
   3.383      free_message(tmp_msg);
   3.384      free_message(enc_msg);
   3.385  
   3.386 -    return status;
   3.387 +    return ERROR(status);
   3.388  
   3.389  }
   3.390  
   3.391 @@ -2618,5 +2625,5 @@
   3.392      free_message(tmp_msg);
   3.393      free_message(enc_msg);
   3.394  
   3.395 -    return status;
   3.396 +    return ERROR(status);
   3.397  }
     4.1 --- a/src/pEpEngine.c	Mon May 08 22:09:00 2017 +0200
     4.2 +++ b/src/pEpEngine.c	Tue May 09 14:00:24 2017 +0200
     4.3 @@ -239,6 +239,10 @@
     4.4  
     4.5      _session->version = PEP_ENGINE_VERSION;
     4.6  
     4.7 +#ifdef DEBUG_ERRORSTACK
     4.8 +    _session->errorstack = new_stringlist(NULL);
     4.9 +#endif
    4.10 +
    4.11      assert(LOCAL_DB);
    4.12      if (LOCAL_DB == NULL) {
    4.13          status = PEP_INIT_CANNOT_OPEN_DB;
    4.14 @@ -791,6 +795,9 @@
    4.15          release_transport_system(session, out_last);
    4.16          release_cryptotech(session, out_last);
    4.17  
    4.18 +#ifdef DEBUG_ERRORSTACK
    4.19 +        free_stringlist(session->errorstack);
    4.20 +#endif
    4.21          free(session);
    4.22      }
    4.23  }
    4.24 @@ -850,7 +857,7 @@
    4.25      } while (result == SQLITE_BUSY);
    4.26      sqlite3_reset(session->log);
    4.27  
    4.28 -    return status;
    4.29 +    return ERROR(status);
    4.30  }
    4.31  
    4.32  DYNAMIC_API PEP_STATUS trustword(
    4.33 @@ -1884,7 +1891,7 @@
    4.34      status = PEP_OUT_OF_MEMORY;
    4.35  
    4.36  the_end:
    4.37 -    return status;
    4.38 +    return ERROR(status);
    4.39  }
    4.40  
    4.41  DYNAMIC_API PEP_STATUS get_languagelist(
    4.42 @@ -2307,3 +2314,39 @@
    4.43  
    4.44      return PEP_STATUS_OK;
    4.45  }
    4.46 +
    4.47 +#ifdef DEBUG_ERRORSTACK
    4.48 +PEP_STATUS session_add_error(PEP_SESSION session, const char* file, unsigned line, PEP_STATUS status)
    4.49 +{
    4.50 +    char logline[48];
    4.51 +    if(status>0)
    4.52 +    {
    4.53 +        snprintf(logline,47, "%.24s:%u status=%u (0x%x)", file, line, status, status);
    4.54 +    }else{
    4.55 +        snprintf(logline,47, "%.24s:%u status=%i.", file, line, status);
    4.56 +    }
    4.57 +    stringlist_add(session->errorstack, logline); // logline is copied! :-)
    4.58 +    return status;
    4.59 +}
    4.60 +
    4.61 +DYNAMIC_API const stringlist_t* get_errorstack(PEP_SESSION session)
    4.62 +{
    4.63 +    return session->errorstack;
    4.64 +}
    4.65 +
    4.66 +#else
    4.67 +
    4.68 +static stringlist_t* dummy_errorstack = NULL;
    4.69 +
    4.70 +DYNAMIC_API const stringlist_t* get_errorstack(PEP_SESSION session)
    4.71 +{
    4.72 +	if(dummy_errorstack == NULL)
    4.73 +	{
    4.74 +		dummy_errorstack = new_stringlist("( Please recompile pEpEngine with -DDEBUG_ERRORSTACK )");
    4.75 +	}
    4.76 +	
    4.77 +    return dummy_errorstack;
    4.78 +}
    4.79 +
    4.80 +#endif
    4.81 +
     5.1 --- a/src/pEpEngine.h	Mon May 08 22:09:00 2017 +0200
     5.2 +++ b/src/pEpEngine.h	Tue May 09 14:00:24 2017 +0200
     5.3 @@ -147,6 +147,17 @@
     5.4  DYNAMIC_API void release(PEP_SESSION session);
     5.5  
     5.6  
     5.7 +// const stringlist_t* get_errorstack(PEP_SESSION) - get the error stack for that session, if any
     5.8 +//
     5.9 +//  parameters:
    5.10 +//        session (in)    session handle
    5.11 +//
    5.12 +//    caveat:
    5.13 +//        To get a useful error stack you have to compile with -DDEBUG_ERRORSTACK
    5.14 +//        The error stack belongs to the session. Do no not change it!
    5.15 +DYNAMIC_API const stringlist_t* get_errorstack(PEP_SESSION session);
    5.16 +
    5.17 +
    5.18  // config_passive_mode() - enable passive mode
    5.19  //
    5.20  //  parameters:
     6.1 --- a/src/pEp_internal.h	Mon May 08 22:09:00 2017 +0200
     6.2 +++ b/src/pEp_internal.h	Tue May 09 14:00:24 2017 +0200
     6.3 @@ -161,8 +161,12 @@
     6.4      bool unencrypted_subject;
     6.5      bool keep_sync_msg;
     6.6      
     6.7 +#ifdef DEBUG_ERRORSTACK
     6.8 +    stringlist_t* errorstack;
     6.9 +#endif
    6.10  };
    6.11  
    6.12 +
    6.13  PEP_STATUS init_transport_system(PEP_SESSION session, bool in_first);
    6.14  void release_transport_system(PEP_SESSION session, bool out_last);
    6.15  
    6.16 @@ -305,3 +309,13 @@
    6.17  
    6.18      return comparison == 0;
    6.19  }
    6.20 +
    6.21 +
    6.22 +#ifdef DEBUG_ERRORSTACK
    6.23 +    PEP_STATUS session_add_error(PEP_SESSION session, const char* file, unsigned line, PEP_STATUS status);
    6.24 +    #define ERROR(status)   session_add_error(session, __FILE__, __LINE__, (status))
    6.25 +    #define GOTO(label)     do{ (void)session_add_error(session, __FILE__, __LINE__, status); goto label; }while(0)
    6.26 +#else
    6.27 +    #define ERROR(status)   (status)
    6.28 +    #define GOTO(label)     goto label
    6.29 +#endif