1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/ossrv/ssl/libcrypto/src/crypto/err/err.c Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,1281 @@
1.4 +/* crypto/err/err.c */
1.5 +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
1.6 + * All rights reserved.
1.7 + *
1.8 + * This package is an SSL implementation written
1.9 + * by Eric Young (eay@cryptsoft.com).
1.10 + * The implementation was written so as to conform with Netscapes SSL.
1.11 + *
1.12 + * This library is free for commercial and non-commercial use as long as
1.13 + * the following conditions are aheared to. The following conditions
1.14 + * apply to all code found in this distribution, be it the RC4, RSA,
1.15 + * lhash, DES, etc., code; not just the SSL code. The SSL documentation
1.16 + * included with this distribution is covered by the same copyright terms
1.17 + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
1.18 + *
1.19 + * Copyright remains Eric Young's, and as such any Copyright notices in
1.20 + * the code are not to be removed.
1.21 + * If this package is used in a product, Eric Young should be given attribution
1.22 + * as the author of the parts of the library used.
1.23 + * This can be in the form of a textual message at program startup or
1.24 + * in documentation (online or textual) provided with the package.
1.25 + *
1.26 + * Redistribution and use in source and binary forms, with or without
1.27 + * modification, are permitted provided that the following conditions
1.28 + * are met:
1.29 + * 1. Redistributions of source code must retain the copyright
1.30 + * notice, this list of conditions and the following disclaimer.
1.31 + * 2. Redistributions in binary form must reproduce the above copyright
1.32 + * notice, this list of conditions and the following disclaimer in the
1.33 + * documentation and/or other materials provided with the distribution.
1.34 + * 3. All advertising materials mentioning features or use of this software
1.35 + * must display the following acknowledgement:
1.36 + * "This product includes cryptographic software written by
1.37 + * Eric Young (eay@cryptsoft.com)"
1.38 + * The word 'cryptographic' can be left out if the rouines from the library
1.39 + * being used are not cryptographic related :-).
1.40 + * 4. If you include any Windows specific code (or a derivative thereof) from
1.41 + * the apps directory (application code) you must include an acknowledgement:
1.42 + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
1.43 + *
1.44 + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
1.45 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1.46 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1.47 + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1.48 + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1.49 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
1.50 + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1.51 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
1.52 + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
1.53 + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
1.54 + * SUCH DAMAGE.
1.55 + *
1.56 + * The licence and distribution terms for any publically available version or
1.57 + * derivative of this code cannot be changed. i.e. this code cannot simply be
1.58 + * copied and put under another distribution licence
1.59 + * [including the GNU Public Licence.]
1.60 + */
1.61 +/* ====================================================================
1.62 + * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved.
1.63 + *
1.64 + * Redistribution and use in source and binary forms, with or without
1.65 + * modification, are permitted provided that the following conditions
1.66 + * are met:
1.67 + *
1.68 + * 1. Redistributions of source code must retain the above copyright
1.69 + * notice, this list of conditions and the following disclaimer.
1.70 + *
1.71 + * 2. Redistributions in binary form must reproduce the above copyright
1.72 + * notice, this list of conditions and the following disclaimer in
1.73 + * the documentation and/or other materials provided with the
1.74 + * distribution.
1.75 + *
1.76 + * 3. All advertising materials mentioning features or use of this
1.77 + * software must display the following acknowledgment:
1.78 + * "This product includes software developed by the OpenSSL Project
1.79 + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
1.80 + *
1.81 + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
1.82 + * endorse or promote products derived from this software without
1.83 + * prior written permission. For written permission, please contact
1.84 + * openssl-core@openssl.org.
1.85 + *
1.86 + * 5. Products derived from this software may not be called "OpenSSL"
1.87 + * nor may "OpenSSL" appear in their names without prior written
1.88 + * permission of the OpenSSL Project.
1.89 + *
1.90 + * 6. Redistributions of any form whatsoever must retain the following
1.91 + * acknowledgment:
1.92 + * "This product includes software developed by the OpenSSL Project
1.93 + * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
1.94 + *
1.95 + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
1.96 + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1.97 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
1.98 + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
1.99 + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
1.100 + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
1.101 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
1.102 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1.103 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
1.104 + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
1.105 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
1.106 + * OF THE POSSIBILITY OF SUCH DAMAGE.
1.107 + * ====================================================================
1.108 + *
1.109 + * This product includes cryptographic software written by Eric Young
1.110 + * (eay@cryptsoft.com). This product includes software written by Tim
1.111 + * Hudson (tjh@cryptsoft.com).
1.112 + *
1.113 + */
1.114 + /*
1.115 + © Portions copyright (c) 2006 Nokia Corporation. All rights reserved.
1.116 + */
1.117 +
1.118 +
1.119 +#include <stdio.h>
1.120 +#include <stdarg.h>
1.121 +#include <string.h>
1.122 +#include "cryptlib.h"
1.123 +#include <openssl/lhash.h>
1.124 +#include <openssl/crypto.h>
1.125 +#include <openssl/buffer.h>
1.126 +#include <openssl/bio.h>
1.127 +#include <openssl/err.h>
1.128 +#if (defined(SYMBIAN) && (defined(__WINSCW__) || defined(__WINS__)))
1.129 +#include "libcrypto_wsd_macros.h"
1.130 +#include "libcrypto_wsd.h"
1.131 +#endif
1.132 +
1.133 +static void err_load_strings(int lib, ERR_STRING_DATA *str);
1.134 +static void ERR_STATE_free(ERR_STATE *s);
1.135 +#ifndef OPENSSL_NO_ERR
1.136 +#ifndef EMULATOR
1.137 +static ERR_STRING_DATA ERR_str_libraries[]=
1.138 + {
1.139 +{ERR_PACK(ERR_LIB_NONE,0,0) ,"unknown library"},
1.140 +{ERR_PACK(ERR_LIB_SYS,0,0) ,"system library"},
1.141 +{ERR_PACK(ERR_LIB_BN,0,0) ,"bignum routines"},
1.142 +{ERR_PACK(ERR_LIB_RSA,0,0) ,"rsa routines"},
1.143 +{ERR_PACK(ERR_LIB_DH,0,0) ,"Diffie-Hellman routines"},
1.144 +{ERR_PACK(ERR_LIB_EVP,0,0) ,"digital envelope routines"},
1.145 +{ERR_PACK(ERR_LIB_BUF,0,0) ,"memory buffer routines"},
1.146 +{ERR_PACK(ERR_LIB_OBJ,0,0) ,"object identifier routines"},
1.147 +{ERR_PACK(ERR_LIB_PEM,0,0) ,"PEM routines"},
1.148 +{ERR_PACK(ERR_LIB_DSA,0,0) ,"dsa routines"},
1.149 +{ERR_PACK(ERR_LIB_X509,0,0) ,"x509 certificate routines"},
1.150 +{ERR_PACK(ERR_LIB_ASN1,0,0) ,"asn1 encoding routines"},
1.151 +{ERR_PACK(ERR_LIB_CONF,0,0) ,"configuration file routines"},
1.152 +{ERR_PACK(ERR_LIB_CRYPTO,0,0) ,"common libcrypto routines"},
1.153 +{ERR_PACK(ERR_LIB_EC,0,0) ,"elliptic curve routines"},
1.154 +{ERR_PACK(ERR_LIB_SSL,0,0) ,"SSL routines"},
1.155 +{ERR_PACK(ERR_LIB_BIO,0,0) ,"BIO routines"},
1.156 +{ERR_PACK(ERR_LIB_PKCS7,0,0) ,"PKCS7 routines"},
1.157 +{ERR_PACK(ERR_LIB_X509V3,0,0) ,"X509 V3 routines"},
1.158 +{ERR_PACK(ERR_LIB_PKCS12,0,0) ,"PKCS12 routines"},
1.159 +{ERR_PACK(ERR_LIB_RAND,0,0) ,"random number generator"},
1.160 +{ERR_PACK(ERR_LIB_DSO,0,0) ,"DSO support routines"},
1.161 +{ERR_PACK(ERR_LIB_ENGINE,0,0) ,"engine routines"},
1.162 +{ERR_PACK(ERR_LIB_OCSP,0,0) ,"OCSP routines"},
1.163 +{0,NULL},
1.164 + };
1.165 +
1.166 +static ERR_STRING_DATA ERR_str_functs[]=
1.167 + {
1.168 + {ERR_PACK(0,SYS_F_FOPEN,0), "fopen"},
1.169 + {ERR_PACK(0,SYS_F_CONNECT,0), "connect"},
1.170 + {ERR_PACK(0,SYS_F_GETSERVBYNAME,0), "getservbyname"},
1.171 + {ERR_PACK(0,SYS_F_SOCKET,0), "socket"},
1.172 + {ERR_PACK(0,SYS_F_IOCTLSOCKET,0), "ioctlsocket"},
1.173 + {ERR_PACK(0,SYS_F_BIND,0), "bind"},
1.174 + {ERR_PACK(0,SYS_F_LISTEN,0), "listen"},
1.175 + {ERR_PACK(0,SYS_F_ACCEPT,0), "accept"},
1.176 +#ifdef OPENSSL_SYS_WINDOWS
1.177 + {ERR_PACK(0,SYS_F_WSASTARTUP,0), "WSAstartup"},
1.178 +#endif
1.179 + {ERR_PACK(0,SYS_F_OPENDIR,0), "opendir"},
1.180 + {ERR_PACK(0,SYS_F_FREAD,0), "fread"},
1.181 + {0,NULL},
1.182 + };
1.183 +
1.184 +static ERR_STRING_DATA ERR_str_reasons[]=
1.185 + {
1.186 +{ERR_R_SYS_LIB ,"system lib"},
1.187 +{ERR_R_BN_LIB ,"BN lib"},
1.188 +{ERR_R_RSA_LIB ,"RSA lib"},
1.189 +{ERR_R_DH_LIB ,"DH lib"},
1.190 +{ERR_R_EVP_LIB ,"EVP lib"},
1.191 +{ERR_R_BUF_LIB ,"BUF lib"},
1.192 +{ERR_R_OBJ_LIB ,"OBJ lib"},
1.193 +{ERR_R_PEM_LIB ,"PEM lib"},
1.194 +{ERR_R_DSA_LIB ,"DSA lib"},
1.195 +{ERR_R_X509_LIB ,"X509 lib"},
1.196 +{ERR_R_ASN1_LIB ,"ASN1 lib"},
1.197 +{ERR_R_CONF_LIB ,"CONF lib"},
1.198 +{ERR_R_CRYPTO_LIB ,"CRYPTO lib"},
1.199 +{ERR_R_EC_LIB ,"EC lib"},
1.200 +{ERR_R_SSL_LIB ,"SSL lib"},
1.201 +{ERR_R_BIO_LIB ,"BIO lib"},
1.202 +{ERR_R_PKCS7_LIB ,"PKCS7 lib"},
1.203 +{ERR_R_X509V3_LIB ,"X509V3 lib"},
1.204 +{ERR_R_PKCS12_LIB ,"PKCS12 lib"},
1.205 +{ERR_R_RAND_LIB ,"RAND lib"},
1.206 +{ERR_R_DSO_LIB ,"DSO lib"},
1.207 +{ERR_R_ENGINE_LIB ,"ENGINE lib"},
1.208 +{ERR_R_OCSP_LIB ,"OCSP lib"},
1.209 +
1.210 +{ERR_R_NESTED_ASN1_ERROR ,"nested asn1 error"},
1.211 +{ERR_R_BAD_ASN1_OBJECT_HEADER ,"bad asn1 object header"},
1.212 +{ERR_R_BAD_GET_ASN1_OBJECT_CALL ,"bad get asn1 object call"},
1.213 +{ERR_R_EXPECTING_AN_ASN1_SEQUENCE ,"expecting an asn1 sequence"},
1.214 +{ERR_R_ASN1_LENGTH_MISMATCH ,"asn1 length mismatch"},
1.215 +{ERR_R_MISSING_ASN1_EOS ,"missing asn1 eos"},
1.216 +
1.217 +{ERR_R_FATAL ,"fatal"},
1.218 +{ERR_R_MALLOC_FAILURE ,"malloc failure"},
1.219 +{ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED ,"called a function you should not call"},
1.220 +{ERR_R_PASSED_NULL_PARAMETER ,"passed a null parameter"},
1.221 +{ERR_R_INTERNAL_ERROR ,"internal error"},
1.222 +{ERR_R_DISABLED ,"called a function that was disabled at compile-time"},
1.223 +
1.224 +{0,NULL},
1.225 + };
1.226 +#else //EMULATOR
1.227 +const ERR_STRING_DATA temp_ERR_str_libraries[]=
1.228 + {
1.229 +{ERR_PACK(ERR_LIB_NONE,0,0) ,"unknown library"},
1.230 +{ERR_PACK(ERR_LIB_SYS,0,0) ,"system library"},
1.231 +{ERR_PACK(ERR_LIB_BN,0,0) ,"bignum routines"},
1.232 +{ERR_PACK(ERR_LIB_RSA,0,0) ,"rsa routines"},
1.233 +{ERR_PACK(ERR_LIB_DH,0,0) ,"Diffie-Hellman routines"},
1.234 +{ERR_PACK(ERR_LIB_EVP,0,0) ,"digital envelope routines"},
1.235 +{ERR_PACK(ERR_LIB_BUF,0,0) ,"memory buffer routines"},
1.236 +{ERR_PACK(ERR_LIB_OBJ,0,0) ,"object identifier routines"},
1.237 +{ERR_PACK(ERR_LIB_PEM,0,0) ,"PEM routines"},
1.238 +{ERR_PACK(ERR_LIB_DSA,0,0) ,"dsa routines"},
1.239 +{ERR_PACK(ERR_LIB_X509,0,0) ,"x509 certificate routines"},
1.240 +{ERR_PACK(ERR_LIB_ASN1,0,0) ,"asn1 encoding routines"},
1.241 +{ERR_PACK(ERR_LIB_CONF,0,0) ,"configuration file routines"},
1.242 +{ERR_PACK(ERR_LIB_CRYPTO,0,0) ,"common libcrypto routines"},
1.243 +{ERR_PACK(ERR_LIB_EC,0,0) ,"elliptic curve routines"},
1.244 +{ERR_PACK(ERR_LIB_SSL,0,0) ,"SSL routines"},
1.245 +{ERR_PACK(ERR_LIB_BIO,0,0) ,"BIO routines"},
1.246 +{ERR_PACK(ERR_LIB_PKCS7,0,0) ,"PKCS7 routines"},
1.247 +{ERR_PACK(ERR_LIB_X509V3,0,0) ,"X509 V3 routines"},
1.248 +{ERR_PACK(ERR_LIB_PKCS12,0,0) ,"PKCS12 routines"},
1.249 +{ERR_PACK(ERR_LIB_RAND,0,0) ,"random number generator"},
1.250 +{ERR_PACK(ERR_LIB_DSO,0,0) ,"DSO support routines"},
1.251 +{ERR_PACK(ERR_LIB_ENGINE,0,0) ,"engine routines"},
1.252 +{ERR_PACK(ERR_LIB_OCSP,0,0) ,"OCSP routines"},
1.253 +{0,NULL},
1.254 + };
1.255 +
1.256 +const ERR_STRING_DATA temp_ERR_str_functs[]=
1.257 + {
1.258 + {ERR_PACK(0,SYS_F_FOPEN,0), "fopen"},
1.259 + {ERR_PACK(0,SYS_F_CONNECT,0), "connect"},
1.260 + {ERR_PACK(0,SYS_F_GETSERVBYNAME,0), "getservbyname"},
1.261 + {ERR_PACK(0,SYS_F_SOCKET,0), "socket"},
1.262 + {ERR_PACK(0,SYS_F_IOCTLSOCKET,0), "ioctlsocket"},
1.263 + {ERR_PACK(0,SYS_F_BIND,0), "bind"},
1.264 + {ERR_PACK(0,SYS_F_LISTEN,0), "listen"},
1.265 + {ERR_PACK(0,SYS_F_ACCEPT,0), "accept"},
1.266 +#ifdef OPENSSL_SYS_WINDOWS
1.267 + {ERR_PACK(0,SYS_F_WSASTARTUP,0), "WSAstartup"},
1.268 +#endif
1.269 + {ERR_PACK(0,SYS_F_OPENDIR,0), "opendir"},
1.270 + {ERR_PACK(0,SYS_F_FREAD,0), "fread"},
1.271 + {0,NULL},
1.272 + };
1.273 +
1.274 +const ERR_STRING_DATA temp_ERR_str_reasons[]=
1.275 + {
1.276 +{ERR_R_SYS_LIB ,"system lib"},
1.277 +{ERR_R_BN_LIB ,"BN lib"},
1.278 +{ERR_R_RSA_LIB ,"RSA lib"},
1.279 +{ERR_R_DH_LIB ,"DH lib"},
1.280 +{ERR_R_EVP_LIB ,"EVP lib"},
1.281 +{ERR_R_BUF_LIB ,"BUF lib"},
1.282 +{ERR_R_OBJ_LIB ,"OBJ lib"},
1.283 +{ERR_R_PEM_LIB ,"PEM lib"},
1.284 +{ERR_R_DSA_LIB ,"DSA lib"},
1.285 +{ERR_R_X509_LIB ,"X509 lib"},
1.286 +{ERR_R_ASN1_LIB ,"ASN1 lib"},
1.287 +{ERR_R_CONF_LIB ,"CONF lib"},
1.288 +{ERR_R_CRYPTO_LIB ,"CRYPTO lib"},
1.289 +{ERR_R_EC_LIB ,"EC lib"},
1.290 +{ERR_R_SSL_LIB ,"SSL lib"},
1.291 +{ERR_R_BIO_LIB ,"BIO lib"},
1.292 +{ERR_R_PKCS7_LIB ,"PKCS7 lib"},
1.293 +{ERR_R_X509V3_LIB ,"X509V3 lib"},
1.294 +{ERR_R_PKCS12_LIB ,"PKCS12 lib"},
1.295 +{ERR_R_RAND_LIB ,"RAND lib"},
1.296 +{ERR_R_DSO_LIB ,"DSO lib"},
1.297 +{ERR_R_ENGINE_LIB ,"ENGINE lib"},
1.298 +{ERR_R_OCSP_LIB ,"OCSP lib"},
1.299 +
1.300 +{ERR_R_NESTED_ASN1_ERROR ,"nested asn1 error"},
1.301 +{ERR_R_BAD_ASN1_OBJECT_HEADER ,"bad asn1 object header"},
1.302 +{ERR_R_BAD_GET_ASN1_OBJECT_CALL ,"bad get asn1 object call"},
1.303 +{ERR_R_EXPECTING_AN_ASN1_SEQUENCE ,"expecting an asn1 sequence"},
1.304 +{ERR_R_ASN1_LENGTH_MISMATCH ,"asn1 length mismatch"},
1.305 +{ERR_R_MISSING_ASN1_EOS ,"missing asn1 eos"},
1.306 +
1.307 +{ERR_R_FATAL ,"fatal"},
1.308 +{ERR_R_MALLOC_FAILURE ,"malloc failure"},
1.309 +{ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED ,"called a function you should not call"},
1.310 +{ERR_R_PASSED_NULL_PARAMETER ,"passed a null parameter"},
1.311 +{ERR_R_INTERNAL_ERROR ,"internal error"},
1.312 +{ERR_R_DISABLED ,"called a function that was disabled at compile-time"},
1.313 +
1.314 +{0,NULL},
1.315 + };
1.316 + GET_STATIC_ARRAY_FROM_TLS(ERR_str_functs,err_err,ERR_STRING_DATA)
1.317 + GET_STATIC_ARRAY_FROM_TLS(ERR_str_reasons,err_err,ERR_STRING_DATA)
1.318 + GET_STATIC_ARRAY_FROM_TLS(ERR_str_libraries,err_err,ERR_STRING_DATA)
1.319 + #define ERR_str_functs (GET_WSD_VAR_NAME(ERR_str_functs,err_err, s)())
1.320 + #define ERR_str_reasons (GET_WSD_VAR_NAME(ERR_str_reasons,err_err, s)())
1.321 + #define ERR_str_libraries (GET_WSD_VAR_NAME(ERR_str_libraries,err_err, s)())
1.322 +#endif //EMULATOR
1.323 +#endif
1.324 +
1.325 +#ifndef EMULATOR
1.326 +/* Define the predeclared (but externally opaque) "ERR_FNS" type */
1.327 +struct st_ERR_FNS
1.328 + {
1.329 + /* Works on the "error_hash" string table */
1.330 + LHASH *(*cb_err_get)(int create);
1.331 + void (*cb_err_del)(void);
1.332 + ERR_STRING_DATA *(*cb_err_get_item)(const ERR_STRING_DATA *);
1.333 + ERR_STRING_DATA *(*cb_err_set_item)(ERR_STRING_DATA *);
1.334 + ERR_STRING_DATA *(*cb_err_del_item)(ERR_STRING_DATA *);
1.335 + /* Works on the "thread_hash" error-state table */
1.336 + LHASH *(*cb_thread_get)(int create);
1.337 + void (*cb_thread_release)(LHASH **hash);
1.338 + ERR_STATE *(*cb_thread_get_item)(const ERR_STATE *);
1.339 + ERR_STATE *(*cb_thread_set_item)(ERR_STATE *);
1.340 + void (*cb_thread_del_item)(const ERR_STATE *);
1.341 + /* Returns the next available error "library" numbers */
1.342 + int (*cb_get_next_lib)(void);
1.343 + };
1.344 +#endif
1.345 +/* Predeclarations of the "err_defaults" functions */
1.346 +static LHASH *int_err_get(int create);
1.347 +static void int_err_del(void);
1.348 +static ERR_STRING_DATA *int_err_get_item(const ERR_STRING_DATA *);
1.349 +static ERR_STRING_DATA *int_err_set_item(ERR_STRING_DATA *);
1.350 +static ERR_STRING_DATA *int_err_del_item(ERR_STRING_DATA *);
1.351 +static LHASH *int_thread_get(int create);
1.352 +static void int_thread_release(LHASH **hash);
1.353 +static ERR_STATE *int_thread_get_item(const ERR_STATE *);
1.354 +static ERR_STATE *int_thread_set_item(ERR_STATE *);
1.355 +static void int_thread_del_item(const ERR_STATE *);
1.356 +static int int_err_get_next_lib(void);
1.357 +/* The static ERR_FNS table using these defaults functions */
1.358 +static const ERR_FNS err_defaults =
1.359 + {
1.360 + int_err_get,
1.361 + int_err_del,
1.362 + int_err_get_item,
1.363 + int_err_set_item,
1.364 + int_err_del_item,
1.365 + int_thread_get,
1.366 + int_thread_release,
1.367 + int_thread_get_item,
1.368 + int_thread_set_item,
1.369 + int_thread_del_item,
1.370 + int_err_get_next_lib
1.371 + };
1.372 +
1.373 +#ifndef EMULATOR
1.374 +/* The replacable table of ERR_FNS functions we use at run-time */
1.375 +static const ERR_FNS *err_fns = NULL;
1.376 +#else
1.377 +GET_STATIC_VAR_FROM_TLS(err_fns,err,const ERR_FNS *)
1.378 +#define err_fns (*GET_WSD_VAR_NAME(err_fns,err, s)())
1.379 +#endif
1.380 +
1.381 +/* Eg. rather than using "err_get()", use "ERRFN(err_get)()". */
1.382 +#define ERRFN(a) err_fns->cb_##a
1.383 +
1.384 +#ifndef EMULATOR
1.385 +/* The internal state used by "err_defaults" - as such, the setting, reading,
1.386 + * creating, and deleting of this data should only be permitted via the
1.387 + * "err_defaults" functions. This way, a linked module can completely defer all
1.388 + * ERR state operation (together with requisite locking) to the implementations
1.389 + * and state in the loading application. */
1.390 +static LHASH *int_error_hash = NULL;
1.391 +static LHASH *int_thread_hash = NULL;
1.392 +static int int_thread_hash_references = 0;
1.393 +static int int_err_library_number= ERR_LIB_USER;
1.394 +#else
1.395 +GET_STATIC_VAR_FROM_TLS(int_error_hash,err,LHASH *)
1.396 +#define int_error_hash (*GET_WSD_VAR_NAME(int_error_hash,err,s)())
1.397 +
1.398 +GET_STATIC_VAR_FROM_TLS(int_thread_hash,err,LHASH *)
1.399 +#define int_thread_hash (*GET_WSD_VAR_NAME(int_thread_hash,err,s)())
1.400 +
1.401 +GET_STATIC_VAR_FROM_TLS(int_thread_hash_references,err,int)
1.402 +#define int_thread_hash_references (*GET_WSD_VAR_NAME(int_thread_hash_references,err,s)())
1.403 +
1.404 +GET_STATIC_VAR_FROM_TLS(int_err_library_number,err,int)
1.405 +#define int_err_library_number (*GET_WSD_VAR_NAME(int_err_library_number,err,s)())
1.406 +
1.407 +#endif
1.408 +
1.409 +/* Internal function that checks whether "err_fns" is set and if not, sets it to
1.410 + * the defaults. */
1.411 +static void err_fns_check(void)
1.412 + {
1.413 + if (err_fns) return;
1.414 +
1.415 + CRYPTO_w_lock(CRYPTO_LOCK_ERR);
1.416 + if (!err_fns)
1.417 + err_fns = &err_defaults;
1.418 + CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
1.419 + }
1.420 +
1.421 +/* API functions to get or set the underlying ERR functions. */
1.422 +
1.423 +EXPORT_C const ERR_FNS *ERR_get_implementation(void)
1.424 + {
1.425 + err_fns_check();
1.426 + return err_fns;
1.427 + }
1.428 +
1.429 +EXPORT_C int ERR_set_implementation(const ERR_FNS *fns)
1.430 + {
1.431 + int ret = 0;
1.432 +
1.433 + CRYPTO_w_lock(CRYPTO_LOCK_ERR);
1.434 + /* It's too late if 'err_fns' is non-NULL. BTW: not much point setting
1.435 + * an error is there?! */
1.436 + if (!err_fns)
1.437 + {
1.438 + err_fns = fns;
1.439 + ret = 1;
1.440 + }
1.441 + CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
1.442 + return ret;
1.443 + }
1.444 +
1.445 +/* These are the callbacks provided to "lh_new()" when creating the LHASH tables
1.446 + * internal to the "err_defaults" implementation. */
1.447 +
1.448 +/* static unsigned long err_hash(ERR_STRING_DATA *a); */
1.449 +static unsigned long err_hash(const void *a_void);
1.450 +/* static int err_cmp(ERR_STRING_DATA *a, ERR_STRING_DATA *b); */
1.451 +static int err_cmp(const void *a_void, const void *b_void);
1.452 +/* static unsigned long pid_hash(ERR_STATE *pid); */
1.453 +static unsigned long pid_hash(const void *pid_void);
1.454 +/* static int pid_cmp(ERR_STATE *a,ERR_STATE *pid); */
1.455 +static int pid_cmp(const void *a_void,const void *pid_void);
1.456 +static unsigned long get_error_values(int inc,int top,const char **file,int *line,
1.457 + const char **data,int *flags);
1.458 +
1.459 +/* The internal functions used in the "err_defaults" implementation */
1.460 +
1.461 +static LHASH *int_err_get(int create)
1.462 + {
1.463 + LHASH *ret = NULL;
1.464 +
1.465 + CRYPTO_w_lock(CRYPTO_LOCK_ERR);
1.466 + if (!int_error_hash && create)
1.467 + {
1.468 + CRYPTO_push_info("int_err_get (err.c)");
1.469 + int_error_hash = lh_new(err_hash, err_cmp);
1.470 + CRYPTO_pop_info();
1.471 + }
1.472 + if (int_error_hash)
1.473 + ret = int_error_hash;
1.474 + CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
1.475 +
1.476 + return ret;
1.477 + }
1.478 +
1.479 +static void int_err_del(void)
1.480 + {
1.481 + CRYPTO_w_lock(CRYPTO_LOCK_ERR);
1.482 + if (int_error_hash)
1.483 + {
1.484 + lh_free(int_error_hash);
1.485 + int_error_hash = NULL;
1.486 + }
1.487 + CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
1.488 + }
1.489 +
1.490 +static ERR_STRING_DATA *int_err_get_item(const ERR_STRING_DATA *d)
1.491 + {
1.492 + ERR_STRING_DATA *p;
1.493 + LHASH *hash;
1.494 +
1.495 + err_fns_check();
1.496 + hash = ERRFN(err_get)(0);
1.497 + if (!hash)
1.498 + return NULL;
1.499 +
1.500 + CRYPTO_r_lock(CRYPTO_LOCK_ERR);
1.501 + p = (ERR_STRING_DATA *)lh_retrieve(hash, d);
1.502 + CRYPTO_r_unlock(CRYPTO_LOCK_ERR);
1.503 +
1.504 + return p;
1.505 + }
1.506 +
1.507 +static ERR_STRING_DATA *int_err_set_item(ERR_STRING_DATA *d)
1.508 + {
1.509 + ERR_STRING_DATA *p;
1.510 + LHASH *hash;
1.511 +
1.512 + err_fns_check();
1.513 + hash = ERRFN(err_get)(1);
1.514 + if (!hash)
1.515 + return NULL;
1.516 +
1.517 + CRYPTO_w_lock(CRYPTO_LOCK_ERR);
1.518 + p = (ERR_STRING_DATA *)lh_insert(hash, d);
1.519 + CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
1.520 +
1.521 + return p;
1.522 + }
1.523 +
1.524 +static ERR_STRING_DATA *int_err_del_item(ERR_STRING_DATA *d)
1.525 + {
1.526 + ERR_STRING_DATA *p;
1.527 + LHASH *hash;
1.528 +
1.529 + err_fns_check();
1.530 + hash = ERRFN(err_get)(0);
1.531 + if (!hash)
1.532 + return NULL;
1.533 +
1.534 + CRYPTO_w_lock(CRYPTO_LOCK_ERR);
1.535 + p = (ERR_STRING_DATA *)lh_delete(hash, d);
1.536 + CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
1.537 +
1.538 + return p;
1.539 + }
1.540 +
1.541 +static LHASH *int_thread_get(int create)
1.542 + {
1.543 + LHASH *ret = NULL;
1.544 +
1.545 + CRYPTO_w_lock(CRYPTO_LOCK_ERR);
1.546 + if (!int_thread_hash && create)
1.547 + {
1.548 + CRYPTO_push_info("int_thread_get (err.c)");
1.549 + int_thread_hash = lh_new(pid_hash, pid_cmp);
1.550 + CRYPTO_pop_info();
1.551 + }
1.552 + if (int_thread_hash)
1.553 + {
1.554 + int_thread_hash_references++;
1.555 + ret = int_thread_hash;
1.556 + }
1.557 + CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
1.558 + return ret;
1.559 + }
1.560 +
1.561 +static void int_thread_release(LHASH **hash)
1.562 + {
1.563 + int i;
1.564 +
1.565 + if (hash == NULL || *hash == NULL)
1.566 + return;
1.567 +
1.568 + i = CRYPTO_add(&int_thread_hash_references, -1, CRYPTO_LOCK_ERR);
1.569 +
1.570 +#ifdef REF_PRINT
1.571 + fprintf(stderr,"%4d:%s\n",int_thread_hash_references,"ERR");
1.572 +#endif
1.573 + if (i > 0) return;
1.574 +#ifdef REF_CHECK
1.575 + if (i < 0)
1.576 + {
1.577 + fprintf(stderr,"int_thread_release, bad reference count\n");
1.578 + abort(); /* ok */
1.579 + }
1.580 +#endif
1.581 + *hash = NULL;
1.582 + }
1.583 +
1.584 +static ERR_STATE *int_thread_get_item(const ERR_STATE *d)
1.585 + {
1.586 + ERR_STATE *p;
1.587 + LHASH *hash;
1.588 +
1.589 + err_fns_check();
1.590 + hash = ERRFN(thread_get)(0);
1.591 + if (!hash)
1.592 + return NULL;
1.593 +
1.594 + CRYPTO_r_lock(CRYPTO_LOCK_ERR);
1.595 + p = (ERR_STATE *)lh_retrieve(hash, d);
1.596 + CRYPTO_r_unlock(CRYPTO_LOCK_ERR);
1.597 +
1.598 + ERRFN(thread_release)(&hash);
1.599 + return p;
1.600 + }
1.601 +
1.602 +static ERR_STATE *int_thread_set_item(ERR_STATE *d)
1.603 + {
1.604 + ERR_STATE *p;
1.605 + LHASH *hash;
1.606 +
1.607 + err_fns_check();
1.608 + hash = ERRFN(thread_get)(1);
1.609 + if (!hash)
1.610 + return NULL;
1.611 +
1.612 + CRYPTO_w_lock(CRYPTO_LOCK_ERR);
1.613 + p = (ERR_STATE *)lh_insert(hash, d);
1.614 + CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
1.615 +
1.616 + ERRFN(thread_release)(&hash);
1.617 + return p;
1.618 + }
1.619 +
1.620 +static void int_thread_del_item(const ERR_STATE *d)
1.621 + {
1.622 + ERR_STATE *p;
1.623 + LHASH *hash;
1.624 +
1.625 + err_fns_check();
1.626 + hash = ERRFN(thread_get)(0);
1.627 + if (!hash)
1.628 + return;
1.629 +
1.630 + CRYPTO_w_lock(CRYPTO_LOCK_ERR);
1.631 + p = (ERR_STATE *)lh_delete(hash, d);
1.632 + /* make sure we don't leak memory */
1.633 + if (int_thread_hash_references == 1
1.634 + && int_thread_hash && (lh_num_items(int_thread_hash) == 0))
1.635 + {
1.636 + lh_free(int_thread_hash);
1.637 + int_thread_hash = NULL;
1.638 + }
1.639 + CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
1.640 +
1.641 + ERRFN(thread_release)(&hash);
1.642 + if (p)
1.643 + ERR_STATE_free(p);
1.644 + }
1.645 +
1.646 +static int int_err_get_next_lib(void)
1.647 + {
1.648 + int ret;
1.649 +
1.650 + CRYPTO_w_lock(CRYPTO_LOCK_ERR);
1.651 + ret = int_err_library_number++;
1.652 + CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
1.653 +
1.654 + return ret;
1.655 + }
1.656 +
1.657 +
1.658 +#ifndef OPENSSL_NO_ERR
1.659 +#define NUM_SYS_STR_REASONS 127
1.660 +#define LEN_SYS_STR_REASON 32
1.661 +
1.662 +#ifndef EMULATOR
1.663 +static ERR_STRING_DATA SYS_str_reasons[NUM_SYS_STR_REASONS + 1];
1.664 +#endif
1.665 +/* SYS_str_reasons is filled with copies of strerror() results at
1.666 + * initialization.
1.667 + * 'errno' values up to 127 should cover all usual errors,
1.668 + * others will be displayed numerically by ERR_error_string.
1.669 + * It is crucial that we have something for each reason code
1.670 + * that occurs in ERR_str_reasons, or bogus reason strings
1.671 + * will be returned for SYSerr(), which always gets an errno
1.672 + * value and never one of those 'standard' reason codes. */
1.673 +#ifdef EMULATOR
1.674 + GET_STATIC_VAR_FROM_TLS(init,err,int)
1.675 + #define init (*GET_WSD_VAR_NAME(init,err, s)())
1.676 + GET_STATIC_ARRAY_FROM_TLS(SYS_str_reasons,err,ERR_STRING_DATA)
1.677 + #define SYS_str_reasons (GET_WSD_VAR_NAME(SYS_str_reasons,err, s)())
1.678 +
1.679 +
1.680 + //GET_STATIC_ARRAY_FROM_TLS(&strerror_tab,err,char)
1.681 + #define strerror_tab libcrypto_ImpurePtr()->strerror_tab
1.682 +#endif
1.683 +
1.684 +static void build_SYS_str_reasons(void)
1.685 + {
1.686 + /* OPENSSL_malloc cannot be used here, use static storage instead */
1.687 +#ifndef EMULATOR
1.688 + static char strerror_tab[NUM_SYS_STR_REASONS][LEN_SYS_STR_REASON];
1.689 +#endif
1.690 + int i;
1.691 +#ifndef EMULATOR
1.692 + static int init = 1;
1.693 +#endif
1.694 +
1.695 + CRYPTO_r_lock(CRYPTO_LOCK_ERR);
1.696 + if (!init)
1.697 + {
1.698 + CRYPTO_r_unlock(CRYPTO_LOCK_ERR);
1.699 + return;
1.700 + }
1.701 +
1.702 + CRYPTO_r_unlock(CRYPTO_LOCK_ERR);
1.703 + CRYPTO_w_lock(CRYPTO_LOCK_ERR);
1.704 + if (!init)
1.705 + {
1.706 + CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
1.707 + return;
1.708 + }
1.709 +
1.710 + for (i = 1; i <= NUM_SYS_STR_REASONS; i++)
1.711 + {
1.712 + ERR_STRING_DATA *str = &SYS_str_reasons[i - 1];
1.713 +
1.714 + str->error = (unsigned long)i;
1.715 + if (str->string == NULL)
1.716 + {
1.717 + char (*dest)[LEN_SYS_STR_REASON] = &(strerror_tab[i - 1]);
1.718 + char *src = strerror(i);
1.719 + if (src != NULL)
1.720 + {
1.721 + strncpy(*dest, src, sizeof *dest);
1.722 + (*dest)[sizeof *dest - 1] = '\0';
1.723 + str->string = *dest;
1.724 + }
1.725 + }
1.726 + if (str->string == NULL)
1.727 + str->string = "unknown";
1.728 + }
1.729 +
1.730 + /* Now we still have SYS_str_reasons[NUM_SYS_STR_REASONS] = {0, NULL},
1.731 + * as required by ERR_load_strings. */
1.732 +
1.733 + init = 0;
1.734 +
1.735 + CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
1.736 + }
1.737 +#endif
1.738 +
1.739 +#define err_clear_data(p,i) \
1.740 + do { \
1.741 + if (((p)->err_data[i] != NULL) && \
1.742 + (p)->err_data_flags[i] & ERR_TXT_MALLOCED) \
1.743 + { \
1.744 + OPENSSL_free((p)->err_data[i]); \
1.745 + (p)->err_data[i]=NULL; \
1.746 + } \
1.747 + (p)->err_data_flags[i]=0; \
1.748 + } while(0)
1.749 +
1.750 +#define err_clear(p,i) \
1.751 + do { \
1.752 + (p)->err_flags[i]=0; \
1.753 + (p)->err_buffer[i]=0; \
1.754 + err_clear_data(p,i); \
1.755 + (p)->err_file[i]=NULL; \
1.756 + (p)->err_line[i]= -1; \
1.757 + } while(0)
1.758 +
1.759 +static void ERR_STATE_free(ERR_STATE *s)
1.760 + {
1.761 + int i;
1.762 +
1.763 + if (s == NULL)
1.764 + return;
1.765 +
1.766 + for (i=0; i<ERR_NUM_ERRORS; i++)
1.767 + {
1.768 + err_clear_data(s,i);
1.769 + }
1.770 + OPENSSL_free(s);
1.771 + }
1.772 +
1.773 +EXPORT_C void ERR_load_ERR_strings(void)
1.774 + {
1.775 + err_fns_check();
1.776 +#ifndef OPENSSL_NO_ERR
1.777 + err_load_strings(0,ERR_str_libraries);
1.778 + err_load_strings(0,ERR_str_reasons);
1.779 + err_load_strings(ERR_LIB_SYS,ERR_str_functs);
1.780 + build_SYS_str_reasons();
1.781 + err_load_strings(ERR_LIB_SYS,SYS_str_reasons);
1.782 +#endif
1.783 + }
1.784 +
1.785 +static void err_load_strings(int lib, ERR_STRING_DATA *str)
1.786 + {
1.787 + while (str->error)
1.788 + {
1.789 + if (lib)
1.790 + str->error|=ERR_PACK(lib,0,0);
1.791 + ERRFN(err_set_item)(str);
1.792 + str++;
1.793 + }
1.794 + }
1.795 +
1.796 +EXPORT_C void ERR_load_strings(int lib, ERR_STRING_DATA *str)
1.797 + {
1.798 + ERR_load_ERR_strings();
1.799 + err_load_strings(lib, str);
1.800 + }
1.801 +
1.802 +EXPORT_C void ERR_unload_strings(int lib, ERR_STRING_DATA *str)
1.803 + {
1.804 + while (str->error)
1.805 + {
1.806 + if (lib)
1.807 + str->error|=ERR_PACK(lib,0,0);
1.808 + ERRFN(err_del_item)(str);
1.809 + str++;
1.810 + }
1.811 + }
1.812 +
1.813 +EXPORT_C void ERR_free_strings(void)
1.814 + {
1.815 + err_fns_check();
1.816 + ERRFN(err_del)();
1.817 + }
1.818 +
1.819 +/********************************************************/
1.820 +
1.821 +EXPORT_C void ERR_put_error(int lib, int func, int reason, const char *file,
1.822 + int line)
1.823 + {
1.824 + ERR_STATE *es;
1.825 +
1.826 +#ifdef _OSD_POSIX
1.827 + /* In the BS2000-OSD POSIX subsystem, the compiler generates
1.828 + * path names in the form "*POSIX(/etc/passwd)".
1.829 + * This dirty hack strips them to something sensible.
1.830 + * @@@ We shouldn't modify a const string, though.
1.831 + */
1.832 + if (strncmp(file,"*POSIX(", sizeof("*POSIX(")-1) == 0) {
1.833 + char *end;
1.834 +
1.835 + /* Skip the "*POSIX(" prefix */
1.836 + file += sizeof("*POSIX(")-1;
1.837 + end = &file[strlen(file)-1];
1.838 + if (*end == ')')
1.839 + *end = '\0';
1.840 + /* Optional: use the basename of the path only. */
1.841 + if ((end = strrchr(file, '/')) != NULL)
1.842 + file = &end[1];
1.843 + }
1.844 +#endif
1.845 + es=ERR_get_state();
1.846 +
1.847 + es->top=(es->top+1)%ERR_NUM_ERRORS;
1.848 + if (es->top == es->bottom)
1.849 + es->bottom=(es->bottom+1)%ERR_NUM_ERRORS;
1.850 + es->err_flags[es->top]=0;
1.851 + es->err_buffer[es->top]=ERR_PACK(lib,func,reason);
1.852 + es->err_file[es->top]=file;
1.853 + es->err_line[es->top]=line;
1.854 + err_clear_data(es,es->top);
1.855 + }
1.856 +
1.857 +EXPORT_C void ERR_clear_error(void)
1.858 + {
1.859 + int i;
1.860 + ERR_STATE *es;
1.861 +
1.862 + es=ERR_get_state();
1.863 +
1.864 + for (i=0; i<ERR_NUM_ERRORS; i++)
1.865 + {
1.866 + err_clear(es,i);
1.867 + }
1.868 + es->top=es->bottom=0;
1.869 + }
1.870 +
1.871 +
1.872 +EXPORT_C unsigned long ERR_get_error(void)
1.873 + { return(get_error_values(1,0,NULL,NULL,NULL,NULL)); }
1.874 +
1.875 +EXPORT_C unsigned long ERR_get_error_line(const char **file,
1.876 + int *line)
1.877 + { return(get_error_values(1,0,file,line,NULL,NULL)); }
1.878 +
1.879 +EXPORT_C unsigned long ERR_get_error_line_data(const char **file, int *line,
1.880 + const char **data, int *flags)
1.881 + { return(get_error_values(1,0,file,line,data,flags)); }
1.882 +
1.883 +
1.884 +EXPORT_C unsigned long ERR_peek_error(void)
1.885 + { return(get_error_values(0,0,NULL,NULL,NULL,NULL)); }
1.886 +
1.887 +EXPORT_C unsigned long ERR_peek_error_line(const char **file, int *line)
1.888 + { return(get_error_values(0,0,file,line,NULL,NULL)); }
1.889 +
1.890 +EXPORT_C unsigned long ERR_peek_error_line_data(const char **file, int *line,
1.891 + const char **data, int *flags)
1.892 + { return(get_error_values(0,0,file,line,data,flags)); }
1.893 +
1.894 +
1.895 +EXPORT_C unsigned long ERR_peek_last_error(void)
1.896 + { return(get_error_values(0,1,NULL,NULL,NULL,NULL)); }
1.897 +
1.898 +EXPORT_C unsigned long ERR_peek_last_error_line(const char **file, int *line)
1.899 + { return(get_error_values(0,1,file,line,NULL,NULL)); }
1.900 +
1.901 +EXPORT_C unsigned long ERR_peek_last_error_line_data(const char **file, int *line,
1.902 + const char **data, int *flags)
1.903 + { return(get_error_values(0,1,file,line,data,flags)); }
1.904 +
1.905 +
1.906 +static unsigned long get_error_values(int inc, int top, const char **file, int *line,
1.907 + const char **data, int *flags)
1.908 + {
1.909 + int i=0;
1.910 + ERR_STATE *es;
1.911 + unsigned long ret;
1.912 +
1.913 + es=ERR_get_state();
1.914 +
1.915 + if (inc && top)
1.916 + {
1.917 + if (file) *file = "";
1.918 + if (line) *line = 0;
1.919 + if (data) *data = "";
1.920 + if (flags) *flags = 0;
1.921 +
1.922 + return ERR_R_INTERNAL_ERROR;
1.923 + }
1.924 +
1.925 + if (es->bottom == es->top) return 0;
1.926 + if (top)
1.927 + i=es->top; /* last error */
1.928 + else
1.929 + i=(es->bottom+1)%ERR_NUM_ERRORS; /* first error */
1.930 +
1.931 + ret=es->err_buffer[i];
1.932 + if (inc)
1.933 + {
1.934 + es->bottom=i;
1.935 + es->err_buffer[i]=0;
1.936 + }
1.937 +
1.938 + if ((file != NULL) && (line != NULL))
1.939 + {
1.940 + if (es->err_file[i] == NULL)
1.941 + {
1.942 + *file="NA";
1.943 + if (line != NULL) *line=0;
1.944 + }
1.945 + else
1.946 + {
1.947 + *file=es->err_file[i];
1.948 + if (line != NULL) *line=es->err_line[i];
1.949 + }
1.950 + }
1.951 +
1.952 + if (data == NULL)
1.953 + {
1.954 + if (inc)
1.955 + {
1.956 + err_clear_data(es, i);
1.957 + }
1.958 + }
1.959 + else
1.960 + {
1.961 + if (es->err_data[i] == NULL)
1.962 + {
1.963 + *data="";
1.964 + if (flags != NULL) *flags=0;
1.965 + }
1.966 + else
1.967 + {
1.968 + *data=es->err_data[i];
1.969 + if (flags != NULL) *flags=es->err_data_flags[i];
1.970 + }
1.971 + }
1.972 + return ret;
1.973 + }
1.974 +
1.975 +EXPORT_C void ERR_error_string_n(unsigned long e, char *buf, size_t len)
1.976 + {
1.977 + char lsbuf[64], fsbuf[64], rsbuf[64];
1.978 + const char *ls,*fs,*rs;
1.979 + unsigned long l,f,r;
1.980 +
1.981 + l=ERR_GET_LIB(e);
1.982 + f=ERR_GET_FUNC(e);
1.983 + r=ERR_GET_REASON(e);
1.984 +
1.985 + ls=ERR_lib_error_string(e);
1.986 + fs=ERR_func_error_string(e);
1.987 + rs=ERR_reason_error_string(e);
1.988 +
1.989 + if (ls == NULL)
1.990 + BIO_snprintf(lsbuf, sizeof(lsbuf), "lib(%lu)", l);
1.991 + if (fs == NULL)
1.992 + BIO_snprintf(fsbuf, sizeof(fsbuf), "func(%lu)", f);
1.993 + if (rs == NULL)
1.994 + BIO_snprintf(rsbuf, sizeof(rsbuf), "reason(%lu)", r);
1.995 +
1.996 + BIO_snprintf(buf, len,"error:%08lX:%s:%s:%s", e, ls?ls:lsbuf,
1.997 + fs?fs:fsbuf, rs?rs:rsbuf);
1.998 + if (strlen(buf) == len-1)
1.999 + {
1.1000 + /* output may be truncated; make sure we always have 5
1.1001 + * colon-separated fields, i.e. 4 colons ... */
1.1002 +#define NUM_COLONS 4
1.1003 + if (len > NUM_COLONS) /* ... if possible */
1.1004 + {
1.1005 + int i;
1.1006 + char *s = buf;
1.1007 +
1.1008 + for (i = 0; i < NUM_COLONS; i++)
1.1009 + {
1.1010 + char *colon = strchr(s, ':');
1.1011 + if (colon == NULL || colon > &buf[len-1] - NUM_COLONS + i)
1.1012 + {
1.1013 + /* set colon no. i at last possible position
1.1014 + * (buf[len-1] is the terminating 0)*/
1.1015 + colon = &buf[len-1] - NUM_COLONS + i;
1.1016 + *colon = ':';
1.1017 + }
1.1018 + s = colon + 1;
1.1019 + }
1.1020 + }
1.1021 + }
1.1022 + }
1.1023 +
1.1024 +#ifdef EMULATOR
1.1025 +GET_STATIC_ARRAY_FROM_TLS(buf,err,char)
1.1026 +#define buf (GET_WSD_VAR_NAME(buf,err, s)())
1.1027 +#endif
1.1028 +
1.1029 +/* BAD for multi-threading: uses a local buffer if ret == NULL */
1.1030 +/* ERR_error_string_n should be used instead for ret != NULL
1.1031 + * as ERR_error_string cannot know how large the buffer is */
1.1032 +EXPORT_C char *ERR_error_string(unsigned long e, char *ret)
1.1033 + {
1.1034 +#ifndef EMULATOR
1.1035 + static char buf[256];
1.1036 +#endif
1.1037 +
1.1038 + if (ret == NULL) ret=buf;
1.1039 + ERR_error_string_n(e, ret, 256);
1.1040 +
1.1041 + return ret;
1.1042 + }
1.1043 +
1.1044 +EXPORT_C LHASH *ERR_get_string_table(void)
1.1045 + {
1.1046 + err_fns_check();
1.1047 + return ERRFN(err_get)(0);
1.1048 + }
1.1049 +
1.1050 +EXPORT_C LHASH *ERR_get_err_state_table(void)
1.1051 + {
1.1052 + err_fns_check();
1.1053 + return ERRFN(thread_get)(0);
1.1054 + }
1.1055 +
1.1056 +EXPORT_C void ERR_release_err_state_table(LHASH **hash)
1.1057 + {
1.1058 + err_fns_check();
1.1059 + ERRFN(thread_release)(hash);
1.1060 + }
1.1061 +
1.1062 +EXPORT_C const char *ERR_lib_error_string(unsigned long e)
1.1063 + {
1.1064 + ERR_STRING_DATA d,*p;
1.1065 + unsigned long l;
1.1066 +
1.1067 + err_fns_check();
1.1068 + l=ERR_GET_LIB(e);
1.1069 + d.error=ERR_PACK(l,0,0);
1.1070 + p=ERRFN(err_get_item)(&d);
1.1071 + return((p == NULL)?NULL:p->string);
1.1072 + }
1.1073 +
1.1074 +EXPORT_C const char *ERR_func_error_string(unsigned long e)
1.1075 + {
1.1076 + ERR_STRING_DATA d,*p;
1.1077 + unsigned long l,f;
1.1078 +
1.1079 + err_fns_check();
1.1080 + l=ERR_GET_LIB(e);
1.1081 + f=ERR_GET_FUNC(e);
1.1082 + d.error=ERR_PACK(l,f,0);
1.1083 + p=ERRFN(err_get_item)(&d);
1.1084 + return((p == NULL)?NULL:p->string);
1.1085 + }
1.1086 +
1.1087 +EXPORT_C const char *ERR_reason_error_string(unsigned long e)
1.1088 + {
1.1089 + ERR_STRING_DATA d,*p=NULL;
1.1090 + unsigned long l,r;
1.1091 +
1.1092 + err_fns_check();
1.1093 + l=ERR_GET_LIB(e);
1.1094 + r=ERR_GET_REASON(e);
1.1095 + d.error=ERR_PACK(l,0,r);
1.1096 + p=ERRFN(err_get_item)(&d);
1.1097 + if (!p)
1.1098 + {
1.1099 + d.error=ERR_PACK(0,0,r);
1.1100 + p=ERRFN(err_get_item)(&d);
1.1101 + }
1.1102 + return((p == NULL)?NULL:p->string);
1.1103 + }
1.1104 +
1.1105 +/* static unsigned long err_hash(ERR_STRING_DATA *a) */
1.1106 +static unsigned long err_hash(const void *a_void)
1.1107 + {
1.1108 + unsigned long ret,l;
1.1109 +
1.1110 + l=((const ERR_STRING_DATA *)a_void)->error;
1.1111 + ret=l^ERR_GET_LIB(l)^ERR_GET_FUNC(l);
1.1112 + return(ret^ret%19*13);
1.1113 + }
1.1114 +
1.1115 +/* static int err_cmp(ERR_STRING_DATA *a, ERR_STRING_DATA *b) */
1.1116 +static int err_cmp(const void *a_void, const void *b_void)
1.1117 + {
1.1118 + return((int)(((const ERR_STRING_DATA *)a_void)->error -
1.1119 + ((const ERR_STRING_DATA *)b_void)->error));
1.1120 + }
1.1121 +
1.1122 +/* static unsigned long pid_hash(ERR_STATE *a) */
1.1123 +static unsigned long pid_hash(const void *a_void)
1.1124 + {
1.1125 + return(((const ERR_STATE *)a_void)->pid*13);
1.1126 + }
1.1127 +
1.1128 +/* static int pid_cmp(ERR_STATE *a, ERR_STATE *b) */
1.1129 +static int pid_cmp(const void *a_void, const void *b_void)
1.1130 + {
1.1131 + return((int)((long)((const ERR_STATE *)a_void)->pid -
1.1132 + (long)((const ERR_STATE *)b_void)->pid));
1.1133 + }
1.1134 +
1.1135 +EXPORT_C void ERR_remove_state(unsigned long pid)
1.1136 + {
1.1137 + ERR_STATE tmp;
1.1138 +
1.1139 + err_fns_check();
1.1140 + if (pid == 0)
1.1141 + pid=(unsigned long)CRYPTO_thread_id();
1.1142 + tmp.pid=pid;
1.1143 + /* thread_del_item automatically destroys the LHASH if the number of
1.1144 + * items reaches zero. */
1.1145 + ERRFN(thread_del_item)(&tmp);
1.1146 + }
1.1147 +#ifdef EMULATOR
1.1148 +GET_STATIC_VAR_FROM_TLS(fallback,err,ERR_STATE)
1.1149 +#define fallback (*GET_WSD_VAR_NAME(fallback,err, s)())
1.1150 +#endif
1.1151 +EXPORT_C ERR_STATE *ERR_get_state(void)
1.1152 + {
1.1153 +#ifndef EMULATOR
1.1154 + static ERR_STATE fallback;
1.1155 +#endif
1.1156 + ERR_STATE *ret,tmp,*tmpp=NULL;
1.1157 + int i;
1.1158 + unsigned long pid;
1.1159 +
1.1160 + err_fns_check();
1.1161 + pid=(unsigned long)CRYPTO_thread_id();
1.1162 + tmp.pid=pid;
1.1163 + ret=ERRFN(thread_get_item)(&tmp);
1.1164 +
1.1165 + /* ret == the error state, if NULL, make a new one */
1.1166 + if (ret == NULL)
1.1167 + {
1.1168 + ret=(ERR_STATE *)OPENSSL_malloc(sizeof(ERR_STATE));
1.1169 + if (ret == NULL) return(&fallback);
1.1170 + ret->pid=pid;
1.1171 + ret->top=0;
1.1172 + ret->bottom=0;
1.1173 + for (i=0; i<ERR_NUM_ERRORS; i++)
1.1174 + {
1.1175 + ret->err_data[i]=NULL;
1.1176 + ret->err_data_flags[i]=0;
1.1177 + }
1.1178 + tmpp = ERRFN(thread_set_item)(ret);
1.1179 + /* To check if insertion failed, do a get. */
1.1180 + if (ERRFN(thread_get_item)(ret) != ret)
1.1181 + {
1.1182 + ERR_STATE_free(ret); /* could not insert it */
1.1183 + return(&fallback);
1.1184 + }
1.1185 + /* If a race occured in this function and we came second, tmpp
1.1186 + * is the first one that we just replaced. */
1.1187 + if (tmpp)
1.1188 + ERR_STATE_free(tmpp);
1.1189 + }
1.1190 + return ret;
1.1191 + }
1.1192 +
1.1193 +EXPORT_C int ERR_get_next_error_library(void)
1.1194 + {
1.1195 + err_fns_check();
1.1196 + return ERRFN(get_next_lib)();
1.1197 + }
1.1198 +
1.1199 +EXPORT_C void ERR_set_error_data(char *data, int flags)
1.1200 + {
1.1201 + ERR_STATE *es;
1.1202 + int i;
1.1203 +
1.1204 + es=ERR_get_state();
1.1205 +
1.1206 + i=es->top;
1.1207 + if (i == 0)
1.1208 + i=ERR_NUM_ERRORS-1;
1.1209 +
1.1210 + err_clear_data(es,i);
1.1211 + es->err_data[i]=data;
1.1212 + es->err_data_flags[i]=flags;
1.1213 + }
1.1214 +
1.1215 +EXPORT_C void ERR_add_error_data(int num, ...)
1.1216 + {
1.1217 + va_list args;
1.1218 + int i,n,s;
1.1219 + char *str,*p,*a;
1.1220 +
1.1221 + s=80;
1.1222 + str=OPENSSL_malloc(s+1);
1.1223 + if (str == NULL) return;
1.1224 + str[0]='\0';
1.1225 +
1.1226 + va_start(args, num);
1.1227 + n=0;
1.1228 + for (i=0; i<num; i++)
1.1229 + {
1.1230 + a=va_arg(args, char*);
1.1231 + /* ignore NULLs, thanks to Bob Beck <beck@obtuse.com> */
1.1232 + if (a != NULL)
1.1233 + {
1.1234 + n+=strlen(a);
1.1235 + if (n > s)
1.1236 + {
1.1237 + s=n+20;
1.1238 + p=OPENSSL_realloc(str,s+1);
1.1239 + if (p == NULL)
1.1240 + {
1.1241 + OPENSSL_free(str);
1.1242 + goto err;
1.1243 + }
1.1244 + else
1.1245 + str=p;
1.1246 + }
1.1247 + BUF_strlcat(str,a,(size_t)s+1);
1.1248 + }
1.1249 + }
1.1250 + ERR_set_error_data(str,ERR_TXT_MALLOCED|ERR_TXT_STRING);
1.1251 +
1.1252 +err:
1.1253 + va_end(args);
1.1254 + }
1.1255 +
1.1256 +EXPORT_C int ERR_set_mark(void)
1.1257 + {
1.1258 + ERR_STATE *es;
1.1259 +
1.1260 + es=ERR_get_state();
1.1261 +
1.1262 + if (es->bottom == es->top) return 0;
1.1263 + es->err_flags[es->top]|=ERR_FLAG_MARK;
1.1264 + return 1;
1.1265 + }
1.1266 +
1.1267 +EXPORT_C int ERR_pop_to_mark(void)
1.1268 + {
1.1269 + ERR_STATE *es;
1.1270 +
1.1271 + es=ERR_get_state();
1.1272 +
1.1273 + while(es->bottom != es->top
1.1274 + && (es->err_flags[es->top] & ERR_FLAG_MARK) == 0)
1.1275 + {
1.1276 + err_clear(es,es->top);
1.1277 + es->top-=1;
1.1278 + if (es->top == -1) es->top=ERR_NUM_ERRORS;
1.1279 + }
1.1280 +
1.1281 + if (es->bottom == es->top) return 0;
1.1282 + es->err_flags[es->top]&=~ERR_FLAG_MARK;
1.1283 + return 1;
1.1284 + }