ssl/libcrypto/src/crypto/err/err.c
changeset 0 e4d67989cc36
equal deleted inserted replaced
-1:000000000000 0:e4d67989cc36
       
     1 /* crypto/err/err.c */
       
     2 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
       
     3  * All rights reserved.
       
     4  *
       
     5  * This package is an SSL implementation written
       
     6  * by Eric Young (eay@cryptsoft.com).
       
     7  * The implementation was written so as to conform with Netscapes SSL.
       
     8  * 
       
     9  * This library is free for commercial and non-commercial use as long as
       
    10  * the following conditions are aheared to.  The following conditions
       
    11  * apply to all code found in this distribution, be it the RC4, RSA,
       
    12  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
       
    13  * included with this distribution is covered by the same copyright terms
       
    14  * except that the holder is Tim Hudson (tjh@cryptsoft.com).
       
    15  * 
       
    16  * Copyright remains Eric Young's, and as such any Copyright notices in
       
    17  * the code are not to be removed.
       
    18  * If this package is used in a product, Eric Young should be given attribution
       
    19  * as the author of the parts of the library used.
       
    20  * This can be in the form of a textual message at program startup or
       
    21  * in documentation (online or textual) provided with the package.
       
    22  * 
       
    23  * Redistribution and use in source and binary forms, with or without
       
    24  * modification, are permitted provided that the following conditions
       
    25  * are met:
       
    26  * 1. Redistributions of source code must retain the copyright
       
    27  *    notice, this list of conditions and the following disclaimer.
       
    28  * 2. Redistributions in binary form must reproduce the above copyright
       
    29  *    notice, this list of conditions and the following disclaimer in the
       
    30  *    documentation and/or other materials provided with the distribution.
       
    31  * 3. All advertising materials mentioning features or use of this software
       
    32  *    must display the following acknowledgement:
       
    33  *    "This product includes cryptographic software written by
       
    34  *     Eric Young (eay@cryptsoft.com)"
       
    35  *    The word 'cryptographic' can be left out if the rouines from the library
       
    36  *    being used are not cryptographic related :-).
       
    37  * 4. If you include any Windows specific code (or a derivative thereof) from 
       
    38  *    the apps directory (application code) you must include an acknowledgement:
       
    39  *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
       
    40  * 
       
    41  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
       
    42  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
       
    43  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
       
    44  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
       
    45  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
       
    46  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
       
    47  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
       
    48  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
       
    49  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
       
    50  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
       
    51  * SUCH DAMAGE.
       
    52  * 
       
    53  * The licence and distribution terms for any publically available version or
       
    54  * derivative of this code cannot be changed.  i.e. this code cannot simply be
       
    55  * copied and put under another distribution licence
       
    56  * [including the GNU Public Licence.]
       
    57  */
       
    58 /* ====================================================================
       
    59  * Copyright (c) 1998-2001 The OpenSSL Project.  All rights reserved.
       
    60  *
       
    61  * Redistribution and use in source and binary forms, with or without
       
    62  * modification, are permitted provided that the following conditions
       
    63  * are met:
       
    64  *
       
    65  * 1. Redistributions of source code must retain the above copyright
       
    66  *    notice, this list of conditions and the following disclaimer. 
       
    67  *
       
    68  * 2. Redistributions in binary form must reproduce the above copyright
       
    69  *    notice, this list of conditions and the following disclaimer in
       
    70  *    the documentation and/or other materials provided with the
       
    71  *    distribution.
       
    72  *
       
    73  * 3. All advertising materials mentioning features or use of this
       
    74  *    software must display the following acknowledgment:
       
    75  *    "This product includes software developed by the OpenSSL Project
       
    76  *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
       
    77  *
       
    78  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
       
    79  *    endorse or promote products derived from this software without
       
    80  *    prior written permission. For written permission, please contact
       
    81  *    openssl-core@openssl.org.
       
    82  *
       
    83  * 5. Products derived from this software may not be called "OpenSSL"
       
    84  *    nor may "OpenSSL" appear in their names without prior written
       
    85  *    permission of the OpenSSL Project.
       
    86  *
       
    87  * 6. Redistributions of any form whatsoever must retain the following
       
    88  *    acknowledgment:
       
    89  *    "This product includes software developed by the OpenSSL Project
       
    90  *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
       
    91  *
       
    92  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
       
    93  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
       
    94  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
       
    95  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
       
    96  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
       
    97  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
       
    98  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
       
    99  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
       
   100  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
       
   101  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
       
   102  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
       
   103  * OF THE POSSIBILITY OF SUCH DAMAGE.
       
   104  * ====================================================================
       
   105  *
       
   106  * This product includes cryptographic software written by Eric Young
       
   107  * (eay@cryptsoft.com).  This product includes software written by Tim
       
   108  * Hudson (tjh@cryptsoft.com).
       
   109  *
       
   110  */
       
   111  /*
       
   112  © Portions copyright (c) 2006 Nokia Corporation.  All rights reserved.
       
   113  */
       
   114 
       
   115 
       
   116 #include <stdio.h>
       
   117 #include <stdarg.h>
       
   118 #include <string.h>
       
   119 #include "cryptlib.h"
       
   120 #include <openssl/lhash.h>
       
   121 #include <openssl/crypto.h>
       
   122 #include <openssl/buffer.h>
       
   123 #include <openssl/bio.h>
       
   124 #include <openssl/err.h>
       
   125 #if (defined(SYMBIAN) && (defined(__WINSCW__) || defined(__WINS__)))
       
   126 #include "libcrypto_wsd_macros.h"
       
   127 #include "libcrypto_wsd.h"
       
   128 #endif
       
   129 
       
   130 static void err_load_strings(int lib, ERR_STRING_DATA *str);
       
   131 static void ERR_STATE_free(ERR_STATE *s);
       
   132 #ifndef OPENSSL_NO_ERR
       
   133 #ifndef EMULATOR
       
   134 static ERR_STRING_DATA ERR_str_libraries[]=
       
   135 	{
       
   136 {ERR_PACK(ERR_LIB_NONE,0,0)		,"unknown library"},
       
   137 {ERR_PACK(ERR_LIB_SYS,0,0)		,"system library"},
       
   138 {ERR_PACK(ERR_LIB_BN,0,0)		,"bignum routines"},
       
   139 {ERR_PACK(ERR_LIB_RSA,0,0)		,"rsa routines"},
       
   140 {ERR_PACK(ERR_LIB_DH,0,0)		,"Diffie-Hellman routines"},
       
   141 {ERR_PACK(ERR_LIB_EVP,0,0)		,"digital envelope routines"},
       
   142 {ERR_PACK(ERR_LIB_BUF,0,0)		,"memory buffer routines"},
       
   143 {ERR_PACK(ERR_LIB_OBJ,0,0)		,"object identifier routines"},
       
   144 {ERR_PACK(ERR_LIB_PEM,0,0)		,"PEM routines"},
       
   145 {ERR_PACK(ERR_LIB_DSA,0,0)		,"dsa routines"},
       
   146 {ERR_PACK(ERR_LIB_X509,0,0)		,"x509 certificate routines"},
       
   147 {ERR_PACK(ERR_LIB_ASN1,0,0)		,"asn1 encoding routines"},
       
   148 {ERR_PACK(ERR_LIB_CONF,0,0)		,"configuration file routines"},
       
   149 {ERR_PACK(ERR_LIB_CRYPTO,0,0)		,"common libcrypto routines"},
       
   150 {ERR_PACK(ERR_LIB_EC,0,0)		,"elliptic curve routines"},
       
   151 {ERR_PACK(ERR_LIB_SSL,0,0)		,"SSL routines"},
       
   152 {ERR_PACK(ERR_LIB_BIO,0,0)		,"BIO routines"},
       
   153 {ERR_PACK(ERR_LIB_PKCS7,0,0)		,"PKCS7 routines"},
       
   154 {ERR_PACK(ERR_LIB_X509V3,0,0)		,"X509 V3 routines"},
       
   155 {ERR_PACK(ERR_LIB_PKCS12,0,0)		,"PKCS12 routines"},
       
   156 {ERR_PACK(ERR_LIB_RAND,0,0)		,"random number generator"},
       
   157 {ERR_PACK(ERR_LIB_DSO,0,0)		,"DSO support routines"},
       
   158 {ERR_PACK(ERR_LIB_ENGINE,0,0)		,"engine routines"},
       
   159 {ERR_PACK(ERR_LIB_OCSP,0,0)		,"OCSP routines"},
       
   160 {0,NULL},
       
   161 	};
       
   162 
       
   163 static ERR_STRING_DATA ERR_str_functs[]=
       
   164 	{
       
   165 	{ERR_PACK(0,SYS_F_FOPEN,0),     	"fopen"},
       
   166 	{ERR_PACK(0,SYS_F_CONNECT,0),		"connect"},
       
   167 	{ERR_PACK(0,SYS_F_GETSERVBYNAME,0),	"getservbyname"},
       
   168 	{ERR_PACK(0,SYS_F_SOCKET,0),		"socket"}, 
       
   169 	{ERR_PACK(0,SYS_F_IOCTLSOCKET,0),	"ioctlsocket"},
       
   170 	{ERR_PACK(0,SYS_F_BIND,0),		"bind"},
       
   171 	{ERR_PACK(0,SYS_F_LISTEN,0),		"listen"},
       
   172 	{ERR_PACK(0,SYS_F_ACCEPT,0),		"accept"},
       
   173 #ifdef OPENSSL_SYS_WINDOWS
       
   174 	{ERR_PACK(0,SYS_F_WSASTARTUP,0),	"WSAstartup"},
       
   175 #endif
       
   176 	{ERR_PACK(0,SYS_F_OPENDIR,0),		"opendir"},
       
   177 	{ERR_PACK(0,SYS_F_FREAD,0),		"fread"},
       
   178 	{0,NULL},
       
   179 	};
       
   180 
       
   181 static ERR_STRING_DATA ERR_str_reasons[]=
       
   182 	{
       
   183 {ERR_R_SYS_LIB				,"system lib"},
       
   184 {ERR_R_BN_LIB				,"BN lib"},
       
   185 {ERR_R_RSA_LIB				,"RSA lib"},
       
   186 {ERR_R_DH_LIB				,"DH lib"},
       
   187 {ERR_R_EVP_LIB				,"EVP lib"},
       
   188 {ERR_R_BUF_LIB				,"BUF lib"},
       
   189 {ERR_R_OBJ_LIB				,"OBJ lib"},
       
   190 {ERR_R_PEM_LIB				,"PEM lib"},
       
   191 {ERR_R_DSA_LIB				,"DSA lib"},
       
   192 {ERR_R_X509_LIB				,"X509 lib"},
       
   193 {ERR_R_ASN1_LIB				,"ASN1 lib"},
       
   194 {ERR_R_CONF_LIB				,"CONF lib"},
       
   195 {ERR_R_CRYPTO_LIB			,"CRYPTO lib"},
       
   196 {ERR_R_EC_LIB				,"EC lib"},
       
   197 {ERR_R_SSL_LIB				,"SSL lib"},
       
   198 {ERR_R_BIO_LIB				,"BIO lib"},
       
   199 {ERR_R_PKCS7_LIB			,"PKCS7 lib"},
       
   200 {ERR_R_X509V3_LIB			,"X509V3 lib"},
       
   201 {ERR_R_PKCS12_LIB			,"PKCS12 lib"},
       
   202 {ERR_R_RAND_LIB				,"RAND lib"},
       
   203 {ERR_R_DSO_LIB				,"DSO lib"},
       
   204 {ERR_R_ENGINE_LIB			,"ENGINE lib"},
       
   205 {ERR_R_OCSP_LIB				,"OCSP lib"},
       
   206 
       
   207 {ERR_R_NESTED_ASN1_ERROR		,"nested asn1 error"},
       
   208 {ERR_R_BAD_ASN1_OBJECT_HEADER		,"bad asn1 object header"},
       
   209 {ERR_R_BAD_GET_ASN1_OBJECT_CALL		,"bad get asn1 object call"},
       
   210 {ERR_R_EXPECTING_AN_ASN1_SEQUENCE	,"expecting an asn1 sequence"},
       
   211 {ERR_R_ASN1_LENGTH_MISMATCH		,"asn1 length mismatch"},
       
   212 {ERR_R_MISSING_ASN1_EOS			,"missing asn1 eos"},
       
   213 
       
   214 {ERR_R_FATAL                            ,"fatal"},
       
   215 {ERR_R_MALLOC_FAILURE			,"malloc failure"},
       
   216 {ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED	,"called a function you should not call"},
       
   217 {ERR_R_PASSED_NULL_PARAMETER		,"passed a null parameter"},
       
   218 {ERR_R_INTERNAL_ERROR			,"internal error"},
       
   219 {ERR_R_DISABLED				,"called a function that was disabled at compile-time"},
       
   220 
       
   221 {0,NULL},
       
   222 	};
       
   223 #else //EMULATOR
       
   224 const ERR_STRING_DATA temp_ERR_str_libraries[]=
       
   225 	{
       
   226 {ERR_PACK(ERR_LIB_NONE,0,0)		,"unknown library"},
       
   227 {ERR_PACK(ERR_LIB_SYS,0,0)		,"system library"},
       
   228 {ERR_PACK(ERR_LIB_BN,0,0)		,"bignum routines"},
       
   229 {ERR_PACK(ERR_LIB_RSA,0,0)		,"rsa routines"},
       
   230 {ERR_PACK(ERR_LIB_DH,0,0)		,"Diffie-Hellman routines"},
       
   231 {ERR_PACK(ERR_LIB_EVP,0,0)		,"digital envelope routines"},
       
   232 {ERR_PACK(ERR_LIB_BUF,0,0)		,"memory buffer routines"},
       
   233 {ERR_PACK(ERR_LIB_OBJ,0,0)		,"object identifier routines"},
       
   234 {ERR_PACK(ERR_LIB_PEM,0,0)		,"PEM routines"},
       
   235 {ERR_PACK(ERR_LIB_DSA,0,0)		,"dsa routines"},
       
   236 {ERR_PACK(ERR_LIB_X509,0,0)		,"x509 certificate routines"},
       
   237 {ERR_PACK(ERR_LIB_ASN1,0,0)		,"asn1 encoding routines"},
       
   238 {ERR_PACK(ERR_LIB_CONF,0,0)		,"configuration file routines"},
       
   239 {ERR_PACK(ERR_LIB_CRYPTO,0,0)		,"common libcrypto routines"},
       
   240 {ERR_PACK(ERR_LIB_EC,0,0)		,"elliptic curve routines"},
       
   241 {ERR_PACK(ERR_LIB_SSL,0,0)		,"SSL routines"},
       
   242 {ERR_PACK(ERR_LIB_BIO,0,0)		,"BIO routines"},
       
   243 {ERR_PACK(ERR_LIB_PKCS7,0,0)		,"PKCS7 routines"},
       
   244 {ERR_PACK(ERR_LIB_X509V3,0,0)		,"X509 V3 routines"},
       
   245 {ERR_PACK(ERR_LIB_PKCS12,0,0)		,"PKCS12 routines"},
       
   246 {ERR_PACK(ERR_LIB_RAND,0,0)		,"random number generator"},
       
   247 {ERR_PACK(ERR_LIB_DSO,0,0)		,"DSO support routines"},
       
   248 {ERR_PACK(ERR_LIB_ENGINE,0,0)		,"engine routines"},
       
   249 {ERR_PACK(ERR_LIB_OCSP,0,0)		,"OCSP routines"},
       
   250 {0,NULL},
       
   251 	};
       
   252 
       
   253 const ERR_STRING_DATA temp_ERR_str_functs[]=
       
   254 	{
       
   255 	{ERR_PACK(0,SYS_F_FOPEN,0),     	"fopen"},
       
   256 	{ERR_PACK(0,SYS_F_CONNECT,0),		"connect"},
       
   257 	{ERR_PACK(0,SYS_F_GETSERVBYNAME,0),	"getservbyname"},
       
   258 	{ERR_PACK(0,SYS_F_SOCKET,0),		"socket"}, 
       
   259 	{ERR_PACK(0,SYS_F_IOCTLSOCKET,0),	"ioctlsocket"},
       
   260 	{ERR_PACK(0,SYS_F_BIND,0),		"bind"},
       
   261 	{ERR_PACK(0,SYS_F_LISTEN,0),		"listen"},
       
   262 	{ERR_PACK(0,SYS_F_ACCEPT,0),		"accept"},
       
   263 #ifdef OPENSSL_SYS_WINDOWS
       
   264 	{ERR_PACK(0,SYS_F_WSASTARTUP,0),	"WSAstartup"},
       
   265 #endif
       
   266 	{ERR_PACK(0,SYS_F_OPENDIR,0),		"opendir"},
       
   267 	{ERR_PACK(0,SYS_F_FREAD,0),		"fread"},
       
   268 	{0,NULL},
       
   269 	};
       
   270 
       
   271 const ERR_STRING_DATA temp_ERR_str_reasons[]=
       
   272 	{
       
   273 {ERR_R_SYS_LIB				,"system lib"},
       
   274 {ERR_R_BN_LIB				,"BN lib"},
       
   275 {ERR_R_RSA_LIB				,"RSA lib"},
       
   276 {ERR_R_DH_LIB				,"DH lib"},
       
   277 {ERR_R_EVP_LIB				,"EVP lib"},
       
   278 {ERR_R_BUF_LIB				,"BUF lib"},
       
   279 {ERR_R_OBJ_LIB				,"OBJ lib"},
       
   280 {ERR_R_PEM_LIB				,"PEM lib"},
       
   281 {ERR_R_DSA_LIB				,"DSA lib"},
       
   282 {ERR_R_X509_LIB				,"X509 lib"},
       
   283 {ERR_R_ASN1_LIB				,"ASN1 lib"},
       
   284 {ERR_R_CONF_LIB				,"CONF lib"},
       
   285 {ERR_R_CRYPTO_LIB			,"CRYPTO lib"},
       
   286 {ERR_R_EC_LIB				,"EC lib"},
       
   287 {ERR_R_SSL_LIB				,"SSL lib"},
       
   288 {ERR_R_BIO_LIB				,"BIO lib"},
       
   289 {ERR_R_PKCS7_LIB			,"PKCS7 lib"},
       
   290 {ERR_R_X509V3_LIB			,"X509V3 lib"},
       
   291 {ERR_R_PKCS12_LIB			,"PKCS12 lib"},
       
   292 {ERR_R_RAND_LIB				,"RAND lib"},
       
   293 {ERR_R_DSO_LIB				,"DSO lib"},
       
   294 {ERR_R_ENGINE_LIB			,"ENGINE lib"},
       
   295 {ERR_R_OCSP_LIB				,"OCSP lib"},
       
   296 
       
   297 {ERR_R_NESTED_ASN1_ERROR		,"nested asn1 error"},
       
   298 {ERR_R_BAD_ASN1_OBJECT_HEADER		,"bad asn1 object header"},
       
   299 {ERR_R_BAD_GET_ASN1_OBJECT_CALL		,"bad get asn1 object call"},
       
   300 {ERR_R_EXPECTING_AN_ASN1_SEQUENCE	,"expecting an asn1 sequence"},
       
   301 {ERR_R_ASN1_LENGTH_MISMATCH		,"asn1 length mismatch"},
       
   302 {ERR_R_MISSING_ASN1_EOS			,"missing asn1 eos"},
       
   303 
       
   304 {ERR_R_FATAL                            ,"fatal"},
       
   305 {ERR_R_MALLOC_FAILURE			,"malloc failure"},
       
   306 {ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED	,"called a function you should not call"},
       
   307 {ERR_R_PASSED_NULL_PARAMETER		,"passed a null parameter"},
       
   308 {ERR_R_INTERNAL_ERROR			,"internal error"},
       
   309 {ERR_R_DISABLED				,"called a function that was disabled at compile-time"},
       
   310 
       
   311 {0,NULL},
       
   312 	};
       
   313  GET_STATIC_ARRAY_FROM_TLS(ERR_str_functs,err_err,ERR_STRING_DATA)
       
   314  GET_STATIC_ARRAY_FROM_TLS(ERR_str_reasons,err_err,ERR_STRING_DATA)
       
   315  GET_STATIC_ARRAY_FROM_TLS(ERR_str_libraries,err_err,ERR_STRING_DATA)
       
   316  #define ERR_str_functs (GET_WSD_VAR_NAME(ERR_str_functs,err_err, s)())
       
   317  #define ERR_str_reasons (GET_WSD_VAR_NAME(ERR_str_reasons,err_err, s)())
       
   318  #define ERR_str_libraries (GET_WSD_VAR_NAME(ERR_str_libraries,err_err, s)())
       
   319 #endif //EMULATOR
       
   320 #endif
       
   321 
       
   322 #ifndef EMULATOR
       
   323 /* Define the predeclared (but externally opaque) "ERR_FNS" type */
       
   324 struct st_ERR_FNS
       
   325 	{
       
   326 	/* Works on the "error_hash" string table */
       
   327 	LHASH *(*cb_err_get)(int create);
       
   328 	void (*cb_err_del)(void);
       
   329 	ERR_STRING_DATA *(*cb_err_get_item)(const ERR_STRING_DATA *);
       
   330 	ERR_STRING_DATA *(*cb_err_set_item)(ERR_STRING_DATA *);
       
   331 	ERR_STRING_DATA *(*cb_err_del_item)(ERR_STRING_DATA *);
       
   332 	/* Works on the "thread_hash" error-state table */
       
   333 	LHASH *(*cb_thread_get)(int create);
       
   334 	void (*cb_thread_release)(LHASH **hash);
       
   335 	ERR_STATE *(*cb_thread_get_item)(const ERR_STATE *);
       
   336 	ERR_STATE *(*cb_thread_set_item)(ERR_STATE *);
       
   337 	void (*cb_thread_del_item)(const ERR_STATE *);
       
   338 	/* Returns the next available error "library" numbers */
       
   339 	int (*cb_get_next_lib)(void);
       
   340 	};
       
   341 #endif
       
   342 /* Predeclarations of the "err_defaults" functions */
       
   343 static LHASH *int_err_get(int create);
       
   344 static void int_err_del(void);
       
   345 static ERR_STRING_DATA *int_err_get_item(const ERR_STRING_DATA *);
       
   346 static ERR_STRING_DATA *int_err_set_item(ERR_STRING_DATA *);
       
   347 static ERR_STRING_DATA *int_err_del_item(ERR_STRING_DATA *);
       
   348 static LHASH *int_thread_get(int create);
       
   349 static void int_thread_release(LHASH **hash);
       
   350 static ERR_STATE *int_thread_get_item(const ERR_STATE *);
       
   351 static ERR_STATE *int_thread_set_item(ERR_STATE *);
       
   352 static void int_thread_del_item(const ERR_STATE *);
       
   353 static int int_err_get_next_lib(void);
       
   354 /* The static ERR_FNS table using these defaults functions */
       
   355 static const ERR_FNS err_defaults =
       
   356 	{
       
   357 	int_err_get,
       
   358 	int_err_del,
       
   359 	int_err_get_item,
       
   360 	int_err_set_item,
       
   361 	int_err_del_item,
       
   362 	int_thread_get,
       
   363 	int_thread_release,
       
   364 	int_thread_get_item,
       
   365 	int_thread_set_item,
       
   366 	int_thread_del_item,
       
   367 	int_err_get_next_lib
       
   368 	};
       
   369 
       
   370 #ifndef EMULATOR
       
   371 /* The replacable table of ERR_FNS functions we use at run-time */
       
   372 static const ERR_FNS *err_fns = NULL;
       
   373 #else
       
   374 GET_STATIC_VAR_FROM_TLS(err_fns,err,const ERR_FNS *)
       
   375 #define err_fns (*GET_WSD_VAR_NAME(err_fns,err, s)())
       
   376 #endif
       
   377 
       
   378 /* Eg. rather than using "err_get()", use "ERRFN(err_get)()". */
       
   379 #define ERRFN(a) err_fns->cb_##a
       
   380 
       
   381 #ifndef EMULATOR
       
   382 /* The internal state used by "err_defaults" - as such, the setting, reading,
       
   383  * creating, and deleting of this data should only be permitted via the
       
   384  * "err_defaults" functions. This way, a linked module can completely defer all
       
   385  * ERR state operation (together with requisite locking) to the implementations
       
   386  * and state in the loading application. */
       
   387 static LHASH *int_error_hash = NULL;
       
   388 static LHASH *int_thread_hash = NULL;
       
   389 static int int_thread_hash_references = 0;
       
   390 static int int_err_library_number= ERR_LIB_USER;
       
   391 #else
       
   392 GET_STATIC_VAR_FROM_TLS(int_error_hash,err,LHASH *)
       
   393 #define int_error_hash (*GET_WSD_VAR_NAME(int_error_hash,err,s)())
       
   394 
       
   395 GET_STATIC_VAR_FROM_TLS(int_thread_hash,err,LHASH *)
       
   396 #define int_thread_hash (*GET_WSD_VAR_NAME(int_thread_hash,err,s)())
       
   397 
       
   398 GET_STATIC_VAR_FROM_TLS(int_thread_hash_references,err,int)
       
   399 #define int_thread_hash_references (*GET_WSD_VAR_NAME(int_thread_hash_references,err,s)())
       
   400 
       
   401 GET_STATIC_VAR_FROM_TLS(int_err_library_number,err,int)
       
   402 #define int_err_library_number (*GET_WSD_VAR_NAME(int_err_library_number,err,s)())
       
   403 
       
   404 #endif
       
   405 
       
   406 /* Internal function that checks whether "err_fns" is set and if not, sets it to
       
   407  * the defaults. */
       
   408 static void err_fns_check(void)
       
   409 	{
       
   410 	if (err_fns) return;
       
   411 	
       
   412 	CRYPTO_w_lock(CRYPTO_LOCK_ERR);
       
   413 	if (!err_fns)
       
   414 		err_fns = &err_defaults;
       
   415 	CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
       
   416 	}
       
   417 
       
   418 /* API functions to get or set the underlying ERR functions. */
       
   419 
       
   420 EXPORT_C const ERR_FNS *ERR_get_implementation(void)
       
   421 	{
       
   422 	err_fns_check();
       
   423 	return err_fns;
       
   424 	}
       
   425 
       
   426 EXPORT_C int ERR_set_implementation(const ERR_FNS *fns)
       
   427 	{
       
   428 	int ret = 0;
       
   429 
       
   430 	CRYPTO_w_lock(CRYPTO_LOCK_ERR);
       
   431 	/* It's too late if 'err_fns' is non-NULL. BTW: not much point setting
       
   432 	 * an error is there?! */
       
   433 	if (!err_fns)
       
   434 		{
       
   435 		err_fns = fns;
       
   436 		ret = 1;
       
   437 		}
       
   438 	CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
       
   439 	return ret;
       
   440 	}
       
   441 
       
   442 /* These are the callbacks provided to "lh_new()" when creating the LHASH tables
       
   443  * internal to the "err_defaults" implementation. */
       
   444 
       
   445 /* static unsigned long err_hash(ERR_STRING_DATA *a); */
       
   446 static unsigned long err_hash(const void *a_void);
       
   447 /* static int err_cmp(ERR_STRING_DATA *a, ERR_STRING_DATA *b); */
       
   448 static int err_cmp(const void *a_void, const void *b_void);
       
   449 /* static unsigned long pid_hash(ERR_STATE *pid); */
       
   450 static unsigned long pid_hash(const void *pid_void);
       
   451 /* static int pid_cmp(ERR_STATE *a,ERR_STATE *pid); */
       
   452 static int pid_cmp(const void *a_void,const void *pid_void);
       
   453 static unsigned long get_error_values(int inc,int top,const char **file,int *line,
       
   454 				      const char **data,int *flags);
       
   455 
       
   456 /* The internal functions used in the "err_defaults" implementation */
       
   457 
       
   458 static LHASH *int_err_get(int create)
       
   459 	{
       
   460 	LHASH *ret = NULL;
       
   461 
       
   462 	CRYPTO_w_lock(CRYPTO_LOCK_ERR);
       
   463 	if (!int_error_hash && create)
       
   464 		{
       
   465 		CRYPTO_push_info("int_err_get (err.c)");
       
   466 		int_error_hash = lh_new(err_hash, err_cmp);
       
   467 		CRYPTO_pop_info();
       
   468 		}
       
   469 	if (int_error_hash)
       
   470 		ret = int_error_hash;
       
   471 	CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
       
   472 
       
   473 	return ret;
       
   474 	}
       
   475 
       
   476 static void int_err_del(void)
       
   477 	{
       
   478 	CRYPTO_w_lock(CRYPTO_LOCK_ERR);
       
   479 	if (int_error_hash)
       
   480 		{
       
   481 		lh_free(int_error_hash);
       
   482 		int_error_hash = NULL;
       
   483 		}
       
   484 	CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
       
   485 	}
       
   486 
       
   487 static ERR_STRING_DATA *int_err_get_item(const ERR_STRING_DATA *d)
       
   488 	{
       
   489 	ERR_STRING_DATA *p;
       
   490 	LHASH *hash;
       
   491 
       
   492 	err_fns_check();
       
   493 	hash = ERRFN(err_get)(0);
       
   494 	if (!hash)
       
   495 		return NULL;
       
   496 
       
   497 	CRYPTO_r_lock(CRYPTO_LOCK_ERR);
       
   498 	p = (ERR_STRING_DATA *)lh_retrieve(hash, d);
       
   499 	CRYPTO_r_unlock(CRYPTO_LOCK_ERR);
       
   500 
       
   501 	return p;
       
   502 	}
       
   503 
       
   504 static ERR_STRING_DATA *int_err_set_item(ERR_STRING_DATA *d)
       
   505 	{
       
   506 	ERR_STRING_DATA *p;
       
   507 	LHASH *hash;
       
   508 
       
   509 	err_fns_check();
       
   510 	hash = ERRFN(err_get)(1);
       
   511 	if (!hash)
       
   512 		return NULL;
       
   513 
       
   514 	CRYPTO_w_lock(CRYPTO_LOCK_ERR);
       
   515 	p = (ERR_STRING_DATA *)lh_insert(hash, d);
       
   516 	CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
       
   517 
       
   518 	return p;
       
   519 	}
       
   520 
       
   521 static ERR_STRING_DATA *int_err_del_item(ERR_STRING_DATA *d)
       
   522 	{
       
   523 	ERR_STRING_DATA *p;
       
   524 	LHASH *hash;
       
   525 
       
   526 	err_fns_check();
       
   527 	hash = ERRFN(err_get)(0);
       
   528 	if (!hash)
       
   529 		return NULL;
       
   530 
       
   531 	CRYPTO_w_lock(CRYPTO_LOCK_ERR);
       
   532 	p = (ERR_STRING_DATA *)lh_delete(hash, d);
       
   533 	CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
       
   534 
       
   535 	return p;
       
   536 	}
       
   537 
       
   538 static LHASH *int_thread_get(int create)
       
   539 	{
       
   540 	LHASH *ret = NULL;
       
   541 
       
   542 	CRYPTO_w_lock(CRYPTO_LOCK_ERR);
       
   543 	if (!int_thread_hash && create)
       
   544 		{
       
   545 		CRYPTO_push_info("int_thread_get (err.c)");
       
   546 		int_thread_hash = lh_new(pid_hash, pid_cmp);
       
   547 		CRYPTO_pop_info();
       
   548 		}
       
   549 	if (int_thread_hash)
       
   550 		{
       
   551 		int_thread_hash_references++;
       
   552 		ret = int_thread_hash;
       
   553 		}
       
   554 	CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
       
   555 	return ret;
       
   556 	}
       
   557 
       
   558 static void int_thread_release(LHASH **hash)
       
   559 	{
       
   560 	int i;
       
   561 
       
   562 	if (hash == NULL || *hash == NULL)
       
   563 		return;
       
   564 
       
   565 	i = CRYPTO_add(&int_thread_hash_references, -1, CRYPTO_LOCK_ERR);
       
   566 
       
   567 #ifdef REF_PRINT
       
   568 	fprintf(stderr,"%4d:%s\n",int_thread_hash_references,"ERR");
       
   569 #endif
       
   570 	if (i > 0) return;
       
   571 #ifdef REF_CHECK
       
   572 	if (i < 0)
       
   573 		{
       
   574 		fprintf(stderr,"int_thread_release, bad reference count\n");
       
   575 		abort(); /* ok */
       
   576 		}
       
   577 #endif
       
   578 	*hash = NULL;
       
   579 	}
       
   580 
       
   581 static ERR_STATE *int_thread_get_item(const ERR_STATE *d)
       
   582 	{
       
   583 	ERR_STATE *p;
       
   584 	LHASH *hash;
       
   585 
       
   586 	err_fns_check();
       
   587 	hash = ERRFN(thread_get)(0);
       
   588 	if (!hash)
       
   589 		return NULL;
       
   590 
       
   591 	CRYPTO_r_lock(CRYPTO_LOCK_ERR);
       
   592 	p = (ERR_STATE *)lh_retrieve(hash, d);
       
   593 	CRYPTO_r_unlock(CRYPTO_LOCK_ERR);
       
   594 
       
   595 	ERRFN(thread_release)(&hash);
       
   596 	return p;
       
   597 	}
       
   598 
       
   599 static ERR_STATE *int_thread_set_item(ERR_STATE *d)
       
   600 	{
       
   601 	ERR_STATE *p;
       
   602 	LHASH *hash;
       
   603 
       
   604 	err_fns_check();
       
   605 	hash = ERRFN(thread_get)(1);
       
   606 	if (!hash)
       
   607 		return NULL;
       
   608 
       
   609 	CRYPTO_w_lock(CRYPTO_LOCK_ERR);
       
   610 	p = (ERR_STATE *)lh_insert(hash, d);
       
   611 	CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
       
   612 
       
   613 	ERRFN(thread_release)(&hash);
       
   614 	return p;
       
   615 	}
       
   616 
       
   617 static void int_thread_del_item(const ERR_STATE *d)
       
   618 	{
       
   619 	ERR_STATE *p;
       
   620 	LHASH *hash;
       
   621 
       
   622 	err_fns_check();
       
   623 	hash = ERRFN(thread_get)(0);
       
   624 	if (!hash)
       
   625 		return;
       
   626 
       
   627 	CRYPTO_w_lock(CRYPTO_LOCK_ERR);
       
   628 	p = (ERR_STATE *)lh_delete(hash, d);
       
   629 	/* make sure we don't leak memory */
       
   630 	if (int_thread_hash_references == 1
       
   631 		&& int_thread_hash && (lh_num_items(int_thread_hash) == 0))
       
   632 		{
       
   633 		lh_free(int_thread_hash);
       
   634 		int_thread_hash = NULL;
       
   635 		}
       
   636 	CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
       
   637 
       
   638 	ERRFN(thread_release)(&hash);
       
   639 	if (p)
       
   640 		ERR_STATE_free(p);
       
   641 	}
       
   642 
       
   643 static int int_err_get_next_lib(void)
       
   644 	{
       
   645 	int ret;
       
   646 
       
   647 	CRYPTO_w_lock(CRYPTO_LOCK_ERR);
       
   648 	ret = int_err_library_number++;
       
   649 	CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
       
   650 
       
   651 	return ret;
       
   652 	}
       
   653 
       
   654 
       
   655 #ifndef OPENSSL_NO_ERR
       
   656 #define NUM_SYS_STR_REASONS 127
       
   657 #define LEN_SYS_STR_REASON 32
       
   658 
       
   659 #ifndef EMULATOR
       
   660 static ERR_STRING_DATA SYS_str_reasons[NUM_SYS_STR_REASONS + 1];
       
   661 #endif
       
   662 /* SYS_str_reasons is filled with copies of strerror() results at
       
   663  * initialization.
       
   664  * 'errno' values up to 127 should cover all usual errors,
       
   665  * others will be displayed numerically by ERR_error_string.
       
   666  * It is crucial that we have something for each reason code
       
   667  * that occurs in ERR_str_reasons, or bogus reason strings
       
   668  * will be returned for SYSerr(), which always gets an errno
       
   669  * value and never one of those 'standard' reason codes. */
       
   670 #ifdef EMULATOR
       
   671   GET_STATIC_VAR_FROM_TLS(init,err,int)
       
   672   #define init (*GET_WSD_VAR_NAME(init,err, s)())
       
   673   GET_STATIC_ARRAY_FROM_TLS(SYS_str_reasons,err,ERR_STRING_DATA)
       
   674   #define SYS_str_reasons (GET_WSD_VAR_NAME(SYS_str_reasons,err, s)())
       
   675   
       
   676   
       
   677   //GET_STATIC_ARRAY_FROM_TLS(&strerror_tab,err,char)
       
   678   #define strerror_tab libcrypto_ImpurePtr()->strerror_tab
       
   679 #endif 
       
   680 
       
   681 static void build_SYS_str_reasons(void)
       
   682 	{
       
   683 	/* OPENSSL_malloc cannot be used here, use static storage instead */
       
   684 #ifndef EMULATOR		
       
   685 	static char strerror_tab[NUM_SYS_STR_REASONS][LEN_SYS_STR_REASON];
       
   686 #endif	
       
   687 	int i;
       
   688 #ifndef EMULATOR	
       
   689 	static int init = 1;
       
   690 #endif	
       
   691 
       
   692 	CRYPTO_r_lock(CRYPTO_LOCK_ERR);
       
   693 	if (!init)
       
   694 		{
       
   695 		CRYPTO_r_unlock(CRYPTO_LOCK_ERR);
       
   696 		return;
       
   697 		}
       
   698 	
       
   699 	CRYPTO_r_unlock(CRYPTO_LOCK_ERR);
       
   700 	CRYPTO_w_lock(CRYPTO_LOCK_ERR);
       
   701 	if (!init)
       
   702 		{
       
   703 		CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
       
   704 		return;
       
   705 		}
       
   706 
       
   707 	for (i = 1; i <= NUM_SYS_STR_REASONS; i++)
       
   708 		{
       
   709 		ERR_STRING_DATA *str = &SYS_str_reasons[i - 1];
       
   710 
       
   711 		str->error = (unsigned long)i;
       
   712 		if (str->string == NULL)
       
   713 			{
       
   714 			char (*dest)[LEN_SYS_STR_REASON] = &(strerror_tab[i - 1]);
       
   715 			char *src = strerror(i);
       
   716 			if (src != NULL)
       
   717 				{
       
   718 				strncpy(*dest, src, sizeof *dest);
       
   719 				(*dest)[sizeof *dest - 1] = '\0';
       
   720 				str->string = *dest;
       
   721 				}
       
   722 			}
       
   723 		if (str->string == NULL)
       
   724 			str->string = "unknown";
       
   725 		}
       
   726 
       
   727 	/* Now we still have SYS_str_reasons[NUM_SYS_STR_REASONS] = {0, NULL},
       
   728 	 * as required by ERR_load_strings. */
       
   729 
       
   730 	init = 0;
       
   731 	
       
   732 	CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
       
   733 	}
       
   734 #endif
       
   735 
       
   736 #define err_clear_data(p,i) \
       
   737 	do { \
       
   738 	if (((p)->err_data[i] != NULL) && \
       
   739 		(p)->err_data_flags[i] & ERR_TXT_MALLOCED) \
       
   740 		{  \
       
   741 		OPENSSL_free((p)->err_data[i]); \
       
   742 		(p)->err_data[i]=NULL; \
       
   743 		} \
       
   744 	(p)->err_data_flags[i]=0; \
       
   745 	} while(0)
       
   746 
       
   747 #define err_clear(p,i) \
       
   748 	do { \
       
   749 	(p)->err_flags[i]=0; \
       
   750 	(p)->err_buffer[i]=0; \
       
   751 	err_clear_data(p,i); \
       
   752 	(p)->err_file[i]=NULL; \
       
   753 	(p)->err_line[i]= -1; \
       
   754 	} while(0)
       
   755 
       
   756 static void ERR_STATE_free(ERR_STATE *s)
       
   757 	{
       
   758 	int i;
       
   759 
       
   760 	if (s == NULL)
       
   761 	    return;
       
   762 
       
   763 	for (i=0; i<ERR_NUM_ERRORS; i++)
       
   764 		{
       
   765 		err_clear_data(s,i);
       
   766 		}
       
   767 	OPENSSL_free(s);
       
   768 	}
       
   769 
       
   770 EXPORT_C void ERR_load_ERR_strings(void)
       
   771 	{
       
   772 	err_fns_check();
       
   773 #ifndef OPENSSL_NO_ERR
       
   774 	err_load_strings(0,ERR_str_libraries);
       
   775 	err_load_strings(0,ERR_str_reasons);
       
   776 	err_load_strings(ERR_LIB_SYS,ERR_str_functs);
       
   777 	build_SYS_str_reasons();
       
   778 	err_load_strings(ERR_LIB_SYS,SYS_str_reasons);
       
   779 #endif
       
   780 	}
       
   781 
       
   782 static void err_load_strings(int lib, ERR_STRING_DATA *str)
       
   783 	{
       
   784 	while (str->error)
       
   785 		{
       
   786 		if (lib)
       
   787 			str->error|=ERR_PACK(lib,0,0);
       
   788 		ERRFN(err_set_item)(str);
       
   789 		str++;
       
   790 		}
       
   791 	}
       
   792 
       
   793 EXPORT_C void ERR_load_strings(int lib, ERR_STRING_DATA *str)
       
   794 	{
       
   795 	ERR_load_ERR_strings();
       
   796 	err_load_strings(lib, str);
       
   797 	}
       
   798 
       
   799 EXPORT_C void ERR_unload_strings(int lib, ERR_STRING_DATA *str)
       
   800 	{
       
   801 	while (str->error)
       
   802 		{
       
   803 		if (lib)
       
   804 			str->error|=ERR_PACK(lib,0,0);
       
   805 		ERRFN(err_del_item)(str);
       
   806 		str++;
       
   807 		}
       
   808 	}
       
   809 
       
   810 EXPORT_C void ERR_free_strings(void)
       
   811 	{
       
   812 	err_fns_check();
       
   813 	ERRFN(err_del)();
       
   814 	}
       
   815 
       
   816 /********************************************************/
       
   817 
       
   818 EXPORT_C void ERR_put_error(int lib, int func, int reason, const char *file,
       
   819 	     int line)
       
   820 	{
       
   821 	ERR_STATE *es;
       
   822 
       
   823 #ifdef _OSD_POSIX
       
   824 	/* In the BS2000-OSD POSIX subsystem, the compiler generates
       
   825 	 * path names in the form "*POSIX(/etc/passwd)".
       
   826 	 * This dirty hack strips them to something sensible.
       
   827 	 * @@@ We shouldn't modify a const string, though.
       
   828 	 */
       
   829 	if (strncmp(file,"*POSIX(", sizeof("*POSIX(")-1) == 0) {
       
   830 		char *end;
       
   831 
       
   832 		/* Skip the "*POSIX(" prefix */
       
   833 		file += sizeof("*POSIX(")-1;
       
   834 		end = &file[strlen(file)-1];
       
   835 		if (*end == ')')
       
   836 			*end = '\0';
       
   837 		/* Optional: use the basename of the path only. */
       
   838 		if ((end = strrchr(file, '/')) != NULL)
       
   839 			file = &end[1];
       
   840 	}
       
   841 #endif
       
   842 	es=ERR_get_state();
       
   843 
       
   844 	es->top=(es->top+1)%ERR_NUM_ERRORS;
       
   845 	if (es->top == es->bottom)
       
   846 		es->bottom=(es->bottom+1)%ERR_NUM_ERRORS;
       
   847 	es->err_flags[es->top]=0;
       
   848 	es->err_buffer[es->top]=ERR_PACK(lib,func,reason);
       
   849 	es->err_file[es->top]=file;
       
   850 	es->err_line[es->top]=line;
       
   851 	err_clear_data(es,es->top);
       
   852 	}
       
   853 
       
   854 EXPORT_C void ERR_clear_error(void)
       
   855 	{
       
   856 	int i;
       
   857 	ERR_STATE *es;
       
   858 
       
   859 	es=ERR_get_state();
       
   860 
       
   861 	for (i=0; i<ERR_NUM_ERRORS; i++)
       
   862 		{
       
   863 		err_clear(es,i);
       
   864 		}
       
   865 	es->top=es->bottom=0;
       
   866 	}
       
   867 
       
   868 
       
   869 EXPORT_C unsigned long ERR_get_error(void)
       
   870 	{ return(get_error_values(1,0,NULL,NULL,NULL,NULL)); }
       
   871 
       
   872 EXPORT_C unsigned long ERR_get_error_line(const char **file,
       
   873 	     int *line)
       
   874 	{ return(get_error_values(1,0,file,line,NULL,NULL)); }
       
   875 
       
   876 EXPORT_C unsigned long ERR_get_error_line_data(const char **file, int *line,
       
   877 	     const char **data, int *flags)
       
   878 	{ return(get_error_values(1,0,file,line,data,flags)); }
       
   879 
       
   880 
       
   881 EXPORT_C unsigned long ERR_peek_error(void)
       
   882 	{ return(get_error_values(0,0,NULL,NULL,NULL,NULL)); }
       
   883 
       
   884 EXPORT_C unsigned long ERR_peek_error_line(const char **file, int *line)
       
   885 	{ return(get_error_values(0,0,file,line,NULL,NULL)); }
       
   886 
       
   887 EXPORT_C unsigned long ERR_peek_error_line_data(const char **file, int *line,
       
   888 	     const char **data, int *flags)
       
   889 	{ return(get_error_values(0,0,file,line,data,flags)); }
       
   890 
       
   891 
       
   892 EXPORT_C unsigned long ERR_peek_last_error(void)
       
   893 	{ return(get_error_values(0,1,NULL,NULL,NULL,NULL)); }
       
   894 
       
   895 EXPORT_C unsigned long ERR_peek_last_error_line(const char **file, int *line)
       
   896 	{ return(get_error_values(0,1,file,line,NULL,NULL)); }
       
   897 
       
   898 EXPORT_C unsigned long ERR_peek_last_error_line_data(const char **file, int *line,
       
   899 	     const char **data, int *flags)
       
   900 	{ return(get_error_values(0,1,file,line,data,flags)); }
       
   901 
       
   902 
       
   903 static unsigned long get_error_values(int inc, int top, const char **file, int *line,
       
   904 	     const char **data, int *flags)
       
   905 	{	
       
   906 	int i=0;
       
   907 	ERR_STATE *es;
       
   908 	unsigned long ret;
       
   909 
       
   910 	es=ERR_get_state();
       
   911 
       
   912 	if (inc && top)
       
   913 		{
       
   914 		if (file) *file = "";
       
   915 		if (line) *line = 0;
       
   916 		if (data) *data = "";
       
   917 		if (flags) *flags = 0;
       
   918 			
       
   919 		return ERR_R_INTERNAL_ERROR;
       
   920 		}
       
   921 
       
   922 	if (es->bottom == es->top) return 0;
       
   923 	if (top)
       
   924 		i=es->top;			 /* last error */
       
   925 	else
       
   926 		i=(es->bottom+1)%ERR_NUM_ERRORS; /* first error */
       
   927 
       
   928 	ret=es->err_buffer[i];
       
   929 	if (inc)
       
   930 		{
       
   931 		es->bottom=i;
       
   932 		es->err_buffer[i]=0;
       
   933 		}
       
   934 
       
   935 	if ((file != NULL) && (line != NULL))
       
   936 		{
       
   937 		if (es->err_file[i] == NULL)
       
   938 			{
       
   939 			*file="NA";
       
   940 			if (line != NULL) *line=0;
       
   941 			}
       
   942 		else
       
   943 			{
       
   944 			*file=es->err_file[i];
       
   945 			if (line != NULL) *line=es->err_line[i];
       
   946 			}
       
   947 		}
       
   948 
       
   949 	if (data == NULL)
       
   950 		{
       
   951 		if (inc)
       
   952 			{
       
   953 			err_clear_data(es, i);
       
   954 			}
       
   955 		}
       
   956 	else
       
   957 		{
       
   958 		if (es->err_data[i] == NULL)
       
   959 			{
       
   960 			*data="";
       
   961 			if (flags != NULL) *flags=0;
       
   962 			}
       
   963 		else
       
   964 			{
       
   965 			*data=es->err_data[i];
       
   966 			if (flags != NULL) *flags=es->err_data_flags[i];
       
   967 			}
       
   968 		}
       
   969 	return ret;
       
   970 	}
       
   971 
       
   972 EXPORT_C void ERR_error_string_n(unsigned long e, char *buf, size_t len)
       
   973 	{
       
   974 	char lsbuf[64], fsbuf[64], rsbuf[64];
       
   975 	const char *ls,*fs,*rs;
       
   976 	unsigned long l,f,r;
       
   977 
       
   978 	l=ERR_GET_LIB(e);
       
   979 	f=ERR_GET_FUNC(e);
       
   980 	r=ERR_GET_REASON(e);
       
   981 
       
   982 	ls=ERR_lib_error_string(e);
       
   983 	fs=ERR_func_error_string(e);
       
   984 	rs=ERR_reason_error_string(e);
       
   985 
       
   986 	if (ls == NULL) 
       
   987 		BIO_snprintf(lsbuf, sizeof(lsbuf), "lib(%lu)", l);
       
   988 	if (fs == NULL)
       
   989 		BIO_snprintf(fsbuf, sizeof(fsbuf), "func(%lu)", f);
       
   990 	if (rs == NULL)
       
   991 		BIO_snprintf(rsbuf, sizeof(rsbuf), "reason(%lu)", r);
       
   992 
       
   993 	BIO_snprintf(buf, len,"error:%08lX:%s:%s:%s", e, ls?ls:lsbuf, 
       
   994 		fs?fs:fsbuf, rs?rs:rsbuf);
       
   995 	if (strlen(buf) == len-1)
       
   996 		{
       
   997 		/* output may be truncated; make sure we always have 5 
       
   998 		 * colon-separated fields, i.e. 4 colons ... */
       
   999 #define NUM_COLONS 4
       
  1000 		if (len > NUM_COLONS) /* ... if possible */
       
  1001 			{
       
  1002 			int i;
       
  1003 			char *s = buf;
       
  1004 			
       
  1005 			for (i = 0; i < NUM_COLONS; i++)
       
  1006 				{
       
  1007 				char *colon = strchr(s, ':');
       
  1008 				if (colon == NULL || colon > &buf[len-1] - NUM_COLONS + i)
       
  1009 					{
       
  1010 					/* set colon no. i at last possible position
       
  1011 					 * (buf[len-1] is the terminating 0)*/
       
  1012 					colon = &buf[len-1] - NUM_COLONS + i;
       
  1013 					*colon = ':';
       
  1014 					}
       
  1015 				s = colon + 1;
       
  1016 				}
       
  1017 			}
       
  1018 		}
       
  1019 	}
       
  1020 
       
  1021 #ifdef EMULATOR	
       
  1022 GET_STATIC_ARRAY_FROM_TLS(buf,err,char)
       
  1023 #define buf (GET_WSD_VAR_NAME(buf,err, s)())
       
  1024 #endif	
       
  1025 
       
  1026 /* BAD for multi-threading: uses a local buffer if ret == NULL */
       
  1027 /* ERR_error_string_n should be used instead for ret != NULL
       
  1028  * as ERR_error_string cannot know how large the buffer is */
       
  1029 EXPORT_C char *ERR_error_string(unsigned long e, char *ret)
       
  1030 	{
       
  1031 #ifndef EMULATOR	
       
  1032 	static char buf[256];
       
  1033 #endif	
       
  1034 
       
  1035 	if (ret == NULL) ret=buf;
       
  1036 	ERR_error_string_n(e, ret, 256);
       
  1037 
       
  1038 	return ret;
       
  1039 	}
       
  1040 
       
  1041 EXPORT_C LHASH *ERR_get_string_table(void)
       
  1042 	{
       
  1043 	err_fns_check();
       
  1044 	return ERRFN(err_get)(0);
       
  1045 	}
       
  1046 
       
  1047 EXPORT_C LHASH *ERR_get_err_state_table(void)
       
  1048 	{
       
  1049 	err_fns_check();
       
  1050 	return ERRFN(thread_get)(0);
       
  1051 	}
       
  1052 
       
  1053 EXPORT_C void ERR_release_err_state_table(LHASH **hash)
       
  1054 	{
       
  1055 	err_fns_check();
       
  1056 	ERRFN(thread_release)(hash);
       
  1057 	}
       
  1058 
       
  1059 EXPORT_C const char *ERR_lib_error_string(unsigned long e)
       
  1060 	{
       
  1061 	ERR_STRING_DATA d,*p;
       
  1062 	unsigned long l;
       
  1063 
       
  1064 	err_fns_check();
       
  1065 	l=ERR_GET_LIB(e);
       
  1066 	d.error=ERR_PACK(l,0,0);
       
  1067 	p=ERRFN(err_get_item)(&d);
       
  1068 	return((p == NULL)?NULL:p->string);
       
  1069 	}
       
  1070 
       
  1071 EXPORT_C const char *ERR_func_error_string(unsigned long e)
       
  1072 	{
       
  1073 	ERR_STRING_DATA d,*p;
       
  1074 	unsigned long l,f;
       
  1075 
       
  1076 	err_fns_check();
       
  1077 	l=ERR_GET_LIB(e);
       
  1078 	f=ERR_GET_FUNC(e);
       
  1079 	d.error=ERR_PACK(l,f,0);
       
  1080 	p=ERRFN(err_get_item)(&d);
       
  1081 	return((p == NULL)?NULL:p->string);
       
  1082 	}
       
  1083 
       
  1084 EXPORT_C const char *ERR_reason_error_string(unsigned long e)
       
  1085 	{
       
  1086 	ERR_STRING_DATA d,*p=NULL;
       
  1087 	unsigned long l,r;
       
  1088 
       
  1089 	err_fns_check();
       
  1090 	l=ERR_GET_LIB(e);
       
  1091 	r=ERR_GET_REASON(e);
       
  1092 	d.error=ERR_PACK(l,0,r);
       
  1093 	p=ERRFN(err_get_item)(&d);
       
  1094 	if (!p)
       
  1095 		{
       
  1096 		d.error=ERR_PACK(0,0,r);
       
  1097 		p=ERRFN(err_get_item)(&d);
       
  1098 		}
       
  1099 	return((p == NULL)?NULL:p->string);
       
  1100 	}
       
  1101 
       
  1102 /* static unsigned long err_hash(ERR_STRING_DATA *a) */
       
  1103 static unsigned long err_hash(const void *a_void)
       
  1104 	{
       
  1105 	unsigned long ret,l;
       
  1106 
       
  1107 	l=((const ERR_STRING_DATA *)a_void)->error;
       
  1108 	ret=l^ERR_GET_LIB(l)^ERR_GET_FUNC(l);
       
  1109 	return(ret^ret%19*13);
       
  1110 	}
       
  1111 
       
  1112 /* static int err_cmp(ERR_STRING_DATA *a, ERR_STRING_DATA *b) */
       
  1113 static int err_cmp(const void *a_void, const void *b_void)
       
  1114 	{
       
  1115 	return((int)(((const ERR_STRING_DATA *)a_void)->error -
       
  1116 			((const ERR_STRING_DATA *)b_void)->error));
       
  1117 	}
       
  1118 
       
  1119 /* static unsigned long pid_hash(ERR_STATE *a) */
       
  1120 static unsigned long pid_hash(const void *a_void)
       
  1121 	{
       
  1122 	return(((const ERR_STATE *)a_void)->pid*13);
       
  1123 	}
       
  1124 
       
  1125 /* static int pid_cmp(ERR_STATE *a, ERR_STATE *b) */
       
  1126 static int pid_cmp(const void *a_void, const void *b_void)
       
  1127 	{
       
  1128 	return((int)((long)((const ERR_STATE *)a_void)->pid -
       
  1129 			(long)((const ERR_STATE *)b_void)->pid));
       
  1130 	}
       
  1131 
       
  1132 EXPORT_C void ERR_remove_state(unsigned long pid)
       
  1133 	{
       
  1134 	ERR_STATE tmp;
       
  1135 
       
  1136 	err_fns_check();
       
  1137 	if (pid == 0)
       
  1138 		pid=(unsigned long)CRYPTO_thread_id();
       
  1139 	tmp.pid=pid;
       
  1140 	/* thread_del_item automatically destroys the LHASH if the number of
       
  1141 	 * items reaches zero. */
       
  1142 	ERRFN(thread_del_item)(&tmp);
       
  1143 	}
       
  1144 #ifdef EMULATOR
       
  1145 GET_STATIC_VAR_FROM_TLS(fallback,err,ERR_STATE)
       
  1146 #define fallback (*GET_WSD_VAR_NAME(fallback,err, s)())
       
  1147 #endif
       
  1148 EXPORT_C ERR_STATE *ERR_get_state(void)
       
  1149 	{
       
  1150 #ifndef EMULATOR	
       
  1151 	static ERR_STATE fallback;
       
  1152 #endif	
       
  1153 	ERR_STATE *ret,tmp,*tmpp=NULL;
       
  1154 	int i;
       
  1155 	unsigned long pid;
       
  1156 
       
  1157 	err_fns_check();
       
  1158 	pid=(unsigned long)CRYPTO_thread_id();
       
  1159 	tmp.pid=pid;
       
  1160 	ret=ERRFN(thread_get_item)(&tmp);
       
  1161 
       
  1162 	/* ret == the error state, if NULL, make a new one */
       
  1163 	if (ret == NULL)
       
  1164 		{
       
  1165 		ret=(ERR_STATE *)OPENSSL_malloc(sizeof(ERR_STATE));
       
  1166 		if (ret == NULL) return(&fallback);
       
  1167 		ret->pid=pid;
       
  1168 		ret->top=0;
       
  1169 		ret->bottom=0;
       
  1170 		for (i=0; i<ERR_NUM_ERRORS; i++)
       
  1171 			{
       
  1172 			ret->err_data[i]=NULL;
       
  1173 			ret->err_data_flags[i]=0;
       
  1174 			}
       
  1175 		tmpp = ERRFN(thread_set_item)(ret);
       
  1176 		/* To check if insertion failed, do a get. */
       
  1177 		if (ERRFN(thread_get_item)(ret) != ret)
       
  1178 			{
       
  1179 			ERR_STATE_free(ret); /* could not insert it */
       
  1180 			return(&fallback);
       
  1181 			}
       
  1182 		/* If a race occured in this function and we came second, tmpp
       
  1183 		 * is the first one that we just replaced. */
       
  1184 		if (tmpp)
       
  1185 			ERR_STATE_free(tmpp);
       
  1186 		}
       
  1187 	return ret;
       
  1188 	}
       
  1189 
       
  1190 EXPORT_C int ERR_get_next_error_library(void)
       
  1191 	{
       
  1192 	err_fns_check();
       
  1193 	return ERRFN(get_next_lib)();
       
  1194 	}
       
  1195 
       
  1196 EXPORT_C void ERR_set_error_data(char *data, int flags)
       
  1197 	{
       
  1198 	ERR_STATE *es;
       
  1199 	int i;
       
  1200 
       
  1201 	es=ERR_get_state();
       
  1202 
       
  1203 	i=es->top;
       
  1204 	if (i == 0)
       
  1205 		i=ERR_NUM_ERRORS-1;
       
  1206 
       
  1207 	err_clear_data(es,i);
       
  1208 	es->err_data[i]=data;
       
  1209 	es->err_data_flags[i]=flags;
       
  1210 	}
       
  1211 
       
  1212 EXPORT_C void ERR_add_error_data(int num, ...)
       
  1213 	{
       
  1214 	va_list args;
       
  1215 	int i,n,s;
       
  1216 	char *str,*p,*a;
       
  1217 
       
  1218 	s=80;
       
  1219 	str=OPENSSL_malloc(s+1);
       
  1220 	if (str == NULL) return;
       
  1221 	str[0]='\0';
       
  1222 
       
  1223 	va_start(args, num);
       
  1224 	n=0;
       
  1225 	for (i=0; i<num; i++)
       
  1226 		{
       
  1227 		a=va_arg(args, char*);
       
  1228 		/* ignore NULLs, thanks to Bob Beck <beck@obtuse.com> */
       
  1229 		if (a != NULL)
       
  1230 			{
       
  1231 			n+=strlen(a);
       
  1232 			if (n > s)
       
  1233 				{
       
  1234 				s=n+20;
       
  1235 				p=OPENSSL_realloc(str,s+1);
       
  1236 				if (p == NULL)
       
  1237 					{
       
  1238 					OPENSSL_free(str);
       
  1239 					goto err;
       
  1240 					}
       
  1241 				else
       
  1242 					str=p;
       
  1243 				}
       
  1244 			BUF_strlcat(str,a,(size_t)s+1);
       
  1245 			}
       
  1246 		}
       
  1247 	ERR_set_error_data(str,ERR_TXT_MALLOCED|ERR_TXT_STRING);
       
  1248 
       
  1249 err:
       
  1250 	va_end(args);
       
  1251 	}
       
  1252 
       
  1253 EXPORT_C int ERR_set_mark(void)
       
  1254 	{
       
  1255 	ERR_STATE *es;
       
  1256 
       
  1257 	es=ERR_get_state();
       
  1258 
       
  1259 	if (es->bottom == es->top) return 0;
       
  1260 	es->err_flags[es->top]|=ERR_FLAG_MARK;
       
  1261 	return 1;
       
  1262 	}
       
  1263 
       
  1264 EXPORT_C int ERR_pop_to_mark(void)
       
  1265 	{
       
  1266 	ERR_STATE *es;
       
  1267 
       
  1268 	es=ERR_get_state();
       
  1269 
       
  1270 	while(es->bottom != es->top
       
  1271 		&& (es->err_flags[es->top] & ERR_FLAG_MARK) == 0)
       
  1272 		{
       
  1273 		err_clear(es,es->top);
       
  1274 		es->top-=1;
       
  1275 		if (es->top == -1) es->top=ERR_NUM_ERRORS;
       
  1276 		}
       
  1277 		
       
  1278 	if (es->bottom == es->top) return 0;
       
  1279 	es->err_flags[es->top]&=~ERR_FLAG_MARK;
       
  1280 	return 1;
       
  1281 	}