PageRenderTime 34ms CodeModel.GetById 11ms app.highlight 17ms RepoModel.GetById 1ms app.codeStats 0ms

/tags/wired-1.3/libwired/libwired/base/wi-error.c

https://bitbucket.org/balrog/zanka-full
C | 309 lines | 165 code | 100 blank | 44 comment | 4 complexity | 6e5d0796bfdff62fe098ec43f95231e5 MD5 | raw file
  1/* $Id$ */
  2
  3/*
  4 *  Copyright (c) 2003-2006 Axel Andersson
  5 *  All rights reserved.
  6 *
  7 *  Redistribution and use in source and binary forms, with or without
  8 *  modification, are permitted provided that the following conditions
  9 *  are met:
 10 *  1. Redistributions of source code must retain the above copyright
 11 *     notice, this list of conditions and the following disclaimer.
 12 *  2. Redistributions in binary form must reproduce the above copyright
 13 *     notice, this list of conditions and the following disclaimer in the
 14 *     documentation and/or other materials provided with the distribution.
 15 *
 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 19 * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
 20 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 22 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 24 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 25 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 26 * POSSIBILITY OF SUCH DAMAGE.
 27 */
 28
 29#include "config.h"
 30
 31#include <sys/types.h>
 32#include <sys/socket.h>
 33#include <netdb.h>
 34#include <string.h>
 35#include <errno.h>
 36#include <regex.h>
 37
 38#ifdef WI_SSL
 39#include <openssl/err.h>
 40#include <openssl/ssl.h>
 41#endif
 42
 43#include <wired/wi-assert.h>
 44#include <wired/wi-error.h>
 45#include <wired/wi-hash.h>
 46#include <wired/wi-runtime.h>
 47#include <wired/wi-string.h>
 48#include <wired/wi-thread.h>
 49
 50#include "wi-private.h"
 51
 52#define _WI_ERROR_THREAD_KEY			"_wi_error_t"
 53
 54#define _WI_ERROR_ASSERT(error) \
 55	WI_ASSERT((error) != NULL, "no wi_error_t created for thread", 0)
 56
 57
 58struct _wi_error {
 59	wi_runtime_base_t					base;
 60	
 61	wi_string_t							*string;
 62	wi_error_domain_t					domain;
 63	int32_t								code;
 64};
 65
 66
 67static wi_error_t *						_wi_error_alloc(void);
 68static wi_error_t *						_wi_error_init(wi_error_t *);
 69static void								_wi_error_dealloc(wi_runtime_instance_t *);
 70
 71static wi_error_t *						_wi_get_error(void);
 72
 73
 74static const char 						*_wi_error_strings[] = {
 75	/* WI_ERROR_NONE */
 76	"No error",
 77
 78	/* WI_ERROR_ADDRESS_NOAVAILABLEADDRESSES */
 79	"No available addresses",
 80	
 81	/* WI_ERROR_HOST_NOAVAILABLEADDRESSES */
 82	"No available addresses",
 83	
 84	/* WI_ERROR_LOG_NOSUCHFACILITY */
 85	"No such syslog facility",
 86	
 87	/* WI_ERROR_REGEXP_NOSLASH */
 88	"Missing \"/\"",
 89	/* WI_ERROR_REGEXP_INVALIDOPTION */
 90	"Invalid option",
 91	
 92	/* WI_ERROR_SETTINGS_SYNTAXERROR */
 93	"Syntax error",
 94	/* WI_ERROR_SETTINGS_UNKNOWNSETTING */
 95	"Unknown setting name",
 96	/* WI_ERROR_SETTINGS_NOSUCHUSER */
 97	"User not found",
 98	/* WI_ERROR_SETTINGS_NOSUCHGROUP */
 99	"Group not found",
100	/* WI_ERROR_SETTINGS_INVALIDPORT */
101	"Port is not in 1-65535 range",
102	/* WI_ERROR_SETTINGS_NOSUCHSERVICE */
103	"Service not found",
104
105	/* WI_ERROR_SOCKET_NOVALIDCIPHER */
106	"No valid cipher",
107	/* WI_ERROR_SOCKET_NOSSL */
108	"Socket has no SSL support",
109	/* WI_ERROR_SOCKET_EOF */
110	"End of file",
111	
112	/* WI_ERROR_TERMCAP_NOSUCHENTRY */
113	"No such entry in termcap database",
114	/* WI_ERROR_TERMCAP_TERMINFONOTFOUND */
115	"Termcap databse not found",
116
117	/* WI_ERROR_THREADS_NOTSUPP */
118	"Threads are not supported in this build",
119};
120
121static wi_runtime_id_t					_wi_error_runtime_id = WI_RUNTIME_ID_NULL;
122static wi_runtime_class_t				_wi_error_runtime_class = {
123	"wi_error_t",
124	_wi_error_dealloc,
125	NULL,
126	NULL,
127	NULL,
128	NULL
129};
130
131
132void wi_error_register(void) {
133	_wi_error_runtime_id = wi_runtime_register_class(&_wi_error_runtime_class);
134}
135
136
137
138void wi_error_initialize(void) {
139#ifdef WI_SSL
140	SSL_load_error_strings();
141#endif
142}
143
144
145
146#pragma mark -
147
148static wi_error_t * _wi_error_alloc(void) {
149	return wi_runtime_create_instance(_wi_error_runtime_id, sizeof(wi_error_t));
150}
151
152
153
154static wi_error_t * _wi_error_init(wi_error_t *error) {
155	return error;
156}
157
158
159
160static void _wi_error_dealloc(wi_runtime_instance_t *instance) {
161	wi_error_t		*error = instance;
162	
163	wi_release(error->string);
164}
165
166
167
168#pragma mark -
169
170wi_error_t * _wi_get_error(void) {
171	return wi_hash_data_for_key(wi_thread_hash(), WI_STR(_WI_ERROR_THREAD_KEY));
172}
173
174
175
176#pragma mark -
177
178void wi_error_enter_thread(void) {
179	wi_error_t		*error;
180
181	error = _wi_error_init(_wi_error_alloc());
182	wi_hash_set_data_for_key(wi_thread_hash(), error, WI_STR(_WI_ERROR_THREAD_KEY));
183	wi_release(error);
184	
185	wi_error_set_error(WI_ERROR_DOMAIN_NONE, WI_ERROR_NONE);
186}
187
188
189
190void wi_error_set_error(wi_error_domain_t domain, int code) {
191	wi_error_t		*error;
192
193	error = _wi_get_error();
194
195	_WI_ERROR_ASSERT(error);
196
197	error->domain = domain;
198	error->code = code;
199
200	wi_release(error->string);
201	error->string = NULL;
202}
203
204
205
206void wi_error_set_errno(int code) {
207	wi_error_set_error(WI_ERROR_DOMAIN_ERRNO, code);
208}
209
210
211
212void wi_error_set_ssl_error(void) {
213#ifdef WI_SSL
214	if(ERR_peek_error() != 0)
215		wi_error_set_error(WI_ERROR_DOMAIN_SSL, ERR_get_error());
216	else
217		wi_error_set_error(WI_ERROR_DOMAIN_ERRNO, errno);
218#endif
219}
220
221
222
223void wi_error_set_regex_error(regex_t *regex, int code) {
224	wi_error_t		*error;
225	char			string[256];
226
227	error = _wi_get_error();
228
229	_WI_ERROR_ASSERT(error);
230
231	error->domain = WI_ERROR_DOMAIN_REGEX;
232	error->code = code;
233	
234	wi_release(error->string);
235
236	regerror(code, regex, string, sizeof(string));
237
238	error->string = wi_string_init_with_cstring(wi_string_alloc(), string);
239}
240
241
242
243void wi_error_set_lib_error(int code) {
244	wi_error_set_error(WI_ERROR_DOMAIN_LIB, code);
245}
246
247
248
249#pragma mark -
250
251wi_string_t * wi_error_string(void) {
252	wi_error_t		*error;
253
254	error = _wi_get_error();
255
256	_WI_ERROR_ASSERT(error);
257
258	if(!error->string) {
259		switch(error->domain) {
260			case WI_ERROR_DOMAIN_ERRNO:
261				error->string = wi_string_init_with_cstring(wi_string_alloc(), strerror(error->code));
262				break;
263
264			case WI_ERROR_DOMAIN_GAI:
265				error->string = wi_string_init_with_cstring(wi_string_alloc(), gai_strerror(error->code));
266				break;
267
268			case WI_ERROR_DOMAIN_REGEX:
269				break;
270
271			case WI_ERROR_DOMAIN_SSL:
272		#ifdef WI_SSL
273				error->string = wi_string_init_with_cstring(wi_string_alloc(), ERR_reason_error_string(error->code));
274		#endif
275				break;
276
277			case WI_ERROR_DOMAIN_NONE:
278			case WI_ERROR_DOMAIN_LIB:
279				error->string = wi_string_init_with_cstring(wi_string_alloc(), _wi_error_strings[error->code]);
280				break;
281		}
282	}
283
284	return error->string;
285}
286
287
288
289wi_error_domain_t wi_error_domain(void) {
290	wi_error_t		*error;
291
292	error = _wi_get_error();
293
294	_WI_ERROR_ASSERT(error);
295
296	return error->domain;
297}
298
299
300
301int32_t wi_error_code(void) {
302	wi_error_t		*error;
303
304	error = _wi_get_error();
305
306	_WI_ERROR_ASSERT(error);
307
308	return error->code;
309}