1656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* crypto/err/err.c */
2656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * All rights reserved.
4656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
5656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * This package is an SSL implementation written
6656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * by Eric Young (eay@cryptsoft.com).
7656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * The implementation was written so as to conform with Netscapes SSL.
8656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
9656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * This library is free for commercial and non-commercial use as long as
10656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * the following conditions are aheared to.  The following conditions
11656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * apply to all code found in this distribution, be it the RC4, RSA,
12656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
13656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * included with this distribution is covered by the same copyright terms
14656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
16656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Copyright remains Eric Young's, and as such any Copyright notices in
17656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * the code are not to be removed.
18656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * If this package is used in a product, Eric Young should be given attribution
19656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * as the author of the parts of the library used.
20656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * This can be in the form of a textual message at program startup or
21656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * in documentation (online or textual) provided with the package.
22656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
23656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Redistribution and use in source and binary forms, with or without
24656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * modification, are permitted provided that the following conditions
25656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * are met:
26656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 1. Redistributions of source code must retain the copyright
27656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    notice, this list of conditions and the following disclaimer.
28656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 2. Redistributions in binary form must reproduce the above copyright
29656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    notice, this list of conditions and the following disclaimer in the
30656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    documentation and/or other materials provided with the distribution.
31656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 3. All advertising materials mentioning features or use of this software
32656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    must display the following acknowledgement:
33656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    "This product includes cryptographic software written by
34656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *     Eric Young (eay@cryptsoft.com)"
35656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    The word 'cryptographic' can be left out if the rouines from the library
36656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    being used are not cryptographic related :-).
37656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 4. If you include any Windows specific code (or a derivative thereof) from
38656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    the apps directory (application code) you must include an acknowledgement:
39656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
41656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * SUCH DAMAGE.
52656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
53656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * The licence and distribution terms for any publically available version or
54656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * derivative of this code cannot be changed.  i.e. this code cannot simply be
55656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * copied and put under another distribution licence
56656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * [including the GNU Public Licence.]
57656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */
58656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* ====================================================================
59221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * Copyright (c) 1998-2006 The OpenSSL Project.  All rights reserved.
60656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
61656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Redistribution and use in source and binary forms, with or without
62656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * modification, are permitted provided that the following conditions
63656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * are met:
64656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
65656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 1. Redistributions of source code must retain the above copyright
66656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    notice, this list of conditions and the following disclaimer.
67656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
68656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 2. Redistributions in binary form must reproduce the above copyright
69656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    notice, this list of conditions and the following disclaimer in
70656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    the documentation and/or other materials provided with the
71656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    distribution.
72656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
73656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 3. All advertising materials mentioning features or use of this
74656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    software must display the following acknowledgment:
75656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    "This product includes software developed by the OpenSSL Project
76656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
77656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
78656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
79656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    endorse or promote products derived from this software without
80656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    prior written permission. For written permission, please contact
81656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    openssl-core@openssl.org.
82656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
83656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 5. Products derived from this software may not be called "OpenSSL"
84656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    nor may "OpenSSL" appear in their names without prior written
85656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    permission of the OpenSSL Project.
86656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
87656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 6. Redistributions of any form whatsoever must retain the following
88656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    acknowledgment:
89656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    "This product includes software developed by the OpenSSL Project
90656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
91656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
92656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
93656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
94656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
95656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
96656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
97656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
98656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
99656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
100656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
101656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
102656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
103656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * OF THE POSSIBILITY OF SUCH DAMAGE.
104656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * ====================================================================
105656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
106656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * This product includes cryptographic software written by Eric Young
107656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * (eay@cryptsoft.com).  This product includes software written by Tim
108656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Hudson (tjh@cryptsoft.com).
109656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
110656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */
111656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
112656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <stdio.h>
113656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <stdarg.h>
114656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <string.h>
115656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include "cryptlib.h"
116656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <openssl/lhash.h>
117656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <openssl/crypto.h>
118656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <openssl/buffer.h>
119656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <openssl/bio.h>
120656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <openssl/err.h>
121656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
122221304ee937bc0910948a8be1320cb8cc4eb6d36Brian CarlstromDECLARE_LHASH_OF(ERR_STRING_DATA);
123221304ee937bc0910948a8be1320cb8cc4eb6d36Brian CarlstromDECLARE_LHASH_OF(ERR_STATE);
124221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
125221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic void err_load_strings(int lib, ERR_STRING_DATA *str);
126221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
127221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic void ERR_STATE_free(ERR_STATE *s);
128221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#ifndef OPENSSL_NO_ERR
129221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic ERR_STRING_DATA ERR_str_libraries[]=
130221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{
131221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom{ERR_PACK(ERR_LIB_NONE,0,0)		,"unknown library"},
132221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom{ERR_PACK(ERR_LIB_SYS,0,0)		,"system library"},
133221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom{ERR_PACK(ERR_LIB_BN,0,0)		,"bignum routines"},
134221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom{ERR_PACK(ERR_LIB_RSA,0,0)		,"rsa routines"},
135221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom{ERR_PACK(ERR_LIB_DH,0,0)		,"Diffie-Hellman routines"},
136221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom{ERR_PACK(ERR_LIB_EVP,0,0)		,"digital envelope routines"},
137221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom{ERR_PACK(ERR_LIB_BUF,0,0)		,"memory buffer routines"},
138221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom{ERR_PACK(ERR_LIB_OBJ,0,0)		,"object identifier routines"},
139221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom{ERR_PACK(ERR_LIB_PEM,0,0)		,"PEM routines"},
140221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom{ERR_PACK(ERR_LIB_DSA,0,0)		,"dsa routines"},
141221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom{ERR_PACK(ERR_LIB_X509,0,0)		,"x509 certificate routines"},
142221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom{ERR_PACK(ERR_LIB_ASN1,0,0)		,"asn1 encoding routines"},
143221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom{ERR_PACK(ERR_LIB_CONF,0,0)		,"configuration file routines"},
144221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom{ERR_PACK(ERR_LIB_CRYPTO,0,0)		,"common libcrypto routines"},
145221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom{ERR_PACK(ERR_LIB_EC,0,0)		,"elliptic curve routines"},
146221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom{ERR_PACK(ERR_LIB_SSL,0,0)		,"SSL routines"},
147221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom{ERR_PACK(ERR_LIB_BIO,0,0)		,"BIO routines"},
148221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom{ERR_PACK(ERR_LIB_PKCS7,0,0)		,"PKCS7 routines"},
149221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom{ERR_PACK(ERR_LIB_X509V3,0,0)		,"X509 V3 routines"},
150221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom{ERR_PACK(ERR_LIB_PKCS12,0,0)		,"PKCS12 routines"},
151221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom{ERR_PACK(ERR_LIB_RAND,0,0)		,"random number generator"},
152221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom{ERR_PACK(ERR_LIB_DSO,0,0)		,"DSO support routines"},
153221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom{ERR_PACK(ERR_LIB_TS,0,0)		,"time stamp routines"},
154221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom{ERR_PACK(ERR_LIB_ENGINE,0,0)		,"engine routines"},
155221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom{ERR_PACK(ERR_LIB_OCSP,0,0)		,"OCSP routines"},
156221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom{ERR_PACK(ERR_LIB_FIPS,0,0)		,"FIPS routines"},
157221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom{ERR_PACK(ERR_LIB_CMS,0,0)		,"CMS routines"},
158221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom{ERR_PACK(ERR_LIB_HMAC,0,0)		,"HMAC routines"},
159221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom{0,NULL},
160221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	};
161221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
162221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic ERR_STRING_DATA ERR_str_functs[]=
163221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{
164221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{ERR_PACK(0,SYS_F_FOPEN,0),     	"fopen"},
165221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{ERR_PACK(0,SYS_F_CONNECT,0),		"connect"},
166221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{ERR_PACK(0,SYS_F_GETSERVBYNAME,0),	"getservbyname"},
167221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{ERR_PACK(0,SYS_F_SOCKET,0),		"socket"},
168221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{ERR_PACK(0,SYS_F_IOCTLSOCKET,0),	"ioctlsocket"},
169221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{ERR_PACK(0,SYS_F_BIND,0),		"bind"},
170221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{ERR_PACK(0,SYS_F_LISTEN,0),		"listen"},
171221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{ERR_PACK(0,SYS_F_ACCEPT,0),		"accept"},
172221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#ifdef OPENSSL_SYS_WINDOWS
173221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{ERR_PACK(0,SYS_F_WSASTARTUP,0),	"WSAstartup"},
174221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#endif
175221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{ERR_PACK(0,SYS_F_OPENDIR,0),		"opendir"},
176221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{ERR_PACK(0,SYS_F_FREAD,0),		"fread"},
177221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{0,NULL},
178221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	};
179221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
180221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic ERR_STRING_DATA ERR_str_reasons[]=
181221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{
182221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom{ERR_R_SYS_LIB				,"system lib"},
183221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom{ERR_R_BN_LIB				,"BN lib"},
184221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom{ERR_R_RSA_LIB				,"RSA lib"},
185221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom{ERR_R_DH_LIB				,"DH lib"},
186221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom{ERR_R_EVP_LIB				,"EVP lib"},
187221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom{ERR_R_BUF_LIB				,"BUF lib"},
188221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom{ERR_R_OBJ_LIB				,"OBJ lib"},
189221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom{ERR_R_PEM_LIB				,"PEM lib"},
190221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom{ERR_R_DSA_LIB				,"DSA lib"},
191221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom{ERR_R_X509_LIB				,"X509 lib"},
192221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom{ERR_R_ASN1_LIB				,"ASN1 lib"},
193221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom{ERR_R_CONF_LIB				,"CONF lib"},
194221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom{ERR_R_CRYPTO_LIB			,"CRYPTO lib"},
195221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom{ERR_R_EC_LIB				,"EC lib"},
196221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom{ERR_R_SSL_LIB				,"SSL lib"},
197221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom{ERR_R_BIO_LIB				,"BIO lib"},
198221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom{ERR_R_PKCS7_LIB			,"PKCS7 lib"},
199221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom{ERR_R_X509V3_LIB			,"X509V3 lib"},
200221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom{ERR_R_PKCS12_LIB			,"PKCS12 lib"},
201221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom{ERR_R_RAND_LIB				,"RAND lib"},
202221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom{ERR_R_DSO_LIB				,"DSO lib"},
203221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom{ERR_R_ENGINE_LIB			,"ENGINE lib"},
204221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom{ERR_R_OCSP_LIB				,"OCSP lib"},
205221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom{ERR_R_TS_LIB				,"TS lib"},
206221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
207221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom{ERR_R_NESTED_ASN1_ERROR		,"nested asn1 error"},
208221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom{ERR_R_BAD_ASN1_OBJECT_HEADER		,"bad asn1 object header"},
209221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom{ERR_R_BAD_GET_ASN1_OBJECT_CALL		,"bad get asn1 object call"},
210221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom{ERR_R_EXPECTING_AN_ASN1_SEQUENCE	,"expecting an asn1 sequence"},
211221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom{ERR_R_ASN1_LENGTH_MISMATCH		,"asn1 length mismatch"},
212221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom{ERR_R_MISSING_ASN1_EOS			,"missing asn1 eos"},
213221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
214221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom{ERR_R_FATAL                            ,"fatal"},
215221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom{ERR_R_MALLOC_FAILURE			,"malloc failure"},
216221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom{ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED	,"called a function you should not call"},
217221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom{ERR_R_PASSED_NULL_PARAMETER		,"passed a null parameter"},
218221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom{ERR_R_INTERNAL_ERROR			,"internal error"},
219221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom{ERR_R_DISABLED				,"called a function that was disabled at compile-time"},
220221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
221221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom{0,NULL},
222221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	};
223221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#endif
224221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
225221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
226221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom/* Define the predeclared (but externally opaque) "ERR_FNS" type */
227221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstruct st_ERR_FNS
228221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{
229221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	/* Works on the "error_hash" string table */
230221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	LHASH_OF(ERR_STRING_DATA) *(*cb_err_get)(int create);
231221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	void (*cb_err_del)(void);
232221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	ERR_STRING_DATA *(*cb_err_get_item)(const ERR_STRING_DATA *);
233221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	ERR_STRING_DATA *(*cb_err_set_item)(ERR_STRING_DATA *);
234221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	ERR_STRING_DATA *(*cb_err_del_item)(ERR_STRING_DATA *);
235221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	/* Works on the "thread_hash" error-state table */
236221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	LHASH_OF(ERR_STATE) *(*cb_thread_get)(int create);
237221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	void (*cb_thread_release)(LHASH_OF(ERR_STATE) **hash);
238221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	ERR_STATE *(*cb_thread_get_item)(const ERR_STATE *);
239221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	ERR_STATE *(*cb_thread_set_item)(ERR_STATE *);
240221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	void (*cb_thread_del_item)(const ERR_STATE *);
241221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	/* Returns the next available error "library" numbers */
242221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	int (*cb_get_next_lib)(void);
243221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	};
244221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
245221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom/* Predeclarations of the "err_defaults" functions */
246221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic LHASH_OF(ERR_STRING_DATA) *int_err_get(int create);
247221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic void int_err_del(void);
248221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic ERR_STRING_DATA *int_err_get_item(const ERR_STRING_DATA *);
249221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic ERR_STRING_DATA *int_err_set_item(ERR_STRING_DATA *);
250221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic ERR_STRING_DATA *int_err_del_item(ERR_STRING_DATA *);
251221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic LHASH_OF(ERR_STATE) *int_thread_get(int create);
252221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic void int_thread_release(LHASH_OF(ERR_STATE) **hash);
253221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic ERR_STATE *int_thread_get_item(const ERR_STATE *);
254221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic ERR_STATE *int_thread_set_item(ERR_STATE *);
255221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic void int_thread_del_item(const ERR_STATE *);
256221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic int int_err_get_next_lib(void);
257221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom/* The static ERR_FNS table using these defaults functions */
258221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic const ERR_FNS err_defaults =
259221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{
260221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	int_err_get,
261221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	int_err_del,
262221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	int_err_get_item,
263221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	int_err_set_item,
264221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	int_err_del_item,
265221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	int_thread_get,
266221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	int_thread_release,
267221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	int_thread_get_item,
268221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	int_thread_set_item,
269221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	int_thread_del_item,
270221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	int_err_get_next_lib
271221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	};
272221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
273221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom/* The replacable table of ERR_FNS functions we use at run-time */
274221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic const ERR_FNS *err_fns = NULL;
275221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
276221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom/* Eg. rather than using "err_get()", use "ERRFN(err_get)()". */
277221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#define ERRFN(a) err_fns->cb_##a
278221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
279221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom/* The internal state used by "err_defaults" - as such, the setting, reading,
280221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * creating, and deleting of this data should only be permitted via the
281221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * "err_defaults" functions. This way, a linked module can completely defer all
282221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * ERR state operation (together with requisite locking) to the implementations
283221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * and state in the loading application. */
284221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic LHASH_OF(ERR_STRING_DATA) *int_error_hash = NULL;
285221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic LHASH_OF(ERR_STATE) *int_thread_hash = NULL;
286221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic int int_thread_hash_references = 0;
287221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic int int_err_library_number= ERR_LIB_USER;
288221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
289221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom/* Internal function that checks whether "err_fns" is set and if not, sets it to
290221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * the defaults. */
291221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic void err_fns_check(void)
292221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{
293221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (err_fns) return;
294221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
295221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	CRYPTO_w_lock(CRYPTO_LOCK_ERR);
296221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (!err_fns)
297221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		err_fns = &err_defaults;
298221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
299221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	}
300221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
301221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom/* API functions to get or set the underlying ERR functions. */
302221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
303221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromconst ERR_FNS *ERR_get_implementation(void)
304221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{
305221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	err_fns_check();
306221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	return err_fns;
307221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	}
308221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
309221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromint ERR_set_implementation(const ERR_FNS *fns)
310221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{
311221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	int ret = 0;
312221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
313221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	CRYPTO_w_lock(CRYPTO_LOCK_ERR);
314221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	/* It's too late if 'err_fns' is non-NULL. BTW: not much point setting
315221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	 * an error is there?! */
316221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (!err_fns)
317221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		{
318221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		err_fns = fns;
319221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		ret = 1;
320221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		}
321221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
322221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	return ret;
323221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	}
324221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
325221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom/* These are the callbacks provided to "lh_new()" when creating the LHASH tables
326221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * internal to the "err_defaults" implementation. */
327221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
328221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic unsigned long get_error_values(int inc,int top,const char **file,int *line,
329221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				      const char **data,int *flags);
330221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
331221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom/* The internal functions used in the "err_defaults" implementation */
332221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
333221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic unsigned long err_string_data_hash(const ERR_STRING_DATA *a)
334221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{
335221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	unsigned long ret,l;
336221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
337221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	l=a->error;
338221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	ret=l^ERR_GET_LIB(l)^ERR_GET_FUNC(l);
339221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	return(ret^ret%19*13);
340221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	}
341221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic IMPLEMENT_LHASH_HASH_FN(err_string_data, ERR_STRING_DATA)
342221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
343221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic int err_string_data_cmp(const ERR_STRING_DATA *a,
344221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			       const ERR_STRING_DATA *b)
345221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{
346221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	return (int)(a->error - b->error);
347221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	}
348221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic IMPLEMENT_LHASH_COMP_FN(err_string_data, ERR_STRING_DATA)
349221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
350221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic LHASH_OF(ERR_STRING_DATA) *int_err_get(int create)
351221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{
352221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	LHASH_OF(ERR_STRING_DATA) *ret = NULL;
353221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
354221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	CRYPTO_w_lock(CRYPTO_LOCK_ERR);
355221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (!int_error_hash && create)
356221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		{
357221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		CRYPTO_push_info("int_err_get (err.c)");
358221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		int_error_hash = lh_ERR_STRING_DATA_new();
359221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		CRYPTO_pop_info();
360221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		}
361221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (int_error_hash)
362221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		ret = int_error_hash;
363221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
364221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
365221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	return ret;
366221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	}
367221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
368221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic void int_err_del(void)
369221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{
370221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	CRYPTO_w_lock(CRYPTO_LOCK_ERR);
371221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (int_error_hash)
372221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		{
373221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		lh_ERR_STRING_DATA_free(int_error_hash);
374221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		int_error_hash = NULL;
375221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		}
376221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
377221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	}
378221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
379221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic ERR_STRING_DATA *int_err_get_item(const ERR_STRING_DATA *d)
380221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{
381221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	ERR_STRING_DATA *p;
382221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	LHASH_OF(ERR_STRING_DATA) *hash;
383221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
384221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	err_fns_check();
385221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	hash = ERRFN(err_get)(0);
386221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (!hash)
387221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		return NULL;
388221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
389221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	CRYPTO_r_lock(CRYPTO_LOCK_ERR);
390221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	p = lh_ERR_STRING_DATA_retrieve(hash, d);
391221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	CRYPTO_r_unlock(CRYPTO_LOCK_ERR);
392221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
393221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	return p;
394221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	}
395221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
396221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic ERR_STRING_DATA *int_err_set_item(ERR_STRING_DATA *d)
397221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{
398221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	ERR_STRING_DATA *p;
399221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	LHASH_OF(ERR_STRING_DATA) *hash;
400221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
401221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	err_fns_check();
402221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	hash = ERRFN(err_get)(1);
403221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (!hash)
404221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		return NULL;
405221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
406221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	CRYPTO_w_lock(CRYPTO_LOCK_ERR);
407221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	p = lh_ERR_STRING_DATA_insert(hash, d);
408221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
409221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
410221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	return p;
411221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	}
412221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
413221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic ERR_STRING_DATA *int_err_del_item(ERR_STRING_DATA *d)
414221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{
415221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	ERR_STRING_DATA *p;
416221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	LHASH_OF(ERR_STRING_DATA) *hash;
417221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
418221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	err_fns_check();
419221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	hash = ERRFN(err_get)(0);
420221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (!hash)
421221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		return NULL;
422221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
423221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	CRYPTO_w_lock(CRYPTO_LOCK_ERR);
424221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	p = lh_ERR_STRING_DATA_delete(hash, d);
425221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
426221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
427221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	return p;
428221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	}
429221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
430221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic unsigned long err_state_hash(const ERR_STATE *a)
431221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{
432221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	return CRYPTO_THREADID_hash(&a->tid) * 13;
433221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	}
434221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic IMPLEMENT_LHASH_HASH_FN(err_state, ERR_STATE)
435221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
436221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic int err_state_cmp(const ERR_STATE *a, const ERR_STATE *b)
437221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{
438221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	return CRYPTO_THREADID_cmp(&a->tid, &b->tid);
439221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	}
440221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic IMPLEMENT_LHASH_COMP_FN(err_state, ERR_STATE)
441221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
442221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic LHASH_OF(ERR_STATE) *int_thread_get(int create)
443221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{
444221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	LHASH_OF(ERR_STATE) *ret = NULL;
445221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
446221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	CRYPTO_w_lock(CRYPTO_LOCK_ERR);
447221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (!int_thread_hash && create)
448221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		{
449221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		CRYPTO_push_info("int_thread_get (err.c)");
450221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		int_thread_hash = lh_ERR_STATE_new();
451221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		CRYPTO_pop_info();
452221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		}
453221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (int_thread_hash)
454221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		{
455221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		int_thread_hash_references++;
456221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		ret = int_thread_hash;
457221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		}
458221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
459221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	return ret;
460221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	}
461221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
462221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic void int_thread_release(LHASH_OF(ERR_STATE) **hash)
463221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{
464221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	int i;
465221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
466221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (hash == NULL || *hash == NULL)
467221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		return;
468221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
469221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	i = CRYPTO_add(&int_thread_hash_references, -1, CRYPTO_LOCK_ERR);
470221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
471221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#ifdef REF_PRINT
472221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	fprintf(stderr,"%4d:%s\n",int_thread_hash_references,"ERR");
473221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#endif
474221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (i > 0) return;
475221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#ifdef REF_CHECK
476221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (i < 0)
477221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		{
478221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		fprintf(stderr,"int_thread_release, bad reference count\n");
479221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		abort(); /* ok */
480221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		}
481221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#endif
482221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	*hash = NULL;
483221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	}
484221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
485221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic ERR_STATE *int_thread_get_item(const ERR_STATE *d)
486221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{
487221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	ERR_STATE *p;
488221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	LHASH_OF(ERR_STATE) *hash;
489221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
490221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	err_fns_check();
491221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	hash = ERRFN(thread_get)(0);
492221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (!hash)
493221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		return NULL;
494221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
495221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	CRYPTO_r_lock(CRYPTO_LOCK_ERR);
496221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	p = lh_ERR_STATE_retrieve(hash, d);
497221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	CRYPTO_r_unlock(CRYPTO_LOCK_ERR);
498221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
499221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	ERRFN(thread_release)(&hash);
500221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	return p;
501221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	}
502221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
503221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic ERR_STATE *int_thread_set_item(ERR_STATE *d)
504221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{
505221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	ERR_STATE *p;
506221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	LHASH_OF(ERR_STATE) *hash;
507221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
508221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	err_fns_check();
509221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	hash = ERRFN(thread_get)(1);
510221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (!hash)
511221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		return NULL;
512221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
513221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	CRYPTO_w_lock(CRYPTO_LOCK_ERR);
514221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	p = lh_ERR_STATE_insert(hash, d);
515221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
516221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
517221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	ERRFN(thread_release)(&hash);
518221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	return p;
519221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	}
520221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
521221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic void int_thread_del_item(const ERR_STATE *d)
522221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{
523221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	ERR_STATE *p;
524221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	LHASH_OF(ERR_STATE) *hash;
525221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
526221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	err_fns_check();
527221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	hash = ERRFN(thread_get)(0);
528221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (!hash)
529221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		return;
530221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
531221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	CRYPTO_w_lock(CRYPTO_LOCK_ERR);
532221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	p = lh_ERR_STATE_delete(hash, d);
533221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	/* make sure we don't leak memory */
534221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (int_thread_hash_references == 1
535221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	    && int_thread_hash && lh_ERR_STATE_num_items(int_thread_hash) == 0)
536221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		{
537221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		lh_ERR_STATE_free(int_thread_hash);
538221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		int_thread_hash = NULL;
539221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		}
540221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
541221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
542221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	ERRFN(thread_release)(&hash);
543221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (p)
544221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		ERR_STATE_free(p);
545221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	}
546221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
547221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic int int_err_get_next_lib(void)
548221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{
549221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	int ret;
550221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
551221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	CRYPTO_w_lock(CRYPTO_LOCK_ERR);
552221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	ret = int_err_library_number++;
553221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
554221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
555221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	return ret;
556221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	}
557221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
558221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
559221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#ifndef OPENSSL_NO_ERR
560221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#define NUM_SYS_STR_REASONS 127
561221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#define LEN_SYS_STR_REASON 32
562221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
563221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic ERR_STRING_DATA SYS_str_reasons[NUM_SYS_STR_REASONS + 1];
564221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom/* SYS_str_reasons is filled with copies of strerror() results at
565221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * initialization.
566221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * 'errno' values up to 127 should cover all usual errors,
567221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * others will be displayed numerically by ERR_error_string.
568221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * It is crucial that we have something for each reason code
569221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * that occurs in ERR_str_reasons, or bogus reason strings
570221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * will be returned for SYSerr(), which always gets an errno
571221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * value and never one of those 'standard' reason codes. */
572221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
573221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic void build_SYS_str_reasons(void)
574221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{
575221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	/* OPENSSL_malloc cannot be used here, use static storage instead */
576221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	static char strerror_tab[NUM_SYS_STR_REASONS][LEN_SYS_STR_REASON];
577221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	int i;
578221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	static int init = 1;
579221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
580221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	CRYPTO_r_lock(CRYPTO_LOCK_ERR);
581221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (!init)
582221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		{
583221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		CRYPTO_r_unlock(CRYPTO_LOCK_ERR);
584221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		return;
585221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		}
586221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
587221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	CRYPTO_r_unlock(CRYPTO_LOCK_ERR);
588221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	CRYPTO_w_lock(CRYPTO_LOCK_ERR);
589221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (!init)
590221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		{
591221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
592221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		return;
593221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		}
594221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
595221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	for (i = 1; i <= NUM_SYS_STR_REASONS; i++)
596221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		{
597221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		ERR_STRING_DATA *str = &SYS_str_reasons[i - 1];
598221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
599221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		str->error = (unsigned long)i;
600221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		if (str->string == NULL)
601221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			{
602221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			char (*dest)[LEN_SYS_STR_REASON] = &(strerror_tab[i - 1]);
603221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			char *src = strerror(i);
604221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			if (src != NULL)
605221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				{
606221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				strncpy(*dest, src, sizeof *dest);
607221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				(*dest)[sizeof *dest - 1] = '\0';
608221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				str->string = *dest;
609221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				}
610221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			}
611221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		if (str->string == NULL)
612221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			str->string = "unknown";
613221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		}
614221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
615221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	/* Now we still have SYS_str_reasons[NUM_SYS_STR_REASONS] = {0, NULL},
616221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	 * as required by ERR_load_strings. */
617221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
618221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	init = 0;
619221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
620221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
621221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	}
622221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#endif
623656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
624656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#define err_clear_data(p,i) \
625656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	do { \
626656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (((p)->err_data[i] != NULL) && \
627656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		(p)->err_data_flags[i] & ERR_TXT_MALLOCED) \
628656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{  \
629656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		OPENSSL_free((p)->err_data[i]); \
630656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		(p)->err_data[i]=NULL; \
631656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		} \
632656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	(p)->err_data_flags[i]=0; \
633656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	} while(0)
634656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
635656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#define err_clear(p,i) \
636656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	do { \
637656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	(p)->err_flags[i]=0; \
638656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	(p)->err_buffer[i]=0; \
639656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	err_clear_data(p,i); \
640656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	(p)->err_file[i]=NULL; \
641656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	(p)->err_line[i]= -1; \
642656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	} while(0)
643656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
644221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic void ERR_STATE_free(ERR_STATE *s)
645221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{
646221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	int i;
647221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
648221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (s == NULL)
649221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	    return;
650221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
651221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	for (i=0; i<ERR_NUM_ERRORS; i++)
652221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		{
653221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		err_clear_data(s,i);
654221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		}
655221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	OPENSSL_free(s);
656221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	}
657221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
658221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromvoid ERR_load_ERR_strings(void)
659221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{
660221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	err_fns_check();
661221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#ifndef OPENSSL_NO_ERR
662221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	err_load_strings(0,ERR_str_libraries);
663221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	err_load_strings(0,ERR_str_reasons);
664221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	err_load_strings(ERR_LIB_SYS,ERR_str_functs);
665221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	build_SYS_str_reasons();
666221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	err_load_strings(ERR_LIB_SYS,SYS_str_reasons);
667221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#endif
668221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	}
669221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
670221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic void err_load_strings(int lib, ERR_STRING_DATA *str)
671221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{
672221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	while (str->error)
673221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		{
674221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		if (lib)
675221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			str->error|=ERR_PACK(lib,0,0);
676221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		ERRFN(err_set_item)(str);
677221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		str++;
678221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		}
679221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	}
680221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
681221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromvoid ERR_load_strings(int lib, ERR_STRING_DATA *str)
682221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{
683221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	ERR_load_ERR_strings();
684221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	err_load_strings(lib, str);
685221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	}
686221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
687221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromvoid ERR_unload_strings(int lib, ERR_STRING_DATA *str)
688221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{
689221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	while (str->error)
690221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		{
691221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		if (lib)
692221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			str->error|=ERR_PACK(lib,0,0);
693221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		ERRFN(err_del_item)(str);
694221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		str++;
695221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		}
696221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	}
697221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
698221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromvoid ERR_free_strings(void)
699221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{
700221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	err_fns_check();
701221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	ERRFN(err_del)();
702221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	}
703221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
704221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom/********************************************************/
705221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
706656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectvoid ERR_put_error(int lib, int func, int reason, const char *file,
707656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	     int line)
708656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
709656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ERR_STATE *es;
710656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
711656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifdef _OSD_POSIX
712656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* In the BS2000-OSD POSIX subsystem, the compiler generates
713656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	 * path names in the form "*POSIX(/etc/passwd)".
714656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	 * This dirty hack strips them to something sensible.
715656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	 * @@@ We shouldn't modify a const string, though.
716656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	 */
717656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (strncmp(file,"*POSIX(", sizeof("*POSIX(")-1) == 0) {
718656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		char *end;
719656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
720656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* Skip the "*POSIX(" prefix */
721656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		file += sizeof("*POSIX(")-1;
722656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		end = &file[strlen(file)-1];
723656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (*end == ')')
724656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			*end = '\0';
725656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* Optional: use the basename of the path only. */
726656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if ((end = strrchr(file, '/')) != NULL)
727656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			file = &end[1];
728656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
729656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
730656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	es=ERR_get_state();
731656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
732656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	es->top=(es->top+1)%ERR_NUM_ERRORS;
733656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (es->top == es->bottom)
734656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		es->bottom=(es->bottom+1)%ERR_NUM_ERRORS;
735656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	es->err_flags[es->top]=0;
736656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	es->err_buffer[es->top]=ERR_PACK(lib,func,reason);
737656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	es->err_file[es->top]=file;
738656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	es->err_line[es->top]=line;
739656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	err_clear_data(es,es->top);
740656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
741656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
742656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectvoid ERR_clear_error(void)
743656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
744656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int i;
745656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ERR_STATE *es;
746656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
747656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	es=ERR_get_state();
748656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
749656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	for (i=0; i<ERR_NUM_ERRORS; i++)
750656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
751656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		err_clear(es,i);
752656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
753656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	es->top=es->bottom=0;
754656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
755656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
756656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
757656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectunsigned long ERR_get_error(void)
758656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{ return(get_error_values(1,0,NULL,NULL,NULL,NULL)); }
759656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
760656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectunsigned long ERR_get_error_line(const char **file,
761656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	     int *line)
762656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{ return(get_error_values(1,0,file,line,NULL,NULL)); }
763656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
764656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectunsigned long ERR_get_error_line_data(const char **file, int *line,
765656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	     const char **data, int *flags)
766656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{ return(get_error_values(1,0,file,line,data,flags)); }
767656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
768656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
769656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectunsigned long ERR_peek_error(void)
770656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{ return(get_error_values(0,0,NULL,NULL,NULL,NULL)); }
771656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
772656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectunsigned long ERR_peek_error_line(const char **file, int *line)
773656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{ return(get_error_values(0,0,file,line,NULL,NULL)); }
774656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
775656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectunsigned long ERR_peek_error_line_data(const char **file, int *line,
776656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	     const char **data, int *flags)
777656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{ return(get_error_values(0,0,file,line,data,flags)); }
778656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
779656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
780656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectunsigned long ERR_peek_last_error(void)
781656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{ return(get_error_values(0,1,NULL,NULL,NULL,NULL)); }
782656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
783656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectunsigned long ERR_peek_last_error_line(const char **file, int *line)
784656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{ return(get_error_values(0,1,file,line,NULL,NULL)); }
785656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
786656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectunsigned long ERR_peek_last_error_line_data(const char **file, int *line,
787656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	     const char **data, int *flags)
788656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{ return(get_error_values(0,1,file,line,data,flags)); }
789656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
790656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
791656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic unsigned long get_error_values(int inc, int top, const char **file, int *line,
792656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	     const char **data, int *flags)
793656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
794656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int i=0;
795656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ERR_STATE *es;
796656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	unsigned long ret;
797656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
798656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	es=ERR_get_state();
799656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
800656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (inc && top)
801656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
802656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (file) *file = "";
803656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (line) *line = 0;
804656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (data) *data = "";
805656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (flags) *flags = 0;
806656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
807656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return ERR_R_INTERNAL_ERROR;
808656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
809656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
810656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (es->bottom == es->top) return 0;
811656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (top)
812656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		i=es->top;			 /* last error */
813656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	else
814656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		i=(es->bottom+1)%ERR_NUM_ERRORS; /* first error */
815656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
816656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ret=es->err_buffer[i];
817656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (inc)
818656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
819656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		es->bottom=i;
820656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		es->err_buffer[i]=0;
821656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
822656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
823656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if ((file != NULL) && (line != NULL))
824656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
825656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (es->err_file[i] == NULL)
826656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
827656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			*file="NA";
828656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (line != NULL) *line=0;
829656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
830656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		else
831656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
832656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			*file=es->err_file[i];
833656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (line != NULL) *line=es->err_line[i];
834656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
835656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
836656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
837656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (data == NULL)
838656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
839656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (inc)
840656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
841656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			err_clear_data(es, i);
842656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
843656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
844656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	else
845656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
846656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (es->err_data[i] == NULL)
847656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
848656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			*data="";
849656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (flags != NULL) *flags=0;
850656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
851656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		else
852656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
853656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			*data=es->err_data[i];
854656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (flags != NULL) *flags=es->err_data_flags[i];
855656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
856656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
857656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return ret;
858656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
859656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
860221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromvoid ERR_error_string_n(unsigned long e, char *buf, size_t len)
861221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{
862221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	char lsbuf[64], fsbuf[64], rsbuf[64];
863221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	const char *ls,*fs,*rs;
864221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	unsigned long l,f,r;
865221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
866221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	l=ERR_GET_LIB(e);
867221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	f=ERR_GET_FUNC(e);
868221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	r=ERR_GET_REASON(e);
869221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
870221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	ls=ERR_lib_error_string(e);
871221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	fs=ERR_func_error_string(e);
872221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	rs=ERR_reason_error_string(e);
873221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
874221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (ls == NULL)
875221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		BIO_snprintf(lsbuf, sizeof(lsbuf), "lib(%lu)", l);
876221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (fs == NULL)
877221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		BIO_snprintf(fsbuf, sizeof(fsbuf), "func(%lu)", f);
878221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (rs == NULL)
879221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		BIO_snprintf(rsbuf, sizeof(rsbuf), "reason(%lu)", r);
880221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
881221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	BIO_snprintf(buf, len,"error:%08lX:%s:%s:%s", e, ls?ls:lsbuf,
882221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		fs?fs:fsbuf, rs?rs:rsbuf);
883221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (strlen(buf) == len-1)
884221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		{
885221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		/* output may be truncated; make sure we always have 5
886221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		 * colon-separated fields, i.e. 4 colons ... */
887221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#define NUM_COLONS 4
888221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		if (len > NUM_COLONS) /* ... if possible */
889221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			{
890221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			int i;
891221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			char *s = buf;
892221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
893221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			for (i = 0; i < NUM_COLONS; i++)
894221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				{
895221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				char *colon = strchr(s, ':');
896221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				if (colon == NULL || colon > &buf[len-1] - NUM_COLONS + i)
897221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom					{
898221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom					/* set colon no. i at last possible position
899221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom					 * (buf[len-1] is the terminating 0)*/
900221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom					colon = &buf[len-1] - NUM_COLONS + i;
901221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom					*colon = ':';
902221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom					}
903221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				s = colon + 1;
904221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				}
905221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			}
906221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		}
907221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	}
908221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
909221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom/* BAD for multi-threading: uses a local buffer if ret == NULL */
910221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom/* ERR_error_string_n should be used instead for ret != NULL
911221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * as ERR_error_string cannot know how large the buffer is */
912221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromchar *ERR_error_string(unsigned long e, char *ret)
913221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{
914221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	static char buf[256];
915221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
916221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (ret == NULL) ret=buf;
917221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	ERR_error_string_n(e, ret, 256);
918221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
919221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	return ret;
920221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	}
921221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
922221304ee937bc0910948a8be1320cb8cc4eb6d36Brian CarlstromLHASH_OF(ERR_STRING_DATA) *ERR_get_string_table(void)
923221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{
924221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	err_fns_check();
925221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	return ERRFN(err_get)(0);
926221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	}
927221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
928221304ee937bc0910948a8be1320cb8cc4eb6d36Brian CarlstromLHASH_OF(ERR_STATE) *ERR_get_err_state_table(void)
929221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{
930221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	err_fns_check();
931221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	return ERRFN(thread_get)(0);
932221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	}
933221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
934221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromvoid ERR_release_err_state_table(LHASH_OF(ERR_STATE) **hash)
935221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{
936221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	err_fns_check();
937221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	ERRFN(thread_release)(hash);
938221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	}
939221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
940221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromconst char *ERR_lib_error_string(unsigned long e)
941221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{
942221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	ERR_STRING_DATA d,*p;
943221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	unsigned long l;
944221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
945221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	err_fns_check();
946221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	l=ERR_GET_LIB(e);
947221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	d.error=ERR_PACK(l,0,0);
948221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	p=ERRFN(err_get_item)(&d);
949221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	return((p == NULL)?NULL:p->string);
950221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	}
951221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
952221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromconst char *ERR_func_error_string(unsigned long e)
953221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{
954221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	ERR_STRING_DATA d,*p;
955221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	unsigned long l,f;
956221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
957221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	err_fns_check();
958221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	l=ERR_GET_LIB(e);
959221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	f=ERR_GET_FUNC(e);
960221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	d.error=ERR_PACK(l,f,0);
961221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	p=ERRFN(err_get_item)(&d);
962221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	return((p == NULL)?NULL:p->string);
963221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	}
964221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
965221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromconst char *ERR_reason_error_string(unsigned long e)
966221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{
967221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	ERR_STRING_DATA d,*p=NULL;
968221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	unsigned long l,r;
969221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
970221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	err_fns_check();
971221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	l=ERR_GET_LIB(e);
972221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	r=ERR_GET_REASON(e);
973221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	d.error=ERR_PACK(l,0,r);
974221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	p=ERRFN(err_get_item)(&d);
975221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (!p)
976221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		{
977221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		d.error=ERR_PACK(0,0,r);
978221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		p=ERRFN(err_get_item)(&d);
979221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		}
980221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	return((p == NULL)?NULL:p->string);
981221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	}
982221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
983221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromvoid ERR_remove_thread_state(const CRYPTO_THREADID *id)
984221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{
985221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	ERR_STATE tmp;
986221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
987221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (id)
988221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		CRYPTO_THREADID_cpy(&tmp.tid, id);
989221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	else
990221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		CRYPTO_THREADID_current(&tmp.tid);
991221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	err_fns_check();
992221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	/* thread_del_item automatically destroys the LHASH if the number of
993221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	 * items reaches zero. */
994221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	ERRFN(thread_del_item)(&tmp);
995221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	}
996221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
997221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#ifndef OPENSSL_NO_DEPRECATED
998221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromvoid ERR_remove_state(unsigned long pid)
999221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{
1000221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	ERR_remove_thread_state(NULL);
1001221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	}
1002221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#endif
1003221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
1004221304ee937bc0910948a8be1320cb8cc4eb6d36Brian CarlstromERR_STATE *ERR_get_state(void)
1005221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{
1006221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	static ERR_STATE fallback;
1007221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	ERR_STATE *ret,tmp,*tmpp=NULL;
1008221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	int i;
1009221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	CRYPTO_THREADID tid;
1010221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
1011221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	err_fns_check();
1012221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	CRYPTO_THREADID_current(&tid);
1013221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	CRYPTO_THREADID_cpy(&tmp.tid, &tid);
1014221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	ret=ERRFN(thread_get_item)(&tmp);
1015221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
1016221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	/* ret == the error state, if NULL, make a new one */
1017221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (ret == NULL)
1018221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		{
1019221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		ret=(ERR_STATE *)OPENSSL_malloc(sizeof(ERR_STATE));
1020221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		if (ret == NULL) return(&fallback);
1021221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		CRYPTO_THREADID_cpy(&ret->tid, &tid);
1022221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		ret->top=0;
1023221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		ret->bottom=0;
1024221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		for (i=0; i<ERR_NUM_ERRORS; i++)
1025221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			{
1026221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			ret->err_data[i]=NULL;
1027221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			ret->err_data_flags[i]=0;
1028221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			}
1029221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		tmpp = ERRFN(thread_set_item)(ret);
1030221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		/* To check if insertion failed, do a get. */
1031221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		if (ERRFN(thread_get_item)(ret) != ret)
1032221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			{
1033221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			ERR_STATE_free(ret); /* could not insert it */
1034221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			return(&fallback);
1035221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			}
1036221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		/* If a race occured in this function and we came second, tmpp
1037221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		 * is the first one that we just replaced. */
1038221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		if (tmpp)
1039221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			ERR_STATE_free(tmpp);
1040221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		}
1041221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	return ret;
1042221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	}
1043221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
1044221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromint ERR_get_next_error_library(void)
1045221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{
1046221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	err_fns_check();
1047221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	return ERRFN(get_next_lib)();
1048221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	}
1049221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
1050656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectvoid ERR_set_error_data(char *data, int flags)
1051656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
1052656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ERR_STATE *es;
1053656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int i;
1054656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1055656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	es=ERR_get_state();
1056656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1057656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	i=es->top;
1058656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (i == 0)
1059656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		i=ERR_NUM_ERRORS-1;
1060656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1061656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	err_clear_data(es,i);
1062656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	es->err_data[i]=data;
1063656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	es->err_data_flags[i]=flags;
1064656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
1065656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1066656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectvoid ERR_add_error_data(int num, ...)
1067656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
1068656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	va_list args;
1069392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	va_start(args, num);
1070392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	ERR_add_error_vdata(num, args);
1071392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	va_end(args);
1072392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	}
1073392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
1074392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromvoid ERR_add_error_vdata(int num, va_list args)
1075392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	{
1076656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int i,n,s;
1077656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	char *str,*p,*a;
1078656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1079656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	s=80;
1080656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	str=OPENSSL_malloc(s+1);
1081656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (str == NULL) return;
1082656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	str[0]='\0';
1083656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1084656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	n=0;
1085656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	for (i=0; i<num; i++)
1086656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
1087656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		a=va_arg(args, char*);
1088656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* ignore NULLs, thanks to Bob Beck <beck@obtuse.com> */
1089656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (a != NULL)
1090656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
1091656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			n+=strlen(a);
1092656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (n > s)
1093656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				{
1094656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				s=n+20;
1095656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				p=OPENSSL_realloc(str,s+1);
1096656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				if (p == NULL)
1097656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					{
1098656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					OPENSSL_free(str);
1099392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom					return;
1100656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					}
1101656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				else
1102656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					str=p;
1103656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				}
1104656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			BUF_strlcat(str,a,(size_t)s+1);
1105656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
1106656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
1107656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ERR_set_error_data(str,ERR_TXT_MALLOCED|ERR_TXT_STRING);
1108656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
1109656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1110656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint ERR_set_mark(void)
1111656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
1112656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ERR_STATE *es;
1113656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1114656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	es=ERR_get_state();
1115656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1116656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (es->bottom == es->top) return 0;
1117656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	es->err_flags[es->top]|=ERR_FLAG_MARK;
1118656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return 1;
1119656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
1120656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1121656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint ERR_pop_to_mark(void)
1122656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
1123656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ERR_STATE *es;
1124656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1125656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	es=ERR_get_state();
1126656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1127656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	while(es->bottom != es->top
1128656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		&& (es->err_flags[es->top] & ERR_FLAG_MARK) == 0)
1129656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
1130656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		err_clear(es,es->top);
1131656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		es->top-=1;
1132656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (es->top == -1) es->top=ERR_NUM_ERRORS-1;
1133656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
1134656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1135656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (es->bottom == es->top) return 0;
1136656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	es->err_flags[es->top]&=~ERR_FLAG_MARK;
1137656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return 1;
1138656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
1139