From 51558729d89b9f3492b2ca754242ed548a579ca4 Mon Sep 17 00:00:00 2001 From: Pekka Riikonen Date: Sat, 22 Dec 2007 18:03:49 +0000 Subject: [PATCH] Added SILC errno API. Added SilcResult, generic error code and return value type. Added global silc_errno that returns last error in that thread. Deprecated SilcSocketStreamStatus, SilcResult replaces it. Backwards support remains. Deprecated SilcNetStatus, SilcResult replaces it. Backwards support remains. Added errno setting to almost all Runtime Tooolkit routines in error conditions. --- CHANGES.RUNTIME | 16 + TODO | 8 +- includes/silc.h.in | 2 + lib/silcclient/client_connect.c | 20 +- lib/silcclient/client_listener.c | 2 +- lib/silcclient/silcclient.h | 4 +- lib/silchttp/silchttpserver.c | 2 +- lib/silcutil/Makefile.ad | 6 +- lib/silcutil/silcbase64.c | 3 +- lib/silcutil/silcbitops.c | 74 +++- lib/silcutil/silcbitops.h | 14 +- lib/silcutil/silcbuffer.h | 28 +- lib/silcutil/silcbuffmt.c | 24 +- lib/silcutil/silcconfig.c | 2 +- lib/silcutil/silcdll.c | 6 +- lib/silcutil/silcerrno.c | 394 +++++++++++++++++++++ lib/silcutil/silcerrno.h | 196 ++++++++++ lib/silcutil/silcfdstream.c | 27 +- lib/silcutil/silcfdstream.h | 15 +- lib/silcutil/silcfileutil.c | 46 ++- lib/silcutil/silcfileutil.h | 11 +- lib/silcutil/silcfsm.c | 6 +- lib/silcutil/silcfsm.h | 4 +- lib/silcutil/silchashtable.c | 34 +- lib/silcutil/silclog.c | 2 +- lib/silcutil/silclog.h | 10 +- lib/silcutil/silcmemory.c | 40 ++- lib/silcutil/silcmemory.h | 14 + lib/silcutil/silcmime.c | 96 +++-- lib/silcutil/silcnet.c | 48 +-- lib/silcutil/silcnet.h | 42 +-- lib/silcutil/silcnet_i.h | 14 +- lib/silcutil/silcschedule.c | 28 +- lib/silcutil/silcsocketstream.c | 43 +-- lib/silcutil/silcsocketstream.h | 41 +-- lib/silcutil/silcsocketstream_i.h | 13 +- lib/silcutil/silcstack.c | 17 +- lib/silcutil/silcstream.h | 9 +- lib/silcutil/silcstrutil.c | 22 +- lib/silcutil/silcthread.c | 12 +- lib/silcutil/silcthread_i.h | 6 +- lib/silcutil/silctime.c | 81 +++-- lib/silcutil/silctimer.c | 37 -- lib/silcutil/silctimer_i.h | 1 + lib/silcutil/silcutf8.c | 130 ++++--- lib/silcutil/silcutil.c | 73 ++-- lib/silcutil/silcutil.h | 15 - lib/silcutil/symbian/silcsymbiannet.cpp | 64 ++-- lib/silcutil/tests/test_silcasync.c | 2 +- lib/silcutil/tests/test_silcatomic.c | 2 +- lib/silcutil/tests/test_silcbitops.c | 5 +- lib/silcutil/tests/test_silcdll.c | 2 +- lib/silcutil/tests/test_silcenv.c | 2 +- lib/silcutil/tests/test_silcfdstream.c | 2 +- lib/silcutil/tests/test_silcfsm.c | 2 +- lib/silcutil/tests/test_silchashtable.c | 4 +- lib/silcutil/tests/test_silclist.c | 2 +- lib/silcutil/tests/test_silcmime.c | 2 +- lib/silcutil/tests/test_silcnet.c | 14 +- lib/silcutil/tests/test_silcschedule.c | 2 +- lib/silcutil/tests/test_silcstack.c | 2 +- lib/silcutil/tests/test_silcstringprep.c | 2 +- lib/silcutil/tests/test_silcstrutil.c | 2 +- lib/silcutil/tests/test_silcthread.c | 2 +- lib/silcutil/tests/test_silctime.c | 2 +- lib/silcutil/tests/test_silctimer.c | 2 +- lib/silcutil/unix/silcunixnet.c | 152 ++++---- lib/silcutil/unix/silcunixsocketstream.c | 27 +- lib/silcutil/unix/silcunixthread.c | 29 +- lib/silcutil/unix/silcunixutil.c | 3 +- lib/silcutil/win32/silcwin32net.c | 142 ++++---- lib/silcutil/win32/silcwin32socketstream.c | 5 +- lib/silcutil/win32/silcwin32thread.c | 1 + lib/silcutil/win32/silcwin32util.c | 2 +- win32/libsilc/libsilc.def | 1 - 75 files changed, 1501 insertions(+), 716 deletions(-) create mode 100644 lib/silcutil/silcerrno.c create mode 100644 lib/silcutil/silcerrno.h diff --git a/CHANGES.RUNTIME b/CHANGES.RUNTIME index f333c3e1..f0995733 100644 --- a/CHANGES.RUNTIME +++ b/CHANGES.RUNTIME @@ -1,3 +1,19 @@ +Sat Dec 22 19:55:28 EET 2007 Pekka Riikonen + + * Added SILC errno API to lib/silcutil/silcerrno.[ch]. Added + SilcResult, generic error code and return value type. Added + global silc_errno that returns last error in that thread. + + * Deprecated SilcSocketStreamStatus, SilcResult replaces it. + Backwards support remains. Affected files are + lib/silcutil/silcsocketstream.[ch]. + + * Deprecated SilcNetStatus, SilcResult replaces it. Backwards + support remains. Affected files are lib/silcutil/silcnet.[ch]. + + * Added errno setting to almost all Runtime Tooolkit routines + in error conditions. + Sun Dec 16 16:18:04 EET 2007 Pekka Riikonen * Added SILC Bit Operations API to lib/silcutil/silcbitops.[ch]. diff --git a/TODO b/TODO index 20ff6e95..3dccfb86 100644 --- a/TODO +++ b/TODO @@ -249,14 +249,12 @@ Runtime library, lib/silcutil/ o Change silc_gettimeofday on Unix to use clock_gettime with REALTIME clock if it is available, otherwise use gettimeofday(). (***DONE) + o Generic SilcResult that includes all possible status and + error conditions and generic errno API. (***DONE) + (o SilcIpAddr abstraction. Ipv4 and Ipv6 support to the abstaction.) maybe - (o Generic SilcStatus or SilcResult that includes all possible status and - error conditions, including those of SILC protocol. Though, the SILC - protocol related status (currently in silcstatus.h) cannot be in - runtime library) maybe - (o SILC specific socket creation/closing routines to silcnet.h, wrappers to all send(), recv(), sendto() etc. Bad thing is that we'd have to define all socket options, sockaddrs, etc.) maybe diff --git a/includes/silc.h.in b/includes/silc.h.in index cb2f0b7b..4a20535e 100644 --- a/includes/silc.h.in +++ b/includes/silc.h.in @@ -246,7 +246,9 @@ extern "C" { #endif /* !SILC_WIN32 */ /* Include generic SILC type definitions */ +#include "silcerrno.h" #include "silctypes.h" +#include "silcbitops.h" #include "silcmutex.h" #include "silcatomic.h" #include "silcversion.h" diff --git a/lib/silcclient/client_connect.c b/lib/silcclient/client_connect.c index de87143f..aeaa374f 100644 --- a/lib/silcclient/client_connect.c +++ b/lib/silcclient/client_connect.c @@ -25,7 +25,7 @@ /* Callback called after connected to remote host */ -static void silc_client_connect_callback(SilcNetStatus status, +static void silc_client_connect_callback(SilcResult status, SilcStream stream, void *context) { SilcFSMThread fsm = context; @@ -35,33 +35,33 @@ static void silc_client_connect_callback(SilcNetStatus status, conn->internal->op = NULL; if (conn->internal->verbose) { switch (status) { - case SILC_NET_OK: + case SILC_OK: break; - case SILC_NET_UNKNOWN_IP: + case SILC_ERR_UNKNOWN_IP: client->internal->ops->say( client, conn, SILC_CLIENT_MESSAGE_ERROR, "Could not connect to host %s: unknown IP address", conn->remote_host); break; - case SILC_NET_UNKNOWN_HOST: + case SILC_ERR_UNKNOWN_HOST: client->internal->ops->say( client, conn, SILC_CLIENT_MESSAGE_ERROR, "Could not connect to host %s: unknown host name", conn->remote_host); break; - case SILC_NET_HOST_UNREACHABLE: + case SILC_ERR_UNREACHABLE: client->internal->ops->say( client, conn, SILC_CLIENT_MESSAGE_ERROR, "Could not connect to host %s: network unreachable", conn->remote_host); break; - case SILC_NET_CONNECTION_REFUSED: + case SILC_ERR_REFUSED: client->internal->ops->say( client, conn, SILC_CLIENT_MESSAGE_ERROR, "Could not connect to host %s: connection refused", conn->remote_host); break; - case SILC_NET_CONNECTION_TIMEOUT: + case SILC_ERR_TIMEOUT: client->internal->ops->say( client, conn, SILC_CLIENT_MESSAGE_ERROR, "Could not connect to host %s: connection timeout", @@ -76,7 +76,7 @@ static void silc_client_connect_callback(SilcNetStatus status, } } - if (status != SILC_NET_OK) { + if (status != SILC_OK) { /* Notify application of failure */ SILC_LOG_DEBUG(("Connecting failed")); conn->internal->status = SILC_CLIENT_CONN_ERROR; @@ -414,8 +414,8 @@ SILC_FSM_STATE(silc_client_st_connect) conn->remote_host, conn->remote_port, conn->internal->schedule); - SILC_FSM_CALL(silc_client_connect_callback(stream ? SILC_NET_OK : - SILC_NET_HOST_UNREACHABLE, + SILC_FSM_CALL(silc_client_connect_callback(stream ? SILC_OK : + SILC_ERR_UNREACHABLE, stream, fsm)); } else { /* Connect (TCP) */ diff --git a/lib/silcclient/client_listener.c b/lib/silcclient/client_listener.c index d6af269f..24ae0c74 100644 --- a/lib/silcclient/client_listener.c +++ b/lib/silcclient/client_listener.c @@ -219,7 +219,7 @@ silc_client_listener_new_connection(SilcClientListener listener, /* TCP network listener callback. Accepts new key agreement connection. Responder function. */ -static void silc_client_listener_tcp_accept(SilcNetStatus status, +static void silc_client_listener_tcp_accept(SilcResult status, SilcStream stream, void *context) { diff --git a/lib/silcclient/silcclient.h b/lib/silcclient/silcclient.h index 1edc5e90..5e6c0d42 100644 --- a/lib/silcclient/silcclient.h +++ b/lib/silcclient/silcclient.h @@ -1083,11 +1083,11 @@ silc_client_connect_to_client(SilcClient client, * stream_create_cb, app); * * // Stream callback delivers our new SilcStream context - * void stream_create_cb(SilcSocketStreamStatus status, SilcStream stream, + * void stream_create_cb(SilcResult status, SilcStream stream, * void *context) * { * ... - * if (status != SILC_SOCKET_OK) + * if (status != SILC_OK) * error(status); * * // Start key exchange diff --git a/lib/silchttp/silchttpserver.c b/lib/silchttp/silchttpserver.c index 661f1d9e..f43b26a3 100644 --- a/lib/silchttp/silchttpserver.c +++ b/lib/silchttp/silchttpserver.c @@ -403,7 +403,7 @@ static void silc_http_server_io(SilcStream stream, SilcStreamStatus status, /* Accepts new connection */ -static void silc_http_server_new_connection(SilcNetStatus status, +static void silc_http_server_new_connection(SilcResult status, SilcStream stream, void *context) { diff --git a/lib/silcutil/Makefile.ad b/lib/silcutil/Makefile.ad index f15910f5..3999d3b7 100644 --- a/lib/silcutil/Makefile.ad +++ b/lib/silcutil/Makefile.ad @@ -74,7 +74,8 @@ libsilcutil_la_SOURCES = \ silcdll.c \ silcenv.c \ silcbase64.c \ - silcbitops.c + silcbitops.c \ + silcerrno.c #ifdef SILC_DIST_TOOLKIT include_HEADERS = \ @@ -122,7 +123,8 @@ include_HEADERS = \ silcdll.h \ silcenv.h \ silcbase64.h \ - silcbitops.h + silcbitops.h \ + silcerrno.h SILC_EXTRA_DIST = tests #endif SILC_DIST_TOOLKIT diff --git a/lib/silcutil/silcbase64.c b/lib/silcutil/silcbase64.c index 441ccbc8..ba9b2c8d 100644 --- a/lib/silcutil/silcbase64.c +++ b/lib/silcutil/silcbase64.c @@ -155,9 +155,10 @@ unsigned char *silc_base64_decode(SilcStack stack, } } - switch(char_count) { + switch (char_count) { case 1: silc_sfree(stack, data); + silc_set_errno(SILC_ERR_BAD_ENCODING); return NULL; break; case 2: diff --git a/lib/silcutil/silcbitops.c b/lib/silcutil/silcbitops.c index 4eeca575..405ed539 100644 --- a/lib/silcutil/silcbitops.c +++ b/lib/silcutil/silcbitops.c @@ -30,8 +30,14 @@ SilcBool silc_bit_set(volatile unsigned long *bitmap, SilcUInt32 bitmap_size, SilcUInt32 pos = SILC_BIT_POS(bit); unsigned long mask = SILC_BIT_MASK(bit); - if (!bitmap || pos >= bitmap_size) + if (!bitmap) { + silc_set_errno(SILC_ERR_INVALID_ARGUMENT); return FALSE; + } + if (pos >= bitmap_size) { + silc_set_errno(SILC_ERR_OVERFLOW); + return FALSE; + } bitmap[pos] |= mask; return TRUE; @@ -45,8 +51,14 @@ SilcBool silc_bit_clear(volatile unsigned long *bitmap, SilcUInt32 bitmap_size, SilcUInt32 pos = SILC_BIT_POS(bit); unsigned long mask = SILC_BIT_MASK(bit); - if (!bitmap || pos >= bitmap_size) + if (!bitmap) { + silc_set_errno(SILC_ERR_INVALID_ARGUMENT); + return FALSE; + } + if (pos >= bitmap_size) { + silc_set_errno(SILC_ERR_OVERFLOW); return FALSE; + } bitmap[pos] &= ~mask; return TRUE; @@ -60,8 +72,14 @@ SilcBool silc_bit_toggle(volatile unsigned long *bitmap, SilcUInt32 pos = SILC_BIT_POS(bit); unsigned long mask = SILC_BIT_MASK(bit); - if (!bitmap || pos >= bitmap_size) + if (!bitmap) { + silc_set_errno(SILC_ERR_INVALID_ARGUMENT); + return FALSE; + } + if (pos >= bitmap_size) { + silc_set_errno(SILC_ERR_OVERFLOW); return FALSE; + } bitmap[pos] ^= mask; return TRUE; @@ -75,8 +93,14 @@ int silc_bit_test_and_set(volatile unsigned long *bitmap, SilcUInt32 pos = SILC_BIT_POS(bit); unsigned long mask = SILC_BIT_MASK(bit), ret; - if (!bitmap || pos >= bitmap_size) + if (!bitmap) { + silc_set_errno(SILC_ERR_INVALID_ARGUMENT); return -1; + } + if (pos >= bitmap_size) { + silc_set_errno(SILC_ERR_OVERFLOW); + return -1; + } ret = bitmap[pos]; bitmap[pos] ^= mask; @@ -92,8 +116,14 @@ int silc_bit_test_and_clear(volatile unsigned long *bitmap, SilcUInt32 pos = SILC_BIT_POS(bit); unsigned long mask = SILC_BIT_MASK(bit), ret; - if (!bitmap || pos >= bitmap_size) + if (!bitmap) { + silc_set_errno(SILC_ERR_INVALID_ARGUMENT); + return -1; + } + if (pos >= bitmap_size) { + silc_set_errno(SILC_ERR_OVERFLOW); return -1; + } ret = bitmap[pos]; bitmap[pos] &= ~mask; @@ -109,8 +139,14 @@ int silc_bit_test_and_toggle(volatile unsigned long *bitmap, SilcUInt32 pos = SILC_BIT_POS(bit); unsigned long mask = SILC_BIT_MASK(bit), ret; - if (!bitmap || pos >= bitmap_size) + if (!bitmap) { + silc_set_errno(SILC_ERR_INVALID_ARGUMENT); return -1; + } + if (pos >= bitmap_size) { + silc_set_errno(SILC_ERR_OVERFLOW); + return -1; + } ret = bitmap[pos]; bitmap[pos] ^= mask; @@ -126,8 +162,14 @@ int silc_bit_get(volatile unsigned long *bitmap, SilcUInt32 bitmap_size, SilcUInt32 pos = SILC_BIT_POS(bit); unsigned long mask = SILC_BIT_MASK(bit); - if (!bitmap || pos >= bitmap_size) + if (!bitmap) { + silc_set_errno(SILC_ERR_INVALID_ARGUMENT); + return -1; + } + if (pos >= bitmap_size) { + silc_set_errno(SILC_ERR_OVERFLOW); return -1; + } return (bitmap[pos] & mask) != 0; } @@ -153,13 +195,20 @@ int silc_bit_fns(volatile unsigned long *bitmap, SilcUInt32 bitmap_size, { register SilcUInt32 i; - if (!bitmap || offset >= bitmap_size * SILC_BIT_SIZE) + if (!bitmap) { + silc_set_errno(SILC_ERR_INVALID_ARGUMENT); return -1; + } + if (offset >= bitmap_size * SILC_BIT_SIZE) { + silc_set_errno(SILC_ERR_OVERFLOW); + return -1; + } for (i = offset; i < bitmap_size * SILC_BIT_SIZE; i++) if (bitmap[SILC_BIT_POS(i)] & SILC_BIT_MASK(i)) return i; + silc_set_errno(SILC_ERR_NOT_FOUND); return -1; } @@ -170,13 +219,20 @@ int silc_bit_fnz(volatile unsigned long *bitmap, SilcUInt32 bitmap_size, { register SilcUInt32 i; - if (!bitmap || offset >= bitmap_size * SILC_BIT_SIZE) + if (!bitmap) { + silc_set_errno(SILC_ERR_INVALID_ARGUMENT); + return -1; + } + if (offset >= bitmap_size * SILC_BIT_SIZE) { + silc_set_errno(SILC_ERR_OVERFLOW); return -1; + } for (i = offset; i < bitmap_size * SILC_BIT_SIZE; i++) if ((bitmap[SILC_BIT_POS(i)] & SILC_BIT_MASK(i)) == 0) return i; + silc_set_errno(SILC_ERR_NOT_FOUND); return -1; } diff --git a/lib/silcutil/silcbitops.h b/lib/silcutil/silcbitops.h index 4aa91c2e..86073b6f 100644 --- a/lib/silcutil/silcbitops.h +++ b/lib/silcutil/silcbitops.h @@ -25,7 +25,7 @@ * find bits in an arbitrarily large bitmap. The interface does not support * setting the bits atomically. * - * Example with a pre-allocate bitmap: + * Example with a pre-allocated bitmap: * * // Declare bitmap of size of 500 bits * SILC_BITMAP_DECLARE(bitmap, 500); @@ -41,7 +41,7 @@ * bit = silc_bit_ffs(bitmap, bitmap_size); * * // Find next set bit from the bitmap - * bit = silc_bit_fns(bitmap, bitmap_size, bit); + * bit = silc_bit_fns(bitmap, bitmap_size, bit + 1); * * // Clear bit number 100 * silc_bit_set(bitmap, bitmap_size, 100); @@ -184,7 +184,7 @@ int silc_bit_test_and_toggle(volatile unsigned long *bitmap, * SYNOPSIS * * int silc_bit_get(volatile unsigned long *bitmap, SilcUInt32 bitmap_size, - * ,SilcUInt32 bit); + * SilcUInt32 bit); * * DESCRIPTION * @@ -203,7 +203,7 @@ int silc_bit_get(volatile unsigned long *bitmap, SilcUInt32 bitmap_size, * DESCRIPTION * * Returns the bit number of the first set bit in the `bitmap' of size - * of `bitmap_size'. Returns -1 on error or there were no set bits. + * of `bitmap_size'. Returns -1 on error or when there were no set bits. * ***/ int silc_bit_ffs(volatile unsigned long *bitmap, SilcUInt32 bitmap_size); @@ -217,7 +217,7 @@ int silc_bit_ffs(volatile unsigned long *bitmap, SilcUInt32 bitmap_size); * DESCRIPTION * * Returns the bit number of the first zero bit in the `bitmap' of size - * of `bitmap_size'. Returns -1 on error or there were no zero bits. + * of `bitmap_size'. Returns -1 on error or when there were no zero bits. * ***/ int silc_bit_ffz(volatile unsigned long *bitmap, SilcUInt32 bitmap_size); @@ -233,7 +233,7 @@ int silc_bit_ffz(volatile unsigned long *bitmap, SilcUInt32 bitmap_size); * * Returns the bit number of the next set bit in the `bitmap' of size * of `bitmap_size' starting at bit `offset'. Returns -1 on error or - * there were no more set bits. + * when there were no more set bits. * ***/ int silc_bit_fns(volatile unsigned long *bitmap, SilcUInt32 bitmap_size, @@ -250,7 +250,7 @@ int silc_bit_fns(volatile unsigned long *bitmap, SilcUInt32 bitmap_size, * * Returns the bit number of the next zero bit in the `bitmap' of size * of `bitmap_size' starting at bit `offset'. Returns -1 on error or - * there were no more zero bits. + * when there were no more zero bits. * ***/ int silc_bit_fnz(volatile unsigned long *bitmap, SilcUInt32 bitmap_size, diff --git a/lib/silcutil/silcbuffer.h b/lib/silcutil/silcbuffer.h index 0a249cb0..30f11dc3 100644 --- a/lib/silcutil/silcbuffer.h +++ b/lib/silcutil/silcbuffer.h @@ -533,8 +533,10 @@ unsigned char *silc_buffer_pull(SilcBuffer sb, SilcUInt32 len) #ifdef SILC_DIST_INPLACE SILC_ASSERT(len <= silc_buffer_len(sb)); #endif /* SILC_DIST_INPLACE */ - if (silc_unlikely(len > silc_buffer_len(sb))) + if (silc_unlikely(len > silc_buffer_len(sb))) { + silc_set_errno(SILC_ERR_OVERFLOW); return NULL; + } sb->data += len; return old_data; @@ -579,8 +581,10 @@ unsigned char *silc_buffer_push(SilcBuffer sb, SilcUInt32 len) #ifdef SILC_DIST_INPLACE SILC_ASSERT((sb->data - len) >= sb->head); #endif /* SILC_DIST_INPLACE */ - if (silc_unlikely((sb->data - len) < sb->head)) + if (silc_unlikely((sb->data - len) < sb->head)) { + silc_set_errno(SILC_ERR_UNDERFLOW); return NULL; + } sb->data -= len; return old_data; @@ -624,8 +628,10 @@ unsigned char *silc_buffer_pull_tail(SilcBuffer sb, SilcUInt32 len) #ifdef SILC_DIST_INPLACE SILC_ASSERT(len <= silc_buffer_taillen(sb)); #endif /* SILC_DIST_INPLACE */ - if (silc_unlikely(len > silc_buffer_taillen(sb))) + if (silc_unlikely(len > silc_buffer_taillen(sb))) { + silc_set_errno(SILC_ERR_OVERFLOW); return NULL; + } sb->tail += len; return old_tail; @@ -670,8 +676,10 @@ unsigned char *silc_buffer_push_tail(SilcBuffer sb, SilcUInt32 len) #ifdef SILC_DIST_INPLACE SILC_ASSERT((sb->tail - len) >= sb->data); #endif /* SILC_DIST_INPLACE */ - if (silc_unlikely((sb->tail - len) < sb->data)) + if (silc_unlikely((sb->tail - len) < sb->data)) { + silc_set_errno(SILC_ERR_UNDERFLOW); return NULL; + } sb->tail -= len; return old_tail; @@ -712,8 +720,10 @@ unsigned char *silc_buffer_put_head(SilcBuffer sb, #ifdef SILC_DIST_INPLACE SILC_ASSERT(len <= silc_buffer_headlen(sb)); #endif /* SILC_DIST_INPLACE */ - if (silc_unlikely(len > silc_buffer_headlen(sb))) + if (silc_unlikely(len > silc_buffer_headlen(sb))) { + silc_set_errno(SILC_ERR_OVERFLOW); return NULL; + } return (unsigned char *)memcpy(sb->head, data, len); } @@ -753,8 +763,10 @@ unsigned char *silc_buffer_put(SilcBuffer sb, #ifdef SILC_DIST_INPLACE SILC_ASSERT(len <= silc_buffer_len(sb)); #endif /* SILC_DIST_INPLACE */ - if (silc_unlikely(len > silc_buffer_len(sb))) + if (silc_unlikely(len > silc_buffer_len(sb))) { + silc_set_errno(SILC_ERR_OVERFLOW); return NULL; + } return (unsigned char *)memcpy(sb->data, data, len); } @@ -794,8 +806,10 @@ unsigned char *silc_buffer_put_tail(SilcBuffer sb, #ifdef SILC_DIST_INPLACE SILC_ASSERT(len <= silc_buffer_taillen(sb)); #endif /* SILC_DIST_INPLACE */ - if (silc_unlikely(len > silc_buffer_taillen(sb))) + if (silc_unlikely(len > silc_buffer_taillen(sb))) { + silc_set_errno(SILC_ERR_OVERFLOW); return NULL; + } return (unsigned char *)memcpy(sb->tail, data, len); } diff --git a/lib/silcutil/silcbuffmt.c b/lib/silcutil/silcbuffmt.c index 36d9b481..3a789fc9 100644 --- a/lib/silcutil/silcbuffmt.c +++ b/lib/silcutil/silcbuffmt.c @@ -32,12 +32,16 @@ do { \ } while(0) /* Check that there is data to be unformatted */ -#define UNFORMAT_HAS_SPACE(b, req) \ -do { \ - if (silc_unlikely(req > silc_buffer_len(b))) \ - goto fail; \ - if (silc_unlikely((req + 1) <= 0)) \ - goto fail; \ +#define UNFORMAT_HAS_SPACE(b, req) \ +do { \ + if (silc_unlikely(req > silc_buffer_len(b))) { \ + silc_set_errno(SILC_ERR_OVERFLOW); \ + goto fail; \ + } \ + if (silc_unlikely((req + 1) <= 0)) { \ + silc_set_errno(SILC_ERR_UNDERFLOW); \ + goto fail; \ + } \ } while(0) @@ -234,8 +238,10 @@ int silc_buffer_sformat_vp(SilcStack stack, SilcBuffer dst, va_list ap) if (!offst) break; if (offst > 1) { - if (offst > silc_buffer_len(dst)) + if (offst > silc_buffer_len(dst)) { + silc_set_errno(SILC_ERR_OVERFLOW); goto fail; + } silc_buffer_pull(dst, offst); flen += offst; } else { @@ -253,6 +259,8 @@ int silc_buffer_sformat_vp(SilcStack stack, SilcBuffer dst, va_list ap) default: SILC_LOG_DEBUG(("Bad buffer formatting type `%d'. Could not " "format the data.", fmt)); + silc_set_errno_reason(SILC_ERR_INVALID_ARGUMENT, + "Bad buffer formatting type %d", fmt); goto fail; break; } @@ -644,6 +652,8 @@ int silc_buffer_sunformat_vp(SilcStack stack, SilcBuffer src, va_list ap) default: SILC_LOG_DEBUG(("Bad buffer formatting type `%d'. Could not " "format the data.", fmt)); + silc_set_errno_reason(SILC_ERR_INVALID_ARGUMENT, + "Bad buffer formatting type %d", fmt); goto fail; break; } diff --git a/lib/silcutil/silcconfig.c b/lib/silcutil/silcconfig.c index 49507005..55524a32 100644 --- a/lib/silcutil/silcconfig.c +++ b/lib/silcutil/silcconfig.c @@ -4,7 +4,7 @@ Author: Giovanni Giacobbi - Copyright (C) 2002 - 2006 Giovanni Giacobbi + Copyright (C) 2002 - 2007 Giovanni Giacobbi This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/lib/silcutil/silcdll.c b/lib/silcutil/silcdll.c index 20acef0b..59ca44d5 100644 --- a/lib/silcutil/silcdll.c +++ b/lib/silcutil/silcdll.c @@ -38,7 +38,8 @@ SilcDll silc_dll_load(const char *object_path) #else /* XXX Symbian */ #endif /* SILC_UNIX */ - SILC_LOG_ERROR(("Shared objects are not supported on this platform")); + silc_set_errno_reason(SILC_ERR_NOT_SUPPORTED, + "Shared objects are not supported on this platform"); return NULL; } @@ -66,7 +67,8 @@ void *silc_dll_getsym(SilcDll dll, const char *symbol) #else /* XXX Symbian */ #endif /* SILC_UNIX */ - SILC_LOG_ERROR(("Shared objects are not supported on this platform")); + silc_set_errno_reason(SILC_ERR_NOT_SUPPORTED, + "Shared objects are not supported on this platform"); return NULL; } diff --git a/lib/silcutil/silcerrno.c b/lib/silcutil/silcerrno.c new file mode 100644 index 00000000..1739b2da --- /dev/null +++ b/lib/silcutil/silcerrno.c @@ -0,0 +1,394 @@ +/* + + silcerrno.c + + Author: Pekka Riikonen + + Copyright (C) 2007 Pekka Riikonen + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + +*/ + +#include "silc.h" + +/* Get last error */ + +SilcResult silc_get_errno(void) +{ + SilcTls tls = silc_thread_get_tls(); + + if (!tls) + return SILC_OK; + + return tls->error; +} + +/* Set error */ + +void silc_set_errno(SilcResult error) +{ + SilcTls tls = silc_thread_get_tls(); + + if (!tls) { + /* Try to create Tls */ + tls = silc_thread_tls_init(); + if (!tls) + return; + } + + SILC_LOG_DEBUG(("Error: %s (%d)", silc_errno_string(error), error)); + + tls->error_reason[0] = '\0'; + tls->error = error; +} + +/* Set error, cannot fail. */ + +void silc_set_errno_nofail(SilcResult error) +{ + SilcTls tls = silc_thread_get_tls(); + + if (!tls) + return; + + SILC_LOG_DEBUG(("Error: %s (%d)", silc_errno_string(error), error)); + + tls->error_reason[0] = '\0'; + tls->error = error; +} + +/* Set errno and reason for error. */ + +void silc_set_errno_reason(SilcResult error, const char *format, ...) +{ + SilcTls tls = silc_thread_get_tls(); + va_list va; + + if (!tls) { + /* Try to create Tls */ + tls = silc_thread_tls_init(); + if (!tls) + return; + } + + va_start(va, format); + silc_vsnprintf(tls->error_reason, sizeof(tls->error_reason), format, va); + va_end(va); + + SILC_LOG_DEBUG(("Error: %s (%d): %s", silc_errno_string(error), error, + tls->error_reason)); + + tls->error = error; +} + +/* Set errno and reason for error, cannot fail. */ + +void silc_set_errno_reason_nofail(SilcResult error, const char *format, ...) +{ + SilcTls tls = silc_thread_get_tls(); + va_list va; + + if (!tls) + return; + + va_start(va, format); + silc_vsnprintf(tls->error_reason, sizeof(tls->error_reason), format, va); + va_end(va); + + SILC_LOG_DEBUG(("Error: %s (%d): %s", silc_errno_string(error), error, + tls->error_reason)); + + tls->error = error; +} + +/* Set error from POSIX errno. */ + +void silc_set_errno_posix(int error) +{ + if (!error) + return; + +#ifdef SILC_WIN32 + /* WSA errors */ + switch (error) { + case WSAEINTR: + silc_set_errno(SILC_ERR_INTERRUPTED); + break; + case WSAEBADF: + silc_set_errno(SILC_ERR_BAD_FD); + break; + case WSAEACCESS: + silc_set_errno(SILC_ERR_PERMISSION_DENIED); + break; + case WSAEFAULT: + silc_set_errno(SILC_ERR_BAD_ADDRESS); + break; + case WSA_INVALID_HANDLE: + case WSAENOTSOCK: + silc_set_errno(SILC_ERR_BAD_SOCKET); + break; + case WSA_INVALID_PARAMETER: + case WSAEINVAL: + silc_set_errno(SILC_ERR_INVALID_ARGUMENT); + break; + case WSA_NOT_ENOUGH_MEMORY: + silc_set_errno(SILC_ERR_OUT_OF_MEMORY); + break; + case WSAEWOULDBLOCK: + silc_set_errno(SILC_ERR_WOULD_BLOCK); + break; + case WSAEOPNOTSUPPORT: + silc_set_errno(SILC_ERR_NOT_SUPPORTED); + break; + case WSAEADDRINUSE: + silc_set_errno(SILC_ERR_ADDR_IN_USE); + break; + case WSAEANETDOWN: + silc_set_errno(SILC_ERR_NET_DOWN); + break; + case WSAENETUNREACH: + case WSAEHOSTUNREACH: + silc_set_errno(SILC_ERR_UNREACHABLE); + break; + case WSAENETRESET: + silc_set_errno(SILC_ERR_RESET); + break; + case WSAECONNABORTED: + silc_set_errno(SILC_ERR_ABORTED); + break; + case WSAETIMEDOUT: + silc_set_errno(SILC_ERR_TIMEOUT); + break; + case WSAECONNREFUSED: + silc_set_errno(SILC_ERR_REFUSED); + break; + case WSAEHOSTDOWN: + silc_set_errno(SILC_ERR_HOST_DOWN); + break; + default: + silc_set_errno(SILC_ERR); + break; + } + + return; +#endif /* SILC_WIN32 */ + + /* POSIX, etc. errors */ + switch (error) { +#if defined(ENOMEM) + case ENOMEM: + silc_set_errno(SILC_ERR_OUT_OF_MEMORY); + break; +#endif +#if defined(EAGAIN) + case EAGAIN: + silc_set_errno(SILC_ERR_WOULD_BLOCK); + break; +#endif +#if defined(EINVAL) + case EINVAL: + silc_set_errno(SILC_ERR_INVALID_ARGUMENT); + break; +#endif +#if defined(EINTR) + case EINTR: + silc_set_errno(SILC_ERR_INTERRUPTED); + break; +#endif +#if defined(EIO) + case EIO: + silc_set_errno(SILC_ERR_IO); + break; +#endif +#if defined(EPIPE) + case EPIPE: + silc_set_errno(SILC_ERR_BROKEN_PIPE); + break; +#endif +#if defined(ENOENT) + case ENOENT: + silc_set_errno(SILC_ERR_NO_SUCH_FILE); + break; +#endif +#if defined(EEXIST) + case EEXIST: + silc_set_errno(SILC_ERR_ALREADY_EXISTS); + break; +#endif +#if defined(ENOTDIR) + case ENOTDIR: + silc_set_errno(SILC_ERR_NOT_DIRECTORY); + break; +#endif +#if defined(EISDIR) + case EISDIR: + silc_set_errno(SILC_ERR_IS_DIRECTORY); + break; +#endif +#if defined(EBUSY) + case EBUSY: + silc_set_errno(SILC_ERR_BUSY); + break; +#endif +#if defined(ENODEV) + case ENODEV: + silc_set_errno(SILC_ERR_NO_SUCH_DEVICE); + break; +#endif +#if defined(ENOSPC) + case ENOSPC: + silc_set_errno(SILC_ERR_NO_SPACE_LEFT); + break; +#endif +#if defined(EROFS) + case EROFS: + silc_set_errno(SILC_ERR_READ_ONLY); + break; +#endif +#if defined(EBADFS) + case EBADFS: + silc_set_errno(SILC_ERR_BAD_FD); + break; +#endif +#if defined(EADDRINUSE) + case EADDRINUSE: + silc_set_errno(SILC_ERR_ADDR_IN_USE); + break; +#endif +#if defined(ECONNREFUSED) + case ECONNREFUSED: + silc_set_errno(SILC_ERR_REFUSED); + break; +#endif +#if defined(ECONNABORTED) + case ECONNABORTED: + silc_set_errno(SILC_ERR_ABORTED); + break; +#endif +#if defined(ECONNRESET) + case ECONNRESET: + silc_set_errno(SILC_ERR_RESET); + break; +#endif +#if defined(ENETUNREACH) + case ENETUNREACH: + silc_set_errno(SILC_ERR_UNREACHABLE); + break; +#endif +#if defined(EHOSTUNREACH) + case EHOSTUNREACH: + silc_set_errno(SILC_ERR_UNREACHABLE); + break; +#endif +#if defined(ENETDOWN) + case ENETDOWN: + silc_set_errno(SILC_ERR_NET_DOWN); + break; +#endif +#if defined(ETIMEDOUT) + case ETIMEDOUT: + silc_set_errno(SILC_ERR_TIMEOUT); + break; +#endif +#if defined(EHOSTDOWN) + case EHOSTDOWN: + silc_set_errno(SILC_ERR_HOST_DOWN); + break; +#endif + default: + silc_set_errno(SILC_ERR); + break; + } +} + +/* Get last reason for error */ + +const char *silc_errno_reason(void) +{ + SilcTls tls = silc_thread_get_tls(); + + if (!tls || tls->error_reason[0] == '\0') + return (const char *)""; + + return tls->error_reason; +} + +const char *silc_errno_strings[] = +{ + "Ok", + + "Error", + "Out of memory", + "Allocation by zero", + "Too large allocation", + "Overflow", + "Underflow", + "Feature not supported", + "Operation not permitted", + "Try again", + "Permission denied", + "Invalid argument", + "Bad time", + "Timeout", + "Assert", + "Not found", + "Unknown character", + "Prohibited character", + "Bad character encoding", + "Unsupported character encoding", + "Bad version", + "Bad memory address", + "Bad buffer encoding", + "Interrupted", + "Not valid", + "Limit reached", + + "No such file or directory", + "Already exists", + "Not a directory", + "Is a directory", + "Directory not empty", + "Device or resource busy", + "No such device", + "No space left on device", + "Broken pipe", + "Read only", + "I/O error", + "Bad file descriptor", + "End of file", + + "Bad IP address", + "Unknown IP address", + "Unknown host", + "Destination unreachable", + "Connection refused", + "Connection aborted", + "Connection reset by peer", + "Would block", + "Host is down", + "Bad socket", + "Bad stream", + "Address already in use", + "Network is down", + "End of stream", + + NULL +}; + +/* Map error to string */ + +const char *silc_errno_string(SilcResult error) +{ + if (error < 0 || error >= SILC_ERR_MAX) + return (const char *)""; + + return silc_errno_strings[error]; +} diff --git a/lib/silcutil/silcerrno.h b/lib/silcutil/silcerrno.h new file mode 100644 index 00000000..74a2b126 --- /dev/null +++ b/lib/silcutil/silcerrno.h @@ -0,0 +1,196 @@ +/* + + silcerrno.h + + Author: Pekka Riikonen + + Copyright (C) 2007 Pekka Riikonen + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + +*/ + +/****h* silcutil/SILC Errno + * + * DESCRIPTION + * + * Error codes and routines for accessing the error codes in case of + * error condition. SILC Runtime toolkit contains a global silc_errno + * that contains the error code that occurred. Each thread has their own + * silc_errno. + * + * Each silc_errno error code can be mapped to a string that can be used + * to display the error for user. Some routines may also provide detailed + * reason why the error occurred. The reason string can be retrieved for + * the last error by using silc_errno_reason. + * + * EXAMPLE + * + * // Use silc_errno + * buf = silc_file_readfile(filename, &buf_len, NULL); + * if (buf == NULL) { + * fprintf(stderr, "Error reading file %s: %s (%d)", filename, + * silc_errno_string(silc_errno), silc_errno); + * exit(1); + * } + * + * // Get the detailed reason for the error too + * if (silc_some_routine() == FALSE) { + * fprintf(stderr, "%s (%d) (%s)", silc_errno_string(silc_errno), + * silc_errno, silc_errno_reason); + * exit(1); + * } + * + ***/ + +#ifndef SILCERRNO_H +#define SILCERRNO_H + +/****d* silcutil/SilcErrnoAPI/SilcResult + * + * NAME + * + * typedef enum { ... } SilcResult; + * + * DESCRIPTION + * + * Error codes. + * + * SOURCE + */ +typedef enum { + SILC_OK = 0, /* Ok, no error */ + + /* General errors */ + SILC_ERR = 1, /* General error */ + SILC_ERR_OUT_OF_MEMORY = 2, /* Out of memory */ + SILC_ERR_ZERO_ALLOCATION = 3, /* Allocation by zero */ + SILC_ERR_TOO_LARGE_ALLOCATION = 4, /* Too large allocation */ + SILC_ERR_OVERFLOW = 5, /* Would overflow */ + SILC_ERR_UNDERFLOW = 6, /* Would underflow */ + SILC_ERR_NOT_SUPPORTED = 7, /* Feature not supported */ + SILC_ERR_NOT_PERMITTED = 8, /* Operation not permitted */ + SILC_ERR_TRY_AGAIN = 9, /* Try again */ + SILC_ERR_PERMISSION_DENIED = 10, /* Permission denied */ + SILC_ERR_INVALID_ARGUMENT = 11, /* Invalid argument */ + SILC_ERR_BAD_TIME = 13, /* Bad time value */ + SILC_ERR_TIMEOUT = 14, /* Timeout occurred */ + SILC_ERR_ASSERT = 15, /* Assertion failed */ + SILC_ERR_NOT_FOUND = 16, /* Item/entry not found */ + SILC_ERR_UNKNOWN_CHAR = 17, /* Unknown character */ + SILC_ERR_PROHIBITED_CHAR = 18, /* Prohibited character */ + SILC_ERR_BAD_CHAR_ENCODING = 19, /* Bad character encoding */ + SILC_ERR_UNSUPPORTED_CHAR_ENCODING = 20, /* Unsupported char encoding */ + SILC_ERR_BAD_VERSION = 21, /* Bad/unsupported version */ + SILC_ERR_BAD_ADDRESS = 22, /* Bad memory address */ + SILC_ERR_BAD_ENCODING = 23, /* Bad data encoding */ + SILC_ERR_INTERRUPTED = 24, /* Interrupted */ + SILC_ERR_NOT_VALID = 25, /* Not valid */ + SILC_ERR_LIMIT = 26, /* Limit reached */ + + /* File, directory and device errors */ + SILC_ERR_NO_SUCH_FILE = 40, /* No such file */ + SILC_ERR_ALREADY_EXISTS = 41, /* File already exists */ + SILC_ERR_NOT_DIRECTORY = 42, /* Not a directory */ + SILC_ERR_IS_DIRECTORY = 43, /* Is a directory */ + SILC_ERR_NOT_EMPTY = 44, /* Directory not empty */ + SILC_ERR_BUSY = 45, /* Device or resource busy */ + SILC_ERR_NO_SUCH_DEVICE = 46, /* No such device */ + SILC_ERR_NO_SPACE_LEFT = 47, /* No space left on device */ + SILC_ERR_BROKEN_PIPE = 48, /* Broken pipe */ + SILC_ERR_READ_ONLY = 49, /* Read only */ + SILC_ERR_IO = 50, /* I/O error */ + SILC_ERR_BAD_FD = 51, /* Bad file descriptor */ + SILC_ERR_EOF = 52, /* End of file */ + + /* Network errors */ + SILC_ERR_BAD_IP = 70, /* Bad IP address */ + SILC_ERR_UNKNOWN_IP = 71, /* Unknown IP address */ + SILC_ERR_UNKNOWN_HOST = 72, /* Unknown host name */ + SILC_ERR_UNREACHABLE = 73, /* Destination unreachable */ + SILC_ERR_REFUSED = 74, /* Connection refused */ + SILC_ERR_ABORTED = 75, /* Connection aborted */ + SILC_ERR_RESET = 76, /* Connection reset by peer */ + SILC_ERR_WOULD_BLOCK = 77, /* Would block */ + SILC_ERR_HOST_DOWN = 78, /* Host is down */ + SILC_ERR_BAD_SOCKET = 79, /* Bad socket */ + SILC_ERR_BAD_STREAM = 80, /* Bad stream */ + SILC_ERR_ADDR_IN_USE = 81, /* Address already in use */ + SILC_ERR_NET_DOWN = 82, /* Network is down */ + SILC_ERR_EOS = 83, /* End of stream */ + + SILC_ERR_MAX, +} SilcResult; +/***/ + +/****d* silcutil/SilcErrnoAPI/silc_errno + * + * NAME + * + * SilcResult silc_errno; + * + * DESCRIPTION + * + * Returns the error code of the last error. To map the error code to a + * string call silc_errno_string. + * + ***/ +#define silc_errno silc_get_errno() + +/****f* silcutil/SilcErrnoAPI/silc_errno_string + * + * NAME + * + * const char *silc_errno_string(SilcResult error); + * + * DESCRIPTION + * + * Returns the string of the error `errno'. This routine never returns + * NULL. + * + ***/ +const char *silc_errno_string(SilcResult error); + +/****d* silcutil/SilcErrnoAPI/silc_errno_string + * + * NAME + * + * const char *silc_errno_reason(void); + * + * DESCRIPTION + * + * Returns additional reason string for the last occurred error or "" + * if the additional information is not available. This routine never + * returns NULL. + * + ***/ +const char *silc_errno_reason(void); + +/* Low-level routines for the error handling. */ + +/* Return last error */ +SilcResult silc_get_errno(void); + +/* Set error */ +void silc_set_errno(SilcResult error); + +/* Set error, cannot fail. */ +void silc_set_errno_nofail(SilcResult error); + +/* Set error and reason string. */ +void silc_set_errno_reason(SilcResult error, const char *format, ...); + +/* Set error and reason string, cannot fail. */ +void silc_set_errno_reason_nofail(SilcResult error, const char *format, ...); + +/* Set error from POSIX errno */ +void silc_set_errno_posix(int error); + +#endif /* SILCERRNO_H */ diff --git a/lib/silcutil/silcfdstream.c b/lib/silcutil/silcfdstream.c index d2875f95..ea043f2b 100644 --- a/lib/silcutil/silcfdstream.c +++ b/lib/silcutil/silcfdstream.c @@ -34,7 +34,6 @@ typedef struct { void *notifier_context; int fd1; int fd2; - int error; } *SilcFDStream; @@ -70,8 +69,10 @@ SILC_TASK_CALLBACK(silc_fd_stream_io) SilcStream silc_fd_stream_create(int fd, SilcStack stack) { - if (fd < 1) + if (fd < 1) { + silc_set_errno_reason(SILC_ERR_BAD_FD, "Bad file descriptor %d", fd); return NULL; + } return silc_fd_stream_create2(fd, 0, stack); } @@ -107,8 +108,10 @@ SilcStream silc_fd_stream_file(const char *filename, SilcBool reading, { const char *read_file = NULL, *write_file = NULL; - if (!filename) + if (!filename) { + silc_set_errno(SILC_ERR_INVALID_ARGUMENT); return NULL; + } if (writing) write_file = filename; @@ -171,18 +174,6 @@ SilcBool silc_fd_stream_get_info(SilcStream stream, int *read_fd, return TRUE; } -/* Return errno */ - -int silc_fd_stream_get_error(SilcStream stream) -{ - SilcFDStream fd_stream = stream; - - if (!SILC_IS_FD_STREAM(fd_stream)) - return 0; - - return fd_stream->error; -} - /* Read */ int silc_fd_stream_read(SilcStream stream, unsigned char *buf, @@ -202,12 +193,13 @@ int silc_fd_stream_read(SilcStream stream, unsigned char *buf, SILC_LOG_DEBUG(("Could not read immediately, will do it later")); silc_schedule_set_listen_fd(fd_stream->schedule, fd_stream->fd1, SILC_TASK_READ, FALSE); + silc_set_errno_posix(errno); return -1; } SILC_LOG_DEBUG(("Cannot read from fd: %d:%s", fd_stream->fd1, strerror(errno))); silc_schedule_unset_listen_fd(fd_stream->schedule, fd_stream->fd1); - fd_stream->error = errno; + silc_set_errno_posix(errno); return -2; } @@ -238,11 +230,12 @@ int silc_fd_stream_write(SilcStream stream, const unsigned char *data, SILC_LOG_DEBUG(("Could not write immediately, will do it later")); silc_schedule_set_listen_fd(fd_stream->schedule, fd_stream->fd2, SILC_TASK_READ | SILC_TASK_WRITE, FALSE); + silc_set_errno_posix(errno); return -1; } SILC_LOG_DEBUG(("Cannot write to fd: %s", strerror(errno))); silc_schedule_unset_listen_fd(fd_stream->schedule, fd_stream->fd2); - fd_stream->error = errno; + silc_set_errno_posix(errno); return -2; } diff --git a/lib/silcutil/silcfdstream.h b/lib/silcutil/silcfdstream.h index 604c0b90..285c796d 100644 --- a/lib/silcutil/silcfdstream.h +++ b/lib/silcutil/silcfdstream.h @@ -144,18 +144,7 @@ SilcStream silc_fd_stream_file2(const char *read_file, const char *write_file, SilcBool silc_fd_stream_get_info(SilcStream stream, int *read_fd, int *write_fd); -/****f* silcutil/SilcFDStreamAPI/silc_fd_stream_get_error - * - * SYNOPSIS - * - * int silc_fd_stream_get_error(SilcStream stream); - * - * DESCRIPTION - * - * If error occurred during file descriptor stream operations, this - * function can be used to retrieve the error number that occurred. - * - ***/ -int silc_fd_stream_get_error(SilcStream stream); +/* Backwards support */ +#define silc_fd_stream_get_error(stream) silc_errno #endif /* SILCFDSTREAM_H */ diff --git a/lib/silcutil/silcfileutil.c b/lib/silcutil/silcfileutil.c index c28ba38f..ea48479b 100644 --- a/lib/silcutil/silcfileutil.c +++ b/lib/silcutil/silcfileutil.c @@ -34,6 +34,8 @@ int silc_file_open(const char *filename, int flags) int silc_file_open_mode(const char *filename, int flags, int mode) { int fd = open(filename, flags, mode); + if (fd < 0) + silc_set_errno_posix(errno); return fd; } @@ -41,21 +43,30 @@ int silc_file_open_mode(const char *filename, int flags, int mode) int silc_file_read(int fd, unsigned char *buf, SilcUInt32 buf_len) { - return read(fd, (void *)buf, buf_len); + int ret = read(fd, (void *)buf, buf_len); + if (ret < 0) + silc_set_errno_posix(errno); + return ret; } /* Writes `buffer' of length of `len' to file descriptor `fd'. */ int silc_file_write(int fd, const char *buffer, SilcUInt32 len) { - return write(fd, (const void *)buffer, len); + int ret = write(fd, (const void *)buffer, len); + if (ret < 0) + silc_set_errno_posix(errno); + return ret; } /* Closes file descriptor */ int silc_file_close(int fd) { - return close(fd); + int ret = close(fd); + if (ret < 0) + silc_set_errno_posix(errno); + return ret; } /* Writes a buffer to the file. */ @@ -72,12 +83,13 @@ int silc_file_writefile(const char *filename, const char *buffer, if ((fd = open(filename, flags, 0644)) == -1) { SILC_LOG_ERROR(("Cannot open file %s for writing: %s", filename, - strerror(errno))); + silc_errno_string(silc_errno))); return -1; } if (silc_file_write(fd, buffer, len) == -1) { - SILC_LOG_ERROR(("Cannot write to file %s: %s", filename, strerror(errno))); + SILC_LOG_ERROR(("Cannot write to file %s: %s", filename, + silc_errno_string(silc_errno))); silc_file_close(fd); return -1; } @@ -104,12 +116,13 @@ int silc_file_writefile_mode(const char *filename, const char *buffer, if ((fd = open(filename, flags, mode)) == -1) { SILC_LOG_ERROR(("Cannot open file %s for writing: %s", filename, - strerror(errno))); + silc_errno_string(silc_errno))); return -1; } if ((silc_file_write(fd, buffer, len)) == -1) { - SILC_LOG_ERROR(("Cannot write to file %s: %s", filename, strerror(errno))); + SILC_LOG_ERROR(("Cannot write to file %s: %s", filename, + silc_errno_string(silc_errno))); silc_file_close(fd); return -1; } @@ -133,24 +146,21 @@ char *silc_file_readfile(const char *filename, SilcUInt32 *return_len, fd = silc_file_open(filename, O_RDONLY); if (fd < 0) { - if (errno == ENOENT) + if (silc_errno == SILC_ERR_NO_SUCH_FILE) return NULL; - SILC_LOG_ERROR(("Cannot open file %s: %s", filename, strerror(errno))); + SILC_LOG_ERROR(("Cannot open file %s: %s", filename, + silc_errno_string(silc_errno))); return NULL; } filelen = lseek(fd, (off_t)0L, SEEK_END); if (filelen < 0) { + silc_set_errno_posix(errno); silc_file_close(fd); return NULL; } if (lseek(fd, (off_t)0L, SEEK_SET) < 0) { - silc_file_close(fd); - return NULL; - } - - if (filelen < 0) { - SILC_LOG_ERROR(("Cannot open file %s: %s", filename, strerror(errno))); + silc_set_errno_posix(errno); silc_file_close(fd); return NULL; } @@ -161,7 +171,7 @@ char *silc_file_readfile(const char *filename, SilcUInt32 *return_len, memset(buffer, 0, sizeof(buffer)); silc_file_close(fd); SILC_LOG_ERROR(("Cannot read from file %s: %s", filename, - strerror(errno))); + silc_errno_string(silc_errno))); return NULL; } @@ -190,8 +200,10 @@ SilcUInt64 silc_file_size(const char *filename) #ifdef SILC_SYMBIAN ret = stat(filename, &stats); #endif /* SILC_SYMBIAN */ - if (ret < 0) + if (ret < 0) { + silc_set_errno_posix(errno); return 0; + } return (SilcUInt64)stats.st_size; } diff --git a/lib/silcutil/silcfileutil.h b/lib/silcutil/silcfileutil.h index 70887760..151f45a4 100644 --- a/lib/silcutil/silcfileutil.h +++ b/lib/silcutil/silcfileutil.h @@ -41,7 +41,8 @@ * * Opens a file indicated by the filename `filename' with flags indicated * by `flags'. The opening permission defaults to 0600. The `flags' - * are defined in open(2). + * are defined in open(2). Returns the opened file descriptor or -1 on + * error. * ***/ int silc_file_open(const char *filename, int flags); @@ -57,6 +58,7 @@ int silc_file_open(const char *filename, int flags); * Opens a file indicated by the filename `filename' with flags indicated * by `flags'. The argument `mode' specifies the permissions to use in * case a new file is created. The `flags' are defined in open(2). + * Returns the opened file descriptor or -1 on error. * ***/ int silc_file_open_mode(const char *filename, int flags, int mode); @@ -69,7 +71,8 @@ int silc_file_open_mode(const char *filename, int flags, int mode); * * DESCRIPTION * - * Reads data from file descriptor `fd' to `buf'. + * Reads data from file descriptor `fd' to `buf'. Returns the amount of + * bytes read, 0 on EOF or -1 on error. * ***/ int silc_file_read(int fd, unsigned char *buf, SilcUInt32 buf_len); @@ -82,7 +85,8 @@ int silc_file_read(int fd, unsigned char *buf, SilcUInt32 buf_len); * * DESCRIPTION * - * Writes `buffer' of length of `len' to file descriptor `fd'. + * Writes `buffer' of length of `len' to file descriptor `fd'. Returns + * the amount of bytes written, 0 on EOF or -1 on error. * ***/ int silc_file_write(int fd, const char *buffer, SilcUInt32 len); @@ -96,6 +100,7 @@ int silc_file_write(int fd, const char *buffer, SilcUInt32 len); * DESCRIPTION * * Closes file descriptor previously opened with silc_file_open(). + * Returns 0 on success or -1 on error. * ***/ int silc_file_close(int fd); diff --git a/lib/silcutil/silcfsm.c b/lib/silcutil/silcfsm.c index d87e0406..3cef6d96 100644 --- a/lib/silcutil/silcfsm.c +++ b/lib/silcutil/silcfsm.c @@ -58,8 +58,10 @@ SilcBool silc_fsm_init(SilcFSM fsm, void *destructor_context, SilcSchedule schedule) { - if (!schedule) + if (!schedule) { + silc_set_errno(SILC_ERR_INVALID_ARGUMENT); return FALSE; + } fsm->fsm_context = fsm_context; fsm->state_context = NULL; @@ -481,7 +483,7 @@ SILC_TASK_CALLBACK(silc_fsm_finish_fsm) } else { /* Machine must not have active threads */ - assert(silc_atomic_get_int32(&fsm->u.m.threads) == 0); + SILC_VERIFY(silc_atomic_get_int32(&fsm->u.m.threads) == 0); if (fsm->u.m.lock) { silc_mutex_free(fsm->u.m.lock); diff --git a/lib/silcutil/silcfsm.h b/lib/silcutil/silcfsm.h index 701182e3..c723bad0 100644 --- a/lib/silcutil/silcfsm.h +++ b/lib/silcutil/silcfsm.h @@ -117,8 +117,8 @@ typedef struct SilcFSMObject SilcFSMThreadStruct; * * DESCRIPTION * - * Moves to next state synchronously. This type is used is returned - * from state functions to immediately move to next state. + * Moves to next state synchronously. This type is returned from state + * functions to immediately move to next state. * * EXAMPLE * diff --git a/lib/silcutil/silchashtable.c b/lib/silcutil/silchashtable.c index dd59263f..027325b0 100644 --- a/lib/silcutil/silchashtable.c +++ b/lib/silcutil/silchashtable.c @@ -362,8 +362,10 @@ SilcHashTable silc_hash_table_alloc(SilcStack stack, SilcHashTable ht; SilcUInt32 size_index = SILC_HASH_TABLE_SIZE; - if (!hash) + if (!hash) { + silc_set_errno(SILC_ERR_INVALID_ARGUMENT); return NULL; + } if (stack) stack = silc_stack_alloc(0, stack); @@ -491,8 +493,10 @@ SilcBool silc_hash_table_del(SilcHashTable ht, void *key) entry = silc_hash_table_find_internal(ht, key, &prev, ht->hash, ht->hash_user_context, ht->compare, ht->compare_user_context); - if (*entry == NULL) + if (*entry == NULL) { + silc_set_errno(SILC_ERR_NOT_FOUND); return FALSE; + } e = *entry; @@ -537,8 +541,10 @@ SilcBool silc_hash_table_del_ext(SilcHashTable ht, void *key, compare_user_context ? compare_user_context : ht->compare_user_context); - if (*entry == NULL) + if (*entry == NULL) { + silc_set_errno(SILC_ERR_NOT_FOUND); return FALSE; + } e = *entry; @@ -582,8 +588,10 @@ SilcBool silc_hash_table_del_by_context(SilcHashTable ht, void *key, ht->hash_user_context, ht->compare, ht->compare_user_context); - if (*entry == NULL) + if (*entry == NULL) { + silc_set_errno(SILC_ERR_NOT_FOUND); return FALSE; + } e = *entry; @@ -631,8 +639,10 @@ SilcBool silc_hash_table_del_by_context_ext(SilcHashTable ht, void *key, compare_user_context ? compare_user_context : ht->compare_user_context); - if (*entry == NULL) + if (*entry == NULL) { + silc_set_errno(SILC_ERR_NOT_FOUND); return FALSE; + } e = *entry; @@ -695,8 +705,10 @@ SilcBool silc_hash_table_find_ext(SilcHashTable ht, void *key, compare_user_context ? compare_user_context : ht->compare_user_context); - if (*entry == NULL) + if (*entry == NULL) { + silc_set_errno(SILC_ERR_NOT_FOUND); return FALSE; + } if (ret_key) *ret_key = (*entry)->key; @@ -736,8 +748,10 @@ SilcBool silc_hash_table_find_by_context_ext(SilcHashTable ht, void *key, compare_user_context ? compare_user_context : ht->compare_user_context); - if (!entry || !(*entry)) + if (!entry || !(*entry)) { + silc_set_errno(SILC_ERR_NOT_FOUND); return FALSE; + } if (ret_key) *ret_key = (*entry)->key; @@ -791,8 +805,10 @@ void silc_hash_table_foreach(SilcHashTable ht, SilcHashForeach foreach, int i; SilcBool auto_rehash; - if (!foreach) - return; + if (!foreach) { + silc_set_errno(SILC_ERR_INVALID_ARGUMENT); + return FALSE; + } auto_rehash = ht->auto_rehash; ht->auto_rehash = FALSE; diff --git a/lib/silcutil/silclog.c b/lib/silcutil/silclog.c index 481dfccb..267e7305 100644 --- a/lib/silcutil/silclog.c +++ b/lib/silcutil/silclog.c @@ -424,7 +424,7 @@ void silc_log_set_debug_string(const char *debug_string) int len; if ((strchr(debug_string, '(') && strchr(debug_string, ')')) || strchr(debug_string, '$')) - string = strdup(debug_string); + string = silc_strdup(debug_string); else string = silc_string_regexify(debug_string); len = strlen(string); diff --git a/lib/silcutil/silclog.h b/lib/silcutil/silclog.h index 4ae8ca9c..80db7783 100644 --- a/lib/silcutil/silclog.h +++ b/lib/silcutil/silclog.h @@ -317,7 +317,7 @@ typedef SilcBool (*SilcLogHexdumpCb)(char *file, char *function, int line, * * DESCRIPTION * - * Verification macro that prints error message to stderr and calls + * Verification macro that prints error message to stderr and calls * abort() if the `expression' is false (ie. compares equal to zero) * on debug builds (SILC_DEBUG defined), and prints error message to * stderr on release builds (SILC_DEBUG undefined) but does not abort(). @@ -330,8 +330,12 @@ typedef SilcBool (*SilcLogHexdumpCb)(char *file, char *function, int line, #define SILC_VERIFY(expr) assert((expr)); #else #define SILC_VERIFY(expr) \ - if (!(expr)) \ - SILC_LOG_ERROR(("SILC_VERIFY %s:%d", __FUNCTION__, __LINE__)); + if (silc_unlikely(!(expr))) { \ + SILC_LOG_ERROR(("SILC_VERIFY %s:%s:%d", \ + __FILE__, __FUNCTION__, __LINE__)); \ + silc_set_errno_reason_nofail(SILC_ERR_ASSERT, "SILC_VERIFY %s:%s:%d", \ + __FILE__, __FUNCTION__, __LINE__); \ + } #endif /* SILC_DEBUG */ /***/ diff --git a/lib/silcutil/silcmemory.c b/lib/silcutil/silcmemory.c index 067cf1a3..ec8eb1e3 100644 --- a/lib/silcutil/silcmemory.c +++ b/lib/silcutil/silcmemory.c @@ -27,26 +27,40 @@ void *silc_malloc(size_t size) { void *addr; + if (silc_unlikely(size <= 0 || size >= SILC_MAX_ALLOC)) { - SILC_LOG_ERROR(("Invalid memory allocation, allocation by %x", size)); + if (size == 0) + silc_set_errno_nofail(SILC_ERR_ZERO_ALLOCATION); + else + silc_set_errno_reason_nofail(SILC_ERR_TOO_LARGE_ALLOCATION, + "Allocation by %d", size); return NULL; } + addr = malloc(size); if (silc_unlikely(!addr)) - SILC_LOG_ERROR(("System out of memory")); + silc_set_errno_nofail(SILC_ERR_OUT_OF_MEMORY); + return addr; } void *silc_calloc(size_t items, size_t size) { void *addr; + if (silc_unlikely(size * items <= 0 || size * items >= SILC_MAX_ALLOC)) { - SILC_LOG_ERROR(("Invalid memory allocation, allocation by %x", size)); + if (size == 0) + silc_set_errno_nofail(SILC_ERR_ZERO_ALLOCATION); + else + silc_set_errno_reason_nofail(SILC_ERR_TOO_LARGE_ALLOCATION, + "Allocation by %d", size); return NULL; } + addr = calloc(items, size); if (silc_unlikely(!addr)) - SILC_LOG_ERROR(("System out of memory")); + silc_set_errno_nofail(SILC_ERR_OUT_OF_MEMORY); + return addr; } @@ -54,12 +68,18 @@ void *silc_realloc(void *ptr, size_t size) { void *addr; if (silc_unlikely(size <= 0 || size >= SILC_MAX_ALLOC)) { - SILC_LOG_ERROR(("Invalid memory allocation, allocation by %x", size)); + if (size == 0) + silc_set_errno_nofail(SILC_ERR_ZERO_ALLOCATION); + else + silc_set_errno_reason_nofail(SILC_ERR_TOO_LARGE_ALLOCATION, + "Allocation by %d", size); return NULL; } + addr = realloc(ptr, size); if (silc_unlikely(!addr)) - SILC_LOG_ERROR(("System out of memory")); + silc_set_errno_nofail(SILC_ERR_OUT_OF_MEMORY); + return addr; } @@ -71,9 +91,10 @@ void silc_free(void *ptr) void *silc_memdup(const void *ptr, size_t size) { unsigned char *addr; + addr = silc_malloc(size + 1); if (silc_unlikely(!addr)) { - SILC_LOG_ERROR(("System out of memory")); + silc_set_errno_nofail(SILC_ERR_OUT_OF_MEMORY); return NULL; } memcpy((void *)addr, ptr, size); @@ -81,6 +102,11 @@ void *silc_memdup(const void *ptr, size_t size) return (void *)addr; } +char *silc_strdup(const char *str) +{ + return silc_memdup(str, strlen(str)); +} + #endif /* !SILC_STACKTRACE */ /* SilcStack aware routines */ diff --git a/lib/silcutil/silcmemory.h b/lib/silcutil/silcmemory.h index a016a204..7dc60062 100644 --- a/lib/silcutil/silcmemory.h +++ b/lib/silcutil/silcmemory.h @@ -118,6 +118,20 @@ void silc_free(void *ptr); ***/ void *silc_memdup(const void *ptr, size_t size); +/****f* silcutil/SilcMemoryAPI/silc_strdup + * + * SYNOPSIS + * + * char *silc_strdup(const char *str); + * + * DESCRIPTION + * + * Duplicates the string indicated by `str' and returns the duplicated + * string. Returns NULL on error. + * + ***/ +char *silc_strdup(const char *str); + #else #ifndef SILC_DIST_TOOLKIT #error "The stack trace is not supported in this distribution" diff --git a/lib/silcutil/silcmime.c b/lib/silcutil/silcmime.c index c3851ea2..04b23adb 100644 --- a/lib/silcutil/silcmime.c +++ b/lib/silcutil/silcmime.c @@ -187,8 +187,10 @@ SilcMime silc_mime_decode(SilcMime mime, const unsigned char *data, SILC_LOG_DEBUG(("Parsing MIME message")); - if (!data) + if (!data) { + silc_set_errno(SILC_ERR_INVALID_ARGUMENT); return NULL; + } if (!mime) { mime = silc_mime_alloc(); @@ -204,26 +206,34 @@ SilcMime silc_mime_decode(SilcMime mime, const unsigned char *data, if (data_len - i >= 2 && tmp[i] == '\r' && tmp[i + 1] == '\n') { /* Get field */ field = strchr(line, ':'); - if (!field) + if (!field) { + silc_set_errno(SILC_ERR_BAD_ENCODING); goto err; + } field = silc_memdup(line, field - line); if (!field) goto err; /* Get value. Remove whitespaces too. */ value = strchr(line, ':'); - if ((tmp + i) - value < 2) + if ((tmp + i) - value < 2) { + silc_set_errno(SILC_ERR_OVERFLOW); goto err; + } value++; for (k = 0; k < (tmp + i) - value; k++) { - if (value[k] == '\r') + if (value[k] == '\r') { + silc_set_errno(SILC_ERR_BAD_ENCODING); goto err; + } if (value[k] != ' ' && value[k] != '\t') break; } value += k; - if ((tmp + i) - value < 1) + if ((tmp + i) - value < 1) { + silc_set_errno(SILC_ERR_OVERFLOW); goto err; + } value = silc_memdup(value, (tmp + i) - value); if (!value) goto err; @@ -261,17 +271,23 @@ SilcMime silc_mime_decode(SilcMime mime, const unsigned char *data, /* Get multipart type */ value = strchr(field, '/'); - if (!value) + if (!value) { + silc_set_errno(SILC_ERR_BAD_ENCODING); goto err; + } value++; if (strchr(field, '"')) value++; - if (!strchr(field, ';')) + if (!strchr(field, ';')) { + silc_set_errno(SILC_ERR_BAD_ENCODING); goto err; + } memset(b, 0, sizeof(b)); len = (unsigned int)(strchr(field, ';') - value); - if (len > sizeof(b) - 1) + if (len > sizeof(b) - 1) { + silc_set_errno(SILC_ERR_OVERFLOW); goto err; + } strncpy(b, value, len); if (strchr(b, '"')) *strchr(b, '"') = '\0'; @@ -285,14 +301,14 @@ SilcMime silc_mime_decode(SilcMime mime, const unsigned char *data, SILC_LOG_DEBUG(("Boundary '%s'", value)); memset(b, 0, sizeof(b)); - line = strdup(value); + line = silc_strdup(value); if (strrchr(line, '"')) { *strrchr(line, '"') = '\0'; silc_snprintf(b, sizeof(b) - 1, "--%s", line + 1); - mime->boundary = strdup(line + 1); + mime->boundary = silc_strdup(line + 1); } else { silc_snprintf(b, sizeof(b) - 1, "--%s", line); - mime->boundary = strdup(line); + mime->boundary = silc_strdup(line); } silc_free(line); @@ -324,8 +340,10 @@ SilcMime silc_mime_decode(SilcMime mime, const unsigned char *data, tmp[k] == '-' && tmp[k + 1] == '-') if (!memcmp(tmp + k, b, strlen(b))) break; - if (k >= data_len) + if (k >= data_len) { + silc_set_errno(SILC_ERR_OVERFLOW); goto err; + } /* Remove preceding CRLF */ k -= 2; @@ -477,23 +495,31 @@ SilcMime silc_mime_assemble(SilcMimeAssembler assembler, SilcMime partial) SILC_LOG_DEBUG(("Assembling MIME fragments")); - if (!assembler || !partial) + if (!assembler || !partial) { + silc_set_errno(SILC_ERR_INVALID_ARGUMENT); goto err; + } type = (char *)silc_mime_get_field(partial, "Content-Type"); - if (!type) + if (!type) { + silc_set_errno(SILC_ERR_BAD_ENCODING); goto err; + } /* Get ID */ tmp = strstr(type, "id="); - if (!tmp) + if (!tmp) { + silc_set_errno(SILC_ERR_BAD_ENCODING); goto err; - if (strlen(tmp) <= 4) + } + if (strlen(tmp) <= 4) { + silc_set_errno(SILC_ERR_OVERFLOW); goto err; + } tmp += 3; if (*tmp == '"') tmp++; - id = strdup(tmp); + id = silc_strdup(tmp); if (strchr(id, ';')) *strchr(id, ';') = '\0'; if (strrchr(id, '"')) @@ -503,14 +529,18 @@ SilcMime silc_mime_assemble(SilcMimeAssembler assembler, SilcMime partial) /* Get fragment number */ tmp = strstr(type, "number="); - if (!tmp) + if (!tmp) { + silc_set_errno(SILC_ERR_BAD_ENCODING); goto err; + } tmp = strchr(tmp, '='); - if (strlen(tmp) < 2) + if (strlen(tmp) < 2) { + silc_set_errno(SILC_ERR_OVERFLOW); goto err; + } tmp++; if (strchr(tmp, ';')) { - tmp = strdup(tmp); + tmp = silc_strdup(tmp); *strchr(tmp, ';') = '\0'; number = atoi(tmp); silc_free(tmp); @@ -545,11 +575,13 @@ SilcMime silc_mime_assemble(SilcMimeAssembler assembler, SilcMime partial) tmp = strstr(type, "total="); if (tmp) { tmp = strchr(tmp, '='); - if (strlen(tmp) < 2) + if (strlen(tmp) < 2) { + silc_set_errno(SILC_ERR_OVERFLOW); goto err; + } tmp++; if (strchr(tmp, ';')) { - tmp = strdup(tmp); + tmp = silc_strdup(tmp); *strchr(tmp, ';') = '\0'; total = atoi(tmp); silc_free(tmp); @@ -583,8 +615,10 @@ SilcMime silc_mime_assemble(SilcMimeAssembler assembler, SilcMime partial) /* The fragment is in the data portion of the partial message */ data = silc_mime_get_data(p, &data_len); - if (!data) + if (!data) { + silc_set_errno(SILC_ERR_BAD_ENCODING); goto err; + } /* Assemble */ if (!compbuf) { @@ -757,7 +791,7 @@ void silc_mime_add_field(SilcMime mime, const char *field, const char *value) if (!mime || !field || !value) return; - silc_hash_table_add(mime->fields, strdup(field), strdup(value)); + silc_hash_table_add(mime->fields, silc_strdup(field), silc_strdup(value)); } /* Get field */ @@ -852,7 +886,7 @@ void silc_mime_set_multipart(SilcMime mime, const char *type, silc_snprintf(tmp, sizeof(tmp) - 1, "multipart/%s; boundary=%s", type, boundary); silc_mime_add_field(mime, "Content-Type", tmp); silc_free(mime->boundary); - mime->boundary = strdup(boundary); + mime->boundary = silc_strdup(boundary); if (mime->multiparts) return; @@ -863,8 +897,10 @@ void silc_mime_set_multipart(SilcMime mime, const char *type, SilcBool silc_mime_add_multipart(SilcMime mime, SilcMime part) { - if (!mime || !mime->multiparts || !part) + if (!mime || !mime->multiparts || !part) { + silc_set_errno(SILC_ERR_INVALID_ARGUMENT); return FALSE; + } silc_dlist_add(mime->multiparts, part); return TRUE; @@ -874,8 +910,10 @@ SilcBool silc_mime_add_multipart(SilcMime mime, SilcMime part) SilcBool silc_mime_is_multipart(SilcMime mime) { - if (!mime) + if (!mime) { + silc_set_errno(SILC_ERR_INVALID_ARGUMENT); return FALSE; + } return mime->multiparts != NULL; } @@ -884,8 +922,10 @@ SilcBool silc_mime_is_multipart(SilcMime mime) SilcDList silc_mime_get_multiparts(SilcMime mime, const char **type) { - if (!mime) + if (!mime) { + silc_set_errno(SILC_ERR_INVALID_ARGUMENT); return NULL; + } if (type) *type = (const char *)mime->multitype; diff --git a/lib/silcutil/silcnet.c b/lib/silcutil/silcnet.c index 17c17d83..027d7089 100644 --- a/lib/silcutil/silcnet.c +++ b/lib/silcutil/silcnet.c @@ -4,7 +4,7 @@ Author: Pekka Riikonen - Copyright (C) 1997 - 2006 Pekka Riikonen + Copyright (C) 1997 - 2007 Pekka Riikonen This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -87,38 +87,22 @@ char **silc_net_listener_get_hostname(SilcNetListener listener, return hs; } -static const char *silc_net_error[] = { - "Ok", - "Unknown IP address", - "Unknown hostname", - "Destination unreachable", - "Connection refused", - "Connection timeout", - "System out of memory", - "Unexpected error", -}; - -/* Return error as string */ - -const char *silc_net_get_error_string(SilcNetStatus error) -{ - if (error < SILC_NET_OK || error > SILC_NET_ERROR) - return ""; - return silc_net_error[error]; -} - /* Accepts a connection from a particular socket */ int silc_net_accept_connection(int sock) { - return accept(sock, 0, 0); + int ret = accept(sock, 0, 0); + if (ret < 0) + silc_set_errno_posix(errno); } /* Sets a option for a socket. */ int silc_net_set_socket_opt(int sock, int level, int option, int on) { - return setsockopt(sock, level, option, (void *)&on, sizeof(on)); + int ret = setsockopt(sock, level, option, (void *)&on, sizeof(on)); + if (ret < 0) + silc_set_errno_posix(errno); } /* Get socket options */ @@ -126,7 +110,9 @@ int silc_net_set_socket_opt(int sock, int level, int option, int on) int silc_net_get_socket_opt(int sock, int level, int option, void *optval, int *opt_len) { - return getsockopt(sock, level, option, optval, opt_len); + int ret = getsockopt(sock, level, option, optval, opt_len); + if (ret < 0) + silc_set_errno_posix(errno); } /* Checks whether IP address sent as argument is valid IPv4 address. */ @@ -204,7 +190,7 @@ static void *silc_net_gethostbyname_thread(void *context) char tmp[64]; if (silc_net_gethostbyname(r->input, r->prefer_ipv6, tmp, sizeof(tmp))) - r->result = strdup(tmp); + r->result = silc_strdup(tmp); silc_schedule_task_add(schedule, 0, silc_net_resolve_completion, r, 0, 1, SILC_TASK_TIMEOUT); @@ -221,7 +207,7 @@ static void *silc_net_gethostbyaddr_thread(void *context) char tmp[256]; if (silc_net_gethostbyaddr(r->input, tmp, sizeof(tmp))) - r->result = strdup(tmp); + r->result = silc_strdup(tmp); silc_schedule_task_add(schedule, 0, silc_net_resolve_completion, r, 0, 1, SILC_TASK_TIMEOUT); @@ -315,7 +301,7 @@ void silc_net_gethostbyname_async(const char *name, r->context = context; r->prefer_ipv6 = prefer_ipv6; r->schedule = schedule; - r->input = strdup(name); + r->input = silc_strdup(name); silc_thread_create(silc_net_gethostbyname_thread, r, FALSE); } @@ -370,7 +356,7 @@ void silc_net_gethostbyaddr_async(const char *addr, r->completion = completion; r->context = context; r->schedule = schedule; - r->input = strdup(addr); + r->input = silc_strdup(addr); silc_thread_create(silc_net_gethostbyaddr_thread, r, FALSE); } @@ -610,10 +596,10 @@ char *silc_net_localhost(void) return NULL; if (!silc_net_gethostbyname(hostname, TRUE, ip_addr, sizeof(ip_addr))) - return strdup(hostname); + return silc_strdup(hostname); silc_net_gethostbyaddr(ip_addr, hostname, sizeof(hostname)); - return strdup(hostname); + return silc_strdup(hostname); } /* Returns local IP address */ @@ -628,5 +614,5 @@ char *silc_net_localip(void) if (!silc_net_gethostbyname(hostname, TRUE, ip_addr, sizeof(ip_addr))) return NULL; - return strdup(ip_addr); + return silc_strdup(ip_addr); } diff --git a/lib/silcutil/silcnet.h b/lib/silcutil/silcnet.h index ffd5bfc3..4d44eced 100644 --- a/lib/silcutil/silcnet.h +++ b/lib/silcutil/silcnet.h @@ -48,36 +48,11 @@ ***/ typedef struct SilcNetListenerStruct *SilcNetListener; -/****d* silcutil/SilcNetAPI/SilcNetStatus - * - * NAME - * - * typedef enum { ... } SilcNetStatus; - * - * DESCRIPTION - * - * Status to indicate the result of the network operation creation. This - * type is returned in the SilcNetCallback callback function. - * - * SOURCE - */ -typedef enum { - SILC_NET_OK, /* Everything Ok */ - SILC_NET_UNKNOWN_IP, /* Unknown IP address */ - SILC_NET_UNKNOWN_HOST, /* Unknown hostname */ - SILC_NET_HOST_UNREACHABLE, /* Destination unreachable */ - SILC_NET_CONNECTION_REFUSED, /* Connection refused */ - SILC_NET_CONNECTION_TIMEOUT, /* Connection timedout */ - SILC_NET_NO_MEMORY, /* System out of memory */ - SILC_NET_ERROR, /* Unknown error */ -} SilcNetStatus; -/***/ - /****f* silcutil/SilcNetAPI/SilcNetCallback * * SYNOPSIS * - * typedef void (*SilcNetCallback)(SilcNetStatus status, + * typedef void (*SilcNetCallback)(SilcResult status, * SilcStream stream, void *context); * * DESCRIPTION @@ -95,7 +70,7 @@ typedef enum { * the `stream'. * ***/ -typedef void (*SilcNetCallback)(SilcNetStatus status, +typedef void (*SilcNetCallback)(SilcResult status, SilcStream stream, void *context); /****f* silcutil/SilcNetAPI/silc_net_tcp_create_listener @@ -374,19 +349,6 @@ int silc_net_udp_send(SilcStream stream, const char *remote_ip_addr, int remote_port, const unsigned char *data, SilcUInt32 data_len); -/****f* silcutil/SilcNetAPI/silc_net_get_error_string - * - * SYNOPSIS - * - * const char silc_net_get_error_string(SilcNetStatus error); - * - * DESCRIPTION - * - * Return `error' as a string. - * - ***/ -const char *silc_net_get_error_string(SilcNetStatus error); - /****f* silcutil/SilcNetAPI/silc_net_close_connection * * SYNOPSIS diff --git a/lib/silcutil/silcnet_i.h b/lib/silcutil/silcnet_i.h index a5ec1038..f8681970 100644 --- a/lib/silcutil/silcnet_i.h +++ b/lib/silcutil/silcnet_i.h @@ -4,7 +4,7 @@ Author: Pekka Riikonen - Copyright (C) 2005 - 2006 Pekka Riikonen + Copyright (C) 2005 - 2007 Pekka Riikonen This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -35,4 +35,16 @@ struct SilcNetListenerStruct { unsigned int lookup : 1; }; +/* Backwards support */ +#define SilcNetStatus SilcResult +#define silc_net_get_error_string silc_errno_string +#define SILC_NET_OK SILC_OK +#define SILC_NET_UNKNOWN_IP SILC_ERR_UNKNOWN_IP +#define SILC_NET_UNKNOWN_HOST SILC_ERR_UNKNOWN_HOST +#define SILC_NET_HOST_UNREACHABLE SILC_ERR_UNREACHABLE +#define SILC_NET_CONNECTION_REFUSED SILC_ERR_REFUSED +#define SILC_NET_CONNECTION_TIMEOUT SILC_ERR_TIMEOUT +#define SILC_NET_NO_MEMORY SILC_ERR_OUT_OF_MEMORY +#define SILC_NET_ERROR SILC_ERR + #endif /* SILCNET_I_H */ diff --git a/lib/silcutil/silcschedule.c b/lib/silcutil/silcschedule.c index ccd9abdb..d2ad0c92 100644 --- a/lib/silcutil/silcschedule.c +++ b/lib/silcutil/silcschedule.c @@ -317,6 +317,9 @@ SilcSchedule silc_schedule_init(int max_tasks, void *app_context, { SilcSchedule schedule; + /* Initialize Tls, in case it hasn't been done yet */ + silc_thread_tls_init(); + stack = silc_stack_alloc(0, stack); if (!stack) return NULL; @@ -581,8 +584,10 @@ SilcTask silc_schedule_task_add(SilcSchedule schedule, SilcUInt32 fd, { SilcTask task = NULL; - if (silc_unlikely(!schedule->valid)) + if (silc_unlikely(!schedule->valid)) { + silc_set_errno(SILC_ERR_NOT_VALID); return NULL; + } SILC_SCHEDULE_LOCK(schedule); @@ -661,6 +666,7 @@ SilcTask silc_schedule_task_add(SilcSchedule schedule, SilcUInt32 fd, schedule->max_tasks)) { SILC_LOG_WARNING(("Scheduler task limit reached: cannot add new task")); task = NULL; + silc_set_errno(SILC_ERR_LIMIT); goto out; } @@ -805,6 +811,9 @@ SilcBool silc_schedule_task_del_by_fd(SilcSchedule schedule, SilcUInt32 fd) ret = TRUE; } + if (ret == FALSE) + silc_set_errno(SILC_ERR_NOT_FOUND); + return ret; } @@ -855,6 +864,9 @@ SilcBool silc_schedule_task_del_by_callback(SilcSchedule schedule, SILC_SCHEDULE_UNLOCK(schedule); + if (ret == FALSE) + silc_set_errno(SILC_ERR_NOT_FOUND); + return ret; } @@ -905,6 +917,9 @@ SilcBool silc_schedule_task_del_by_context(SilcSchedule schedule, SILC_SCHEDULE_UNLOCK(schedule); + if (ret == FALSE) + silc_set_errno(SILC_ERR_NOT_FOUND); + return ret; } @@ -943,6 +958,9 @@ SilcBool silc_schedule_task_del_by_all(SilcSchedule schedule, int fd, SILC_SCHEDULE_UNLOCK(schedule); + if (ret == FALSE) + silc_set_errno(SILC_ERR_NOT_FOUND); + return TRUE; } @@ -955,8 +973,10 @@ SilcBool silc_schedule_set_listen_fd(SilcSchedule schedule, SilcUInt32 fd, { SilcTaskFd task; - if (silc_unlikely(!schedule->valid)) + if (silc_unlikely(!schedule->valid)) { + silc_set_errno(SILC_ERR_NOT_VALID); return FALSE; + } SILC_SCHEDULE_LOCK(schedule); @@ -992,8 +1012,10 @@ SilcTaskEvent silc_schedule_get_fd_events(SilcSchedule schedule, SilcTaskFd task; SilcTaskEvent event = 0; - if (silc_unlikely(!schedule->valid)) + if (silc_unlikely(!schedule->valid)) { + silc_set_errno(SILC_ERR_NOT_VALID); return 0; + } SILC_SCHEDULE_LOCK(schedule); if (silc_hash_table_find(schedule->fd_queue, SILC_32_TO_PTR(fd), diff --git a/lib/silcutil/silcsocketstream.c b/lib/silcutil/silcsocketstream.c index e4b59f5a..5e335743 100644 --- a/lib/silcutil/silcsocketstream.c +++ b/lib/silcutil/silcsocketstream.c @@ -43,7 +43,7 @@ SilcSchedule silc_socket_stream_get_schedule(SilcStream stream); /* Internal async host lookup context. */ typedef struct { SilcSocketStream stream; - SilcSocketStreamStatus status; + SilcResult status; SilcSocketStreamCallback callback; SilcAsyncOperation op; void *context; @@ -71,7 +71,7 @@ SILC_TASK_CALLBACK(silc_socket_host_lookup_finish) return; } - if (lookup->status != SILC_SOCKET_OK) { + if (lookup->status != SILC_OK) { SILC_LOG_DEBUG(("Socket stream lookup failed")); stream->schedule = NULL; silc_socket_stream_destroy(stream); @@ -99,24 +99,24 @@ static void *silc_socket_host_lookup_start(void *context) silc_net_check_host_by_sock(stream->sock, &stream->hostname, &stream->ip); if (!stream->ip) { - lookup->status = SILC_SOCKET_UNKNOWN_IP; + lookup->status = SILC_ERR_UNKNOWN_IP; goto out; } if (!stream->hostname && lookup->require_fqdn) { - lookup->status = SILC_SOCKET_UNKNOWN_HOST; + lookup->status = SILC_ERR_UNKNOWN_HOST; goto out; } if (!stream->hostname) { - stream->hostname = strdup(stream->ip); + stream->hostname = silc_strdup(stream->ip); if (!stream->hostname) { - lookup->status = SILC_SOCKET_NO_MEMORY; + lookup->status = SILC_ERR_OUT_OF_MEMORY; goto out; } } - lookup->status = SILC_SOCKET_OK; + lookup->status = SILC_OK; out: silc_schedule_task_add_timeout(schedule, silc_socket_host_lookup_finish, @@ -155,14 +155,14 @@ silc_socket_tcp_stream_create(SilcSocket sock, SilcBool lookup, if (!sock || !schedule) { SILC_LOG_ERROR(("Missing arguments to silc_socket_tcp_stream_create")); if (callback) - callback(SILC_SOCKET_ERROR, NULL, context); + callback(SILC_ERR_INVALID_ARGUMENT, NULL, context); return NULL; } stream = silc_calloc(1, sizeof(*stream)); if (!stream) { if (callback) - callback(SILC_SOCKET_NO_MEMORY, NULL, context); + callback(silc_errno, NULL, context); return NULL; } @@ -177,7 +177,7 @@ silc_socket_tcp_stream_create(SilcSocket sock, SilcBool lookup, if (!l) { silc_free(stream); if (callback) - callback(SILC_SOCKET_NO_MEMORY, NULL, context); + callback(silc_errno, NULL, context); return NULL; } @@ -193,7 +193,7 @@ silc_socket_tcp_stream_create(SilcSocket sock, SilcBool lookup, silc_free(stream); silc_free(l); if (callback) - callback(SILC_SOCKET_ERROR, NULL, context); + callback(silc_errno, NULL, context); return NULL; } @@ -203,7 +203,7 @@ silc_socket_tcp_stream_create(SilcSocket sock, SilcBool lookup, return l->op; } else { /* No lookup */ - l->status = SILC_SOCKET_OK; + l->status = SILC_OK; silc_socket_host_lookup_finish(schedule, silc_schedule_get_context(schedule), 0, 0, l); @@ -296,17 +296,17 @@ SilcBool silc_socket_stream_set_info(SilcStream stream, if (hostname) { silc_free(socket_stream->hostname); - socket_stream->hostname = strdup(hostname); + socket_stream->hostname = silc_strdup(hostname); if (!socket_stream->hostname) return FALSE; } if (ip) { silc_free(socket_stream->ip); - socket_stream->ip = strdup(ip); + socket_stream->ip = silc_strdup(ip); if (!socket_stream->ip) return FALSE; if (!socket_stream->hostname) { - socket_stream->hostname = strdup(ip); + socket_stream->hostname = silc_strdup(ip); if (!socket_stream->hostname) return FALSE; } @@ -317,19 +317,6 @@ SilcBool silc_socket_stream_set_info(SilcStream stream, return TRUE; } -/* Return socket errno */ - -int silc_socket_stream_get_error(SilcStream stream) -{ - SilcSocketStream socket_stream = stream; - - if (!SILC_IS_SOCKET_STREAM(socket_stream) && - !SILC_IS_SOCKET_STREAM_UDP(socket_stream)) - return 0; - - return socket_stream->sock_error; -} - /* Set QoS for socket stream */ SilcBool silc_socket_stream_set_qos(SilcStream stream, diff --git a/lib/silcutil/silcsocketstream.h b/lib/silcutil/silcsocketstream.h index e9fd4357..42990936 100644 --- a/lib/silcutil/silcsocketstream.h +++ b/lib/silcutil/silcsocketstream.h @@ -35,34 +35,11 @@ #ifndef SILCSOCKETSTREAM_H #define SILCSOCKETSTREAM_H -/****d* silcutil/SilcSocketStreamAPI/SilcSocketStreamStatus - * - * NAME - * - * typedef enum { ... } SilcStreamStatus; - * - * DESCRIPTION - * - * Socket Stream status. This status is returned into the - * SilcSocketStreamCallback function after the socket stream is - * created. - * - * SOURCE - */ -typedef enum { - SILC_SOCKET_OK, /* Normal status */ - SILC_SOCKET_UNKNOWN_IP, /* Remote does not have IP address */ - SILC_SOCKET_UNKNOWN_HOST, /* Remote does not have host name */ - SILC_SOCKET_NO_MEMORY, /* System out of memory */ - SILC_SOCKET_ERROR, /* Unknown error */ -} SilcSocketStreamStatus; -/***/ - /****f* silcutil/SilcSocketStreamAPI/SilcSocketStreamCallback * * SYNOPSIS * - * typedef void (*SilcSocketStreamCallback)(SilcSocketStreamStatus status, + * typedef void (*SilcSocketStreamCallback)(SilcResult status, * SilcStream stream, * void *context); * @@ -82,7 +59,7 @@ typedef enum { * non-blocking mode. * ***/ -typedef void (*SilcSocketStreamCallback)(SilcSocketStreamStatus status, +typedef void (*SilcSocketStreamCallback)(SilcResult status, SilcStream stream, void *context); /****f* silcutil/SilcSocketStreamAPI/silc_socket_tcp_stream_create @@ -231,20 +208,6 @@ SilcBool silc_socket_stream_set_info(SilcStream stream, const char *hostname, const char *ip, SilcUInt16 port); -/****f* silcutil/SilcSocketStreamAPI/silc_socket_stream_get_error - * - * SYNOPSIS - * - * int silc_socket_stream_get_error(SilcStream stream); - * - * DESCRIPTION - * - * If error occurred during socket stream operations, this function - * can be used to retrieve the error number that occurred. - * - ***/ -int silc_socket_stream_get_error(SilcStream stream); - /****f* silcutil/SilcSocketStreamAPI/silc_socket_stream_set_qos * * SYNOPSIS diff --git a/lib/silcutil/silcsocketstream_i.h b/lib/silcutil/silcsocketstream_i.h index 50385df3..b82024fa 100644 --- a/lib/silcutil/silcsocketstream_i.h +++ b/lib/silcutil/silcsocketstream_i.h @@ -4,7 +4,7 @@ Author: Pekka Riikonen - Copyright (C) 2005 - 2006 Pekka Riikonen + Copyright (C) 2005 - 2007 Pekka Riikonen This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -47,11 +47,10 @@ struct SilcSocketStreamStruct { SilcSocket sock; char *hostname; char *ip; - SilcUInt16 port; - SilcUInt16 sock_error; SilcSocketQos qos; SilcStreamNotifier notifier; void *notifier_context; + SilcUInt16 port; unsigned int ipv6 : 1; /* UDP IPv6 */ unsigned int connected : 1; /* UDP connected state */ }; @@ -62,4 +61,12 @@ struct SilcSocketStreamStruct { extern const SilcStreamOps silc_socket_stream_ops; extern const SilcStreamOps silc_socket_udp_stream_ops; +/* Backwards support */ +#define silc_socket_stream_get_error(stream) silc_errno +#define SILC_SOCKET_OK SILC_OK +#define SILC_SOCKET_UNKNOWN_IP SILC_ERR_UNKNOWN_IP +#define SILC_SOCKET_UNKNOWN_HOST SILC_ERR_UNKNOWN_HOST +#define SILC_SOCKET_NO_MEMORY SILC_ERR_OUT_OF_MEMORY +#define SILC_SOCKET_ERROR SILC_ERR + #endif /* SILCSOCKETSTREAM_I_H */ diff --git a/lib/silcutil/silcstack.c b/lib/silcutil/silcstack.c index 02e2e0c2..509331f2 100644 --- a/lib/silcutil/silcstack.c +++ b/lib/silcutil/silcstack.c @@ -372,13 +372,15 @@ void *silc_stack_malloc(SilcStack stack, SilcUInt32 size) SILC_ST_DEBUG(("Allocating %d bytes from %p", size, stack)); if (silc_unlikely(!size)) { - SILC_LOG_ERROR(("Allocation by zero (0)")); + SILC_LOG_DEBUG(("Allocation by zero (0)")); + silc_set_errno_nofail(SILC_ERR_ZERO_ALLOCATION); SILC_STACK_STAT(stack, num_errors, 1); return NULL; } if (silc_unlikely(size > SILC_STACK_MAX_ALLOC)) { - SILC_LOG_ERROR(("Allocating too much")); + SILC_LOG_DEBUG(("Allocating too much")); + silc_set_errno_nofail(SILC_ERR_TOO_LARGE_ALLOCATION); SILC_STACK_STAT(stack, num_errors, 1); if (stack->oom_handler) stack->oom_handler(stack, stack->oom_context); @@ -412,7 +414,8 @@ void *silc_stack_malloc(SilcStack stack, SilcUInt32 size) si++; } if (silc_unlikely(si >= SILC_STACK_BLOCK_NUM)) { - SILC_LOG_ERROR(("Allocating too large block")); + SILC_LOG_DEBUG(("Allocating too large block")); + silc_set_errno_nofail(SILC_ERR_TOO_LARGE_ALLOCATION); SILC_STACK_STAT(stack, num_errors, 1); if (stack->oom_handler) stack->oom_handler(stack, stack->oom_context); @@ -467,13 +470,15 @@ void *silc_stack_realloc(SilcStack stack, SilcUInt32 old_size, SILC_ST_DEBUG(("Reallocating %d bytes (%d) from %p", size, old_size, stack)); if (silc_unlikely(!size || !old_size)) { - SILC_LOG_ERROR(("Allocation by zero (0)")); + SILC_LOG_DEBUG(("Allocation by zero (0)")); + silc_set_errno_nofail(SILC_ERR_ZERO_ALLOCATION); SILC_STACK_STAT(stack, num_errors, 1); return NULL; } if (silc_unlikely(size > SILC_STACK_MAX_ALLOC)) { - SILC_LOG_ERROR(("Allocating too much")); + SILC_LOG_DEBUG(("Allocating too much")); + silc_set_errno_nofail(SILC_ERR_TOO_LARGE_ALLOCATION); SILC_STACK_STAT(stack, num_errors, 1); if (stack->oom_handler) stack->oom_handler(stack, stack->oom_context); @@ -492,6 +497,7 @@ void *silc_stack_realloc(SilcStack stack, SilcUInt32 old_size, if (stack->stack->data[si]->bytes_left + old_size + ((unsigned char *)ptr - (unsigned char *)sptr) != bsize) { SILC_LOG_DEBUG(("Cannot reallocate")); + silc_set_errno_nofail(SILC_ERR_BAD_ADDRESS); SILC_STACK_STAT(stack, num_errors, 1); return NULL; } @@ -506,6 +512,7 @@ void *silc_stack_realloc(SilcStack stack, SilcUInt32 old_size, } SILC_LOG_DEBUG(("Cannot reallocate in this block")); + silc_set_errno_nofail(SILC_ERR_OUT_OF_MEMORY); SILC_STACK_STAT(stack, num_errors, 1); return NULL; } diff --git a/lib/silcutil/silcstream.h b/lib/silcutil/silcstream.h index 3067313b..8195a15f 100644 --- a/lib/silcutil/silcstream.h +++ b/lib/silcutil/silcstream.h @@ -68,11 +68,6 @@ typedef void *SilcStream; typedef enum { SILC_STREAM_CAN_READ, /* Data available for reading */ SILC_STREAM_CAN_WRITE, /* Stream ready for writing */ - SILC_STREAM_EOS, /* End of stream */ - SILC_STREAM_CLOSED, /* Stream is closed */ - SILC_STREAM_INVALID, /* Stream is invalid */ - SILC_STREAM_NO_MEMORY, /* System out of memory */ - SILC_STREAM_ERROR, /* Unknown error */ } SilcStreamStatus; /***/ @@ -174,6 +169,8 @@ typedef struct { * the notifier callback will later be called with SILC_STREAM_CAN_READ * status when stream is again ready for reading. * + * If error occurred the error code can be retrieved with silc_errno. + * ***/ int silc_stream_read(SilcStream stream, unsigned char *buf, SilcUInt32 buf_len); @@ -194,6 +191,8 @@ int silc_stream_read(SilcStream stream, unsigned char *buf, * notifier callback will later be called with SILC_STREAM_CAN_WRITE * status when stream is again ready for writing. * + * If error occurred the error code can be retrieved with silc_errno. + * ***/ int silc_stream_write(SilcStream stream, const unsigned char *data, SilcUInt32 data_len); diff --git a/lib/silcutil/silcstrutil.c b/lib/silcutil/silcstrutil.c index e7344ad5..1655f213 100644 --- a/lib/silcutil/silcstrutil.c +++ b/lib/silcutil/silcstrutil.c @@ -124,10 +124,10 @@ char **silc_string_split(const char *string, char ch, int *ret_count) char **splitted = NULL, sep[1], *item, *cp; int i = 0, len; - if (!string) - return NULL; - if (!ret_count) + if (!string || !ret_count) { + silc_set_errno(SILC_ERR_INVALID_ARGUMENT); return NULL; + } splitted = silc_calloc(1, sizeof(*splitted)); if (!splitted) @@ -174,8 +174,10 @@ char *silc_string_regexify(const char *string) int i, len, count; char *regex; - if (!string) + if (!string) { + silc_set_errno(SILC_ERR_INVALID_ARGUMENT); return NULL; + } len = strlen(string); count = 4; @@ -224,8 +226,10 @@ char *silc_string_regex_combine(const char *string1, const char *string2) char *tmp; int len1, len2; - if (!string1 || !string2) + if (!string1 || !string2) { + silc_set_errno(SILC_ERR_INVALID_ARGUMENT); return NULL; + } len1 = strlen(string1); len2 = strlen(string2); @@ -245,8 +249,10 @@ int silc_string_regex_match(const char *regex, const char *string) regex_t preg; int ret = FALSE; - if (regcomp(&preg, regex, REG_NOSUB | REG_EXTENDED) != 0) + if (regcomp(&preg, regex, REG_NOSUB | REG_EXTENDED) != 0) { + silc_set_errno(SILC_ERR_INVALID_ARGUMENT); return FALSE; + } if (regexec(&preg, string, 0, NULL, 0) == 0) ret = TRUE; @@ -264,8 +270,10 @@ int silc_string_match(const char *string1, const char *string2) char *s1; int ret = FALSE; - if (!string1 || !string2) + if (!string1 || !string2) { + silc_set_errno(SILC_ERR_INVALID_ARGUMENT); return ret; + } s1 = silc_string_regexify(string1); ret = silc_string_regex_match(s1, string2); diff --git a/lib/silcutil/silcthread.c b/lib/silcutil/silcthread.c index 3ada012c..8e51a15d 100644 --- a/lib/silcutil/silcthread.c +++ b/lib/silcutil/silcthread.c @@ -319,10 +319,16 @@ SilcThreadPool silc_thread_pool_alloc(SilcStack stack, SilcThreadPool tp; int i; - if (max_threads < min_threads) + if (max_threads < min_threads) { + silc_set_errno_reason(SILC_ERR_INVALID_ARGUMENT, + "Max threads is smaller than min threads (%d < %d)", + max_threads, min_threads); return NULL; - if (!max_threads) + } + if (!max_threads) { + silc_set_errno_reason(SILC_ERR_INVALID_ARGUMENT, "Max threads is 0"); return NULL; + } if (stack) stack = silc_stack_alloc(0, stack); @@ -411,6 +417,7 @@ SilcBool silc_thread_pool_run(SilcThreadPool tp, if (tp->destroy) { silc_mutex_unlock(tp->lock); + silc_set_errno(SILC_ERR_NOT_VALID); return FALSE; } @@ -422,6 +429,7 @@ SilcBool silc_thread_pool_run(SilcThreadPool tp, /* Maximum threads reached */ if (!queuable) { silc_mutex_unlock(tp->lock); + silc_set_errno(SILC_ERR_LIMIT); return FALSE; } diff --git a/lib/silcutil/silcthread_i.h b/lib/silcutil/silcthread_i.h index 0038a616..c67fce08 100644 --- a/lib/silcutil/silcthread_i.h +++ b/lib/silcutil/silcthread_i.h @@ -29,8 +29,10 @@ with silc_calloc and freeable with silc_free, and must also be able to pre-allocate from stack. */ typedef struct SilcTlsObject { - void *thread_context; /* Context set with SILC Tls API */ - void *platform_context; /* Platform specific context */ + void *thread_context; /* Context set with SILC Tls API */ + void *platform_context; /* Platform specific context */ + char error_reason[256]; /* Reason for the error */ + SilcResult error; /* Errno, last error */ } *SilcTls, SilcTlsStruct; /* The internal Tls API. Implementation is platform specific. */ diff --git a/lib/silcutil/silctime.c b/lib/silcutil/silctime.c index 5a917172..4dc7f217 100644 --- a/lib/silcutil/silctime.c +++ b/lib/silcutil/silctime.c @@ -31,19 +31,19 @@ static SilcBool silc_time_fill(SilcTime time, unsigned int msec) { if (year > (1 << 15)) - return FALSE; + goto err; if (month < 1 || month > 12) - return FALSE; + goto err; if (day < 1 || day > 31) - return FALSE; + goto err; if (hour > 23) - return FALSE; + goto err; if (minute > 60) - return FALSE; + goto err; if (second > 61) - return FALSE; + goto err; if (msec > 1000) - return FALSE; + goto err; time->year = year; time->month = month; @@ -54,6 +54,10 @@ static SilcBool silc_time_fill(SilcTime time, time->msecond = msec; return TRUE; + + err: + silc_set_errno(SILC_ERR_BAD_TIME); + return FALSE; } /* Return time since Epoch */ @@ -78,7 +82,8 @@ SilcInt64 silc_time_msec(void) SilcInt64 silc_time_usec(void) { struct timeval curtime; - silc_gettimeofday(&curtime); + if (silc_gettimeofday(&curtime)) + silc_set_errno_posix(errno); return (curtime.tv_sec * (SilcUInt64)1000000) + curtime.tv_usec; } @@ -94,8 +99,10 @@ const char *silc_time_string(SilcInt64 time_val) else curtime = (time_t)time_val; return_time = ctime(&curtime); - if (!return_time) + if (!return_time) { + silc_set_errno(SILC_ERR_BAD_TIME); return NULL; + } return_time[strlen(return_time) - 1] = '\0'; return (const char *)return_time; @@ -120,8 +127,10 @@ SilcBool silc_time_value(SilcInt64 time_val, SilcTime ret_time) timeval = (time_t)((SilcUInt64)time_val / (SilcUInt64)1000); t = localtime(&timeval); - if (!t) + if (!t) { + silc_set_errno(SILC_ERR_BAD_TIME); return FALSE; + } memset(ret_time, 0, sizeof(*ret_time)); if (!silc_time_fill(ret_time, t->tm_year + 1900, t->tm_mon + 1, @@ -170,8 +179,10 @@ SilcBool silc_timezone(char *timezone, SilcUInt32 timezone_size) { SilcTimeStruct curtime; - if (timezone_size < 6) + if (timezone_size < 6) { + silc_set_errno(SILC_ERR_INVALID_ARGUMENT); return FALSE; + } if (!silc_time_value(0, &curtime)) return FALSE; @@ -206,6 +217,7 @@ SilcBool silc_time_universal(const char *universal_time, SilcTime ret_time) &day, &hour, &minute, &second, &z); if (ret < 3) { SILC_LOG_DEBUG(("Invalid UTC time string")); + silc_set_errno_reason(SILC_ERR_BAD_TIME, "Invalid UTC time string"); return FALSE; } @@ -221,19 +233,21 @@ SilcBool silc_time_universal(const char *universal_time, SilcTime ret_time) ret = sscanf(universal_time + (ret * 2) + 1, "%02u%02u", &hour, &minute); if (ret != 2) { SILC_LOG_DEBUG(("Malformed UTC time string")); + silc_set_errno_reason(SILC_ERR_BAD_TIME, "Malformed UTC time string"); return FALSE; } - if (hour > 23) - return FALSE; - if (minute > 60) + if (hour > 23 || minute > 60) { + silc_set_errno(SILC_ERR_BAD_TIME); return FALSE; + } ret_time->utc_hour = hour; ret_time->utc_minute = minute; ret_time->utc_east = (z == '-') ? 0 : 1; } else if (z != 'Z') { SILC_LOG_DEBUG(("Invalid timezone")); + silc_set_errno_reason(SILC_ERR_BAD_TIME, "Invalid timezone"); return FALSE; } @@ -251,11 +265,12 @@ SilcBool silc_time_universal_string(SilcTime time_val, char *ret_string, SilcUInt32 ret_string_size) { int ret, len = 0; + memset(ret_string, 0, ret_string_size); ret = silc_snprintf(ret_string, ret_string_size - 1, - "%02u%02u%02u%02u%02u%02u", - time_val->year % 100, time_val->month, time_val->day, - time_val->hour, time_val->minute, time_val->second); + "%02u%02u%02u%02u%02u%02u", + time_val->year % 100, time_val->month, time_val->day, + time_val->hour, time_val->minute, time_val->second); if (ret < 0) return FALSE; len += ret; @@ -267,8 +282,8 @@ SilcBool silc_time_universal_string(SilcTime time_val, char *ret_string, len += ret; } else { ret = silc_snprintf(ret_string + len, ret_string_size - 1 - len, - "%c%02u%02u", time_val->utc_east ? '+' : '-', - time_val->utc_hour, time_val->utc_minute); + "%c%02u%02u", time_val->utc_east ? '+' : '-', + time_val->utc_hour, time_val->utc_minute); if (ret < 0) return FALSE; len += ret; @@ -295,6 +310,7 @@ SilcBool silc_time_generalized(const char *generalized_time, SilcTime ret_time) &day, &hour, &minute, &second); if (ret < 3) { SILC_LOG_DEBUG(("Invalid generalized time string")); + silc_set_errno_reason(SILC_ERR_BAD_TIME, "Invalid generalized time string"); return FALSE; } @@ -310,6 +326,8 @@ SilcBool silc_time_generalized(const char *generalized_time, SilcTime ret_time) ret = sscanf(generalized_time + i, "%c", &z); if (ret != 1) { SILC_LOG_DEBUG(("Malformed generalized time string")); + silc_set_errno_reason(SILC_ERR_BAD_TIME, + "Malformed generalized time string"); return FALSE; } @@ -320,6 +338,8 @@ SilcBool silc_time_generalized(const char *generalized_time, SilcTime ret_time) ret = sscanf(generalized_time + i, "%u%n", &msecond, &l); if (ret != 1) { SILC_LOG_DEBUG(("Malformed generalized time string")); + silc_set_errno_reason(SILC_ERR_BAD_TIME, + "Malformed generalized time string"); return FALSE; } while (l > 4) { @@ -338,14 +358,16 @@ SilcBool silc_time_generalized(const char *generalized_time, SilcTime ret_time) if (z == '-' || z == '+') { ret = sscanf(generalized_time + i + 1, "%02u%02u", &hour, &minute); if (ret != 2) { - SILC_LOG_DEBUG(("Malformed UTC time string")); + SILC_LOG_DEBUG(("Malformed generalized time string")); + silc_set_errno_reason(SILC_ERR_BAD_TIME, + "Malformed generalized time string"); return FALSE; } - if (hour > 23) - return FALSE; - if (minute > 60) + if (hour > 23 || minute > 60) { + silc_set_errno(SILC_ERR_BAD_TIME); return FALSE; + } ret_time->utc_hour = hour; ret_time->utc_minute = minute; @@ -363,16 +385,17 @@ SilcBool silc_time_generalized_string(SilcTime time_val, char *ret_string, int len = 0, ret; memset(ret_string, 0, ret_string_size); ret = silc_snprintf(ret_string, ret_string_size - 1, - "%04u%02u%02u%02u%02u%02u", - time_val->year, time_val->month, time_val->day, time_val->hour, - time_val->minute, time_val->second); + "%04u%02u%02u%02u%02u%02u", + time_val->year, time_val->month, + time_val->day, time_val->hour, + time_val->minute, time_val->second); if (ret < 0) return FALSE; len += ret; if (time_val->msecond) { ret = silc_snprintf(ret_string + len, ret_string_size - 1 - len, - ".%lu", (unsigned long)time_val->msecond); + ".%lu", (unsigned long)time_val->msecond); if (ret < 0) return FALSE; len += ret; @@ -385,8 +408,8 @@ SilcBool silc_time_generalized_string(SilcTime time_val, char *ret_string, len += ret; } else { ret = silc_snprintf(ret_string + len, ret_string_size - 1 - len, - "%c%02u%02u", time_val->utc_east ? '+' : '-', - time_val->utc_hour, time_val->utc_minute); + "%c%02u%02u", time_val->utc_east ? '+' : '-', + time_val->utc_hour, time_val->utc_minute); if (ret < 0) return FALSE; len += ret; diff --git a/lib/silcutil/silctimer.c b/lib/silcutil/silctimer.c index 3973752e..0313a315 100644 --- a/lib/silcutil/silctimer.c +++ b/lib/silcutil/silctimer.c @@ -128,40 +128,3 @@ SilcBool silc_timer_is_running(SilcTimer timer) { return timer->running; } - -#if 0 -void silc_timer_synchronize(SilcTimer timer) -{ - SilcUInt32 tdiff, cumu, i; - SilcUInt64 t1, t2, tcumu; - - /* Sync normal timer */ - for (i = 0, cumu = 0; i < 5; i++) { - silc_timer_start(timer); - silc_timer_stop(timer); - silc_timer_value(timer, NULL, &tdiff); - cumu += tdiff; - } - - timer->sync_diff = cumu; - if (timer->sync_diff > 5) - timer->sync_diff /= 5; - - /* Sync CPU tick count */ - tcumu = 0; - t1 = silc_timer_tick(timer, FALSE); - t2 = silc_timer_tick(timer, FALSE); - tcumu += (t2 - t1); - t1 = silc_timer_tick(timer, FALSE); - t2 = silc_timer_tick(timer, FALSE); - tcumu += (t2 - t1); - t1 = silc_timer_tick(timer, FALSE); - t2 = silc_timer_tick(timer, FALSE); - tcumu += (t2 - t1); - timer->sync_tdiff = tcumu / 3; - - t1 = silc_timer_tick(timer, FALSE); - t2 = silc_timer_tick(timer, TRUE); - timer->sync_tdiff += (int)(t2 - t1); -} -#endif diff --git a/lib/silcutil/silctimer_i.h b/lib/silcutil/silctimer_i.h index cefaac04..1ecfdcdf 100644 --- a/lib/silcutil/silctimer_i.h +++ b/lib/silcutil/silctimer_i.h @@ -24,6 +24,7 @@ #error "Do not include this header directly" #endif +/* Timer context */ struct SilcTimerObject { SilcUInt64 start_sec; /* Start seconds */ SilcUInt64 timer_sec; /* Timer seconds */ diff --git a/lib/silcutil/silcutf8.c b/lib/silcutil/silcutf8.c index 1faf14c9..8bbb5ece 100644 --- a/lib/silcutil/silcutf8.c +++ b/lib/silcutil/silcutf8.c @@ -32,8 +32,10 @@ SilcUInt32 silc_utf8_encode(const unsigned char *bin, SilcUInt32 bin_len, { SilcUInt32 enclen = 0, i, charval = 0; - if (!bin || !bin_len) + if (!bin || !bin_len) { + silc_set_errno(SILC_ERR_INVALID_ARGUMENT); return 0; + } if (bin_encoding == SILC_STRING_UTF8) { if (!silc_utf8_valid(bin, bin_len)) @@ -41,7 +43,7 @@ SilcUInt32 silc_utf8_encode(const unsigned char *bin, SilcUInt32 bin_len, if (!utf8) return bin_len; if (bin_len > utf8_size) - return 0; + goto overflow; memcpy(utf8, bin, bin_len); return bin_len; } @@ -55,7 +57,7 @@ SilcUInt32 silc_utf8_encode(const unsigned char *bin, SilcUInt32 bin_len, for (i = 0; i < bin_len; i++) { if (bin[i] == '\\') { if (i + 1 >= bin_len) - return 0; + goto overflow; /* If escaped character is any of the following no processing is needed, otherwise it is a hex value and we need to read it. */ @@ -64,12 +66,14 @@ SilcUInt32 silc_utf8_encode(const unsigned char *bin, SilcUInt32 bin_len, cv != '>' && cv != ';' && cv != ' ' && cv != '#') { unsigned int hexval; if (i + 2 >= bin_len) + goto overflow; + if (sscanf(&bin[i + 1], "%02X", &hexval) != 1) { + silc_set_errno_posix(errno); return 0; - if (sscanf(&bin[i + 1], "%02X", &hexval) != 1) - return 0; + } if (utf8) { if (enclen + 1 > utf8_size) - return 0; + goto overflow; utf8[enclen] = (unsigned char)hexval; } @@ -82,7 +86,7 @@ SilcUInt32 silc_utf8_encode(const unsigned char *bin, SilcUInt32 bin_len, if (utf8) { if (enclen + 1 > utf8_size) - return 0; + goto overflow; utf8[enclen] = bin[i]; } enclen++; @@ -129,44 +133,50 @@ SilcUInt32 silc_utf8_encode(const unsigned char *bin, SilcUInt32 bin_len, break; case SILC_STRING_ASCII_ESC: SILC_NOT_IMPLEMENTED("SILC_STRING_ASCII_ESC"); + silc_set_errno(SILC_ERR_NOT_SUPPORTED); return 0; break; case SILC_STRING_BMP: if (i + 1 >= bin_len) - return 0; + goto overflow; SILC_GET16_MSB(charval, bin + i); i += 1; break; case SILC_STRING_BMP_LSB: if (i + 1 >= bin_len) - return 0; + goto overflow; SILC_GET16_LSB(charval, bin + i); i += 1; break; case SILC_STRING_UNIVERSAL: if (i + 3 >= bin_len) - return 0; + goto overflow; SILC_GET32_MSB(charval, bin + i); i += 3; break; case SILC_STRING_UNIVERSAL_LSB: if (i + 3 >= bin_len) - return 0; + goto overflow; SILC_GET32_LSB(charval, bin + i); i += 3; break; case SILC_STRING_PRINTABLE: case SILC_STRING_VISIBLE: - if (!isprint(bin[i])) + if (!isprint(bin[i])) { + silc_set_errno(SILC_ERR_PROHIBITED_CHAR); return 0; + } charval = bin[i]; break; case SILC_STRING_NUMERICAL: - if (bin[i] != 0x20 && !isdigit(bin[i])) + if (bin[i] != 0x20 && !isdigit(bin[i])) { + silc_set_errno(SILC_ERR_PROHIBITED_CHAR); return 0; + } charval = bin[i]; break; default: + silc_set_errno(SILC_ERR_INVALID_ARGUMENT); return 0; break; } @@ -174,7 +184,7 @@ SilcUInt32 silc_utf8_encode(const unsigned char *bin, SilcUInt32 bin_len, if (charval < 0x80) { if (utf8) { if (enclen > utf8_size) - return 0; + goto overflow; utf8[enclen] = (unsigned char)charval; } @@ -182,7 +192,7 @@ SilcUInt32 silc_utf8_encode(const unsigned char *bin, SilcUInt32 bin_len, } else if (charval < 0x800) { if (utf8) { if (enclen + 2 > utf8_size) - return 0; + goto overflow; utf8[enclen ] = (unsigned char )(((charval >> 6) & 0x1f) | 0xc0); utf8[enclen + 1] = (unsigned char )((charval & 0x3f) | 0x80); @@ -191,7 +201,7 @@ SilcUInt32 silc_utf8_encode(const unsigned char *bin, SilcUInt32 bin_len, } else if (charval < 0x10000) { if (utf8) { if (enclen + 3 > utf8_size) - return 0; + goto overflow; utf8[enclen ] = (unsigned char )(((charval >> 12) & 0xf) | 0xe0); utf8[enclen + 1] = (unsigned char )(((charval >> 6) & 0x3f) | 0x80); @@ -201,7 +211,7 @@ SilcUInt32 silc_utf8_encode(const unsigned char *bin, SilcUInt32 bin_len, } else if (charval < 0x200000) { if (utf8) { if (enclen + 4 > utf8_size) - return 0; + goto overflow; utf8[enclen ] = (unsigned char )(((charval >> 18) & 0x7) | 0xf0); utf8[enclen + 1] = (unsigned char )(((charval >> 12) & 0x3f) | 0x80); @@ -212,7 +222,7 @@ SilcUInt32 silc_utf8_encode(const unsigned char *bin, SilcUInt32 bin_len, } else if (charval < 0x4000000) { if (utf8) { if (enclen + 5 > utf8_size) - return 0; + goto overflow; utf8[enclen ] = (unsigned char )(((charval >> 24) & 0x3) | 0xf8); utf8[enclen + 1] = (unsigned char )(((charval >> 18) & 0x3f) | 0x80); @@ -224,7 +234,7 @@ SilcUInt32 silc_utf8_encode(const unsigned char *bin, SilcUInt32 bin_len, } else { if (utf8) { if (enclen + 6 > utf8_size) - return 0; + goto overflow; utf8[enclen ] = (unsigned char )(((charval >> 30) & 0x1) | 0xfc); utf8[enclen + 1] = (unsigned char )(((charval >> 24) & 0x3f) | 0x80); @@ -238,6 +248,10 @@ SilcUInt32 silc_utf8_encode(const unsigned char *bin, SilcUInt32 bin_len, } return enclen; + + overflow: + silc_set_errno(SILC_ERR_OVERFLOW); + return 0; } /* Decodes UTF-8 encoded string `utf8' to string of which encoding is @@ -253,13 +267,16 @@ SilcUInt32 silc_utf8_decode(const unsigned char *utf8, SilcUInt32 utf8_len, { SilcUInt32 enclen = 0, i, charval, bytes; - if (!utf8 || !utf8_len) + if (!utf8 || !utf8_len) { + silc_set_errno(SILC_ERR_INVALID_ARGUMENT); return 0; + } if (bin_encoding == SILC_STRING_UTF8) { - if (!silc_utf8_valid(utf8, utf8_len) || - utf8_len > bin_size) + if (!silc_utf8_valid(utf8, utf8_len)) return 0; + if (utf8_len > bin_size) + goto overflow; memcpy(bin, utf8, utf8_len); return utf8_len; } @@ -300,10 +317,10 @@ SilcUInt32 silc_utf8_decode(const unsigned char *utf8, SilcUInt32 utf8_len, bytes = 1; } else if ((utf8[i] & 0xe0) == 0xc0) { if (i + 1 >= utf8_len) - return 0; + goto overflow; if ((utf8[i + 1] & 0xc0) != 0x80) - return 0; + goto bad_char; charval = (utf8[i++] & 0x1f) << 6; charval |= utf8[i] & 0x3f; @@ -312,49 +329,49 @@ SilcUInt32 silc_utf8_decode(const unsigned char *utf8, SilcUInt32 utf8_len, bytes = 2; } else if ((utf8[i] & 0xf0) == 0xe0) { if (i + 2 >= utf8_len) - return 0; + goto overflow; if (((utf8[i + 1] & 0xc0) != 0x80) || ((utf8[i + 2] & 0xc0) != 0x80)) - return 0; + goto bad_char; /* Surrogates not allowed (D800-DFFF) */ if (utf8[i] == 0xed && utf8[i + 1] >= 0xa0 && utf8[i + 1] <= 0xbf && utf8[i + 2] >= 0x80 && utf8[i + 2] <= 0xbf) - return 0; + goto bad_char; charval = (utf8[i++] & 0xf) << 12; charval |= (utf8[i++] & 0x3f) << 6; charval |= utf8[i] & 0x3f; if (charval < 0x800) - return 0; + goto bad_char; bytes = 3; } else if ((utf8[i] & 0xf8) == 0xf0) { if (i + 3 >= utf8_len) - return 0; + goto overflow; if (((utf8[i + 1] & 0xc0) != 0x80) || ((utf8[i + 2] & 0xc0) != 0x80) || ((utf8[i + 3] & 0xc0) != 0x80)) - return 0; + goto bad_char; charval = ((SilcUInt32)(utf8[i++] & 0x7)) << 18; charval |= (utf8[i++] & 0x3f) << 12; charval |= (utf8[i++] & 0x3f) << 6; charval |= utf8[i] & 0x3f; if (charval < 0x10000) - return 0; + goto bad_char; bytes = 4; } else if ((utf8[i] & 0xfc) == 0xf8) { if (i + 4 >= utf8_len) - return 0; + goto overflow; if (((utf8[i + 1] & 0xc0) != 0x80) || ((utf8[i + 2] & 0xc0) != 0x80) || ((utf8[i + 3] & 0xc0) != 0x80) || ((utf8[i + 4] & 0xc0) != 0x80)) - return 0; + goto bad_char; charval = ((SilcUInt32)(utf8[i++] & 0x3)) << 24; charval |= ((SilcUInt32)(utf8[i++] & 0x3f)) << 18; @@ -362,18 +379,18 @@ SilcUInt32 silc_utf8_decode(const unsigned char *utf8, SilcUInt32 utf8_len, charval |= (utf8[i++] & 0x3f) << 6; charval |= utf8[i] & 0x3f; if (charval < 0x200000) - return 0; + goto bad_char; bytes = 5; } else if ((utf8[i] & 0xfe) == 0xfc) { if (i + 5 >= utf8_len) - return 0; + goto overflow; if (((utf8[i + 1] & 0xc0) != 0x80) || ((utf8[i + 2] & 0xc0) != 0x80) || ((utf8[i + 3] & 0xc0) != 0x80) || ((utf8[i + 4] & 0xc0) != 0x80) || ((utf8[i + 5] & 0xc0) != 0x80)) - return 0; + goto bad_char; charval = ((SilcUInt32)(utf8[i++] & 0x1)) << 30; charval |= ((SilcUInt32)(utf8[i++] & 0x3f)) << 24; @@ -382,10 +399,10 @@ SilcUInt32 silc_utf8_decode(const unsigned char *utf8, SilcUInt32 utf8_len, charval |= (utf8[i++] & 0x3f) << 6; charval |= utf8[i] & 0x3f; if (charval < 0x4000000) - return 0; + goto bad_char; bytes = 6; } else { - return 0; + goto bad_char; } switch (bin_encoding) { @@ -396,7 +413,7 @@ SilcUInt32 silc_utf8_decode(const unsigned char *utf8, SilcUInt32 utf8_len, case SILC_STRING_NUMERICAL: if (bin) { if (enclen + 1 > bin_size) - return 0; + goto overflow; bin[enclen] = (unsigned char)charval; } @@ -409,7 +426,7 @@ SilcUInt32 silc_utf8_decode(const unsigned char *utf8, SilcUInt32 utf8_len, case SILC_STRING_BMP: if (bin) { if (enclen + 2 > bin_size) - return 0; + goto overflow; SILC_PUT16_MSB(charval, bin + enclen); } enclen += 2; @@ -417,7 +434,7 @@ SilcUInt32 silc_utf8_decode(const unsigned char *utf8, SilcUInt32 utf8_len, case SILC_STRING_BMP_LSB: if (bin) { if (enclen + 2 > bin_size) - return 0; + goto overflow; SILC_PUT16_LSB(charval, bin + enclen); } enclen += 2; @@ -425,7 +442,7 @@ SilcUInt32 silc_utf8_decode(const unsigned char *utf8, SilcUInt32 utf8_len, case SILC_STRING_UNIVERSAL: if (bin) { if (enclen + 4 > bin_size) - return 0; + goto overflow; SILC_PUT32_MSB(charval, bin + enclen); } enclen += 4; @@ -433,7 +450,7 @@ SilcUInt32 silc_utf8_decode(const unsigned char *utf8, SilcUInt32 utf8_len, case SILC_STRING_UNIVERSAL_LSB: if (bin) { if (enclen + 4 > bin_size) - return 0; + goto overflow; SILC_PUT32_LSB(charval, bin + enclen); } enclen += 4; @@ -452,7 +469,7 @@ SilcUInt32 silc_utf8_decode(const unsigned char *utf8, SilcUInt32 utf8_len, if (!enclen && (cv == '#' || cv == ' ')) { if (bin) { if (enclen + 2 > bin_size) - return 0; + goto overflow; bin[enclen] = '\\'; bin[enclen + 1] = cv; } @@ -464,7 +481,7 @@ SilcUInt32 silc_utf8_decode(const unsigned char *utf8, SilcUInt32 utf8_len, if (i == utf8_len - 1 && cv == ' ') { if (bin) { if (enclen + 2 > bin_size) - return 0; + goto overflow; bin[enclen] = '\\'; bin[enclen + 1] = cv; } @@ -477,7 +494,7 @@ SilcUInt32 silc_utf8_decode(const unsigned char *utf8, SilcUInt32 utf8_len, cv == '>' || cv == ';') { if (bin) { if (enclen + 2 > bin_size) - return 0; + goto overflow; bin[enclen] = '\\'; bin[enclen + 1] = cv; } @@ -489,7 +506,7 @@ SilcUInt32 silc_utf8_decode(const unsigned char *utf8, SilcUInt32 utf8_len, if (!isprint((int)cv)) { if (bin) { if (enclen + 3 > bin_size) - return 0; + goto overflow; bin[enclen] = '\\'; silc_snprintf(bin + enclen + 1, 3, "%02X", cv); } @@ -499,7 +516,7 @@ SilcUInt32 silc_utf8_decode(const unsigned char *utf8, SilcUInt32 utf8_len, if (bin) { if (enclen + 1 > bin_size) - return 0; + goto overflow; bin[enclen] = cv; } enclen++; @@ -507,12 +524,21 @@ SilcUInt32 silc_utf8_decode(const unsigned char *utf8, SilcUInt32 utf8_len, } break; default: + silc_set_errno(SILC_ERR_INVALID_ARGUMENT); return 0; break; } } return enclen; + + overflow: + silc_set_errno(SILC_ERR_OVERFLOW); + return 0; + + bad_char: + silc_set_errno(SILC_ERR_BAD_CHAR_ENCODING); + return 0; } /* UTF-8 to wide characters */ @@ -528,8 +554,10 @@ SilcUInt32 silc_utf8_c2w(const unsigned char *utf8, SilcUInt32 utf8_len, if (!tmp_len) return 0; - if (utf8_wide_size < tmp_len / 2) + if (utf8_wide_size < tmp_len / 2) { + silc_set_errno(SILC_ERR_OVERFLOW); return 0; + } memset(utf8_wide, 0, utf8_wide_size * 2); @@ -557,8 +585,10 @@ SilcUInt32 silc_utf8_w2c(const SilcUInt16 *wide_str, SilcUInt32 tmp_len; int i, k; - if (utf8_size < wide_str_len * 2) + if (utf8_size < wide_str_len * 2) { + silc_set_errno(SILC_ERR_OVERFLOW); return 0; + } memset(utf8, 0, utf8_size); diff --git a/lib/silcutil/silcutil.c b/lib/silcutil/silcutil.c index a191f46b..fe012c6b 100644 --- a/lib/silcutil/silcutil.c +++ b/lib/silcutil/silcutil.c @@ -40,13 +40,17 @@ int silc_gets(char *dest, int destlen, const char *src, int srclen, int begin) i = 0; for ( ; start <= srclen; i++, start++) { - if (i > destlen) + if (i > destlen) { + silc_set_errno(SILC_ERR_OVERFLOW); return -1; + } dest[i] = src[start]; - if (dest[i] == EOF) + if (dest[i] == EOF) { + silc_set_errno(SILC_ERR_EOF); return EOF; + } if (dest[i] == '\n') break; @@ -56,36 +60,16 @@ int silc_gets(char *dest, int destlen, const char *src, int srclen, int begin) return start; } -/* Checks line for illegal characters. Return -1 when illegal character - were found. This is used to check for bad lines when reading data from - for example a configuration file. */ - -int silc_check_line(char *buf) -{ - /* Illegal characters in line */ - if (strchr(buf, '#')) return -1; - if (strchr(buf, '\'')) return -1; - if (strchr(buf, '\\')) return -1; - if (strchr(buf, '\r')) return -1; - if (strchr(buf, '\a')) return -1; - if (strchr(buf, '\b')) return -1; - if (strchr(buf, '\f')) return -1; - - /* Empty line */ - if (buf[0] == '\n') - return -1; - - return 0; -} - /* Converts string to capital characters. */ SilcBool silc_to_upper(const char *string, char *dest, SilcUInt32 dest_size) { int i; - if (strlen(string) > dest_size) + if (strlen(string) > dest_size) { + silc_set_errno(SILC_ERR_OVERFLOW); return FALSE; + } for (i = 0; i < strlen(string); i++) dest[i] = (char)toupper((int)string[i]); @@ -99,8 +83,10 @@ SilcBool silc_to_lower(const char *string, char *dest, SilcUInt32 dest_size) { int i; - if (strlen(string) > dest_size) + if (strlen(string) > dest_size) { + silc_set_errno(SILC_ERR_OVERFLOW); return FALSE; + } for (i = 0; i < strlen(string); i++) dest[i] = (char)tolower((int)string[i]); @@ -116,14 +102,18 @@ int silc_parse_userfqdn(const char *string, { SilcUInt32 tlen; - if (!user && !fqdn) + if (!user && !fqdn) { + silc_set_errno(SILC_ERR_INVALID_ARGUMENT); return 0; + } memset(user, 0, user_size); memset(fqdn, 0, fqdn_size); - if (!string) + if (!string) { + silc_set_errno(SILC_ERR_INVALID_ARGUMENT); return 0; + } if (string[0] == '@') { if (user) @@ -239,7 +229,7 @@ char *silc_format(char *fmt, ...) silc_vsnprintf(buf, sizeof(buf) - 1, fmt, args); va_end(args); - return strdup(buf); + return silc_strdup(buf); } /* Basic has function to hash strings. May be used with the SilcHashTable. @@ -460,7 +450,7 @@ char *silc_fingerprint(const unsigned char *data, SilcUInt32 data_len) if ((i + 1) % 10 == 0) cp[-1] = 0; - return strdup(fingerprint); + return silc_strdup(fingerprint); } /* Return TRUE if the `data' is ASCII string. */ @@ -493,7 +483,7 @@ char *silc_get_input(const char *prompt, SilcBool echo_off) fd = open("/dev/tty", O_RDONLY); if (fd < 0) { - fprintf(stderr, "silc: %s\n", strerror(errno)); + silc_set_errno_posix(errno); return NULL; } @@ -515,13 +505,14 @@ char *silc_get_input(const char *prompt, SilcBool echo_off) fflush(stdout); if ((read(fd, input, sizeof(input))) < 0) { - fprintf(stderr, "silc: %s\n", strerror(errno)); + silc_set_errno_posix(errno); tcsetattr(fd, TCSANOW, &to_old); return NULL; } if (strlen(input) <= 1) { tcsetattr(fd, TCSANOW, &to_old); + silc_set_errno(SILC_ERR_EOF); return NULL; } @@ -539,7 +530,7 @@ char *silc_get_input(const char *prompt, SilcBool echo_off) } else { fd = open("/dev/tty", O_RDONLY); if (fd < 0) { - fprintf(stderr, "silc: %s\n", strerror(errno)); + silc_set_errno_posix(errno); return NULL; } @@ -549,17 +540,19 @@ char *silc_get_input(const char *prompt, SilcBool echo_off) fflush(stdout); if ((read(fd, input, sizeof(input))) < 0) { - fprintf(stderr, "silc: %s\n", strerror(errno)); + silc_set_errno_posix(errno); return NULL; } - if (strlen(input) <= 1) + if (strlen(input) <= 1) { + silc_set_errno(SILC_ERR_EOF); return NULL; + } if (strchr(input, '\n')) *strchr(input, '\n') = '\0'; - return strdup(input); + return silc_strdup(input); } #else return NULL; @@ -640,8 +633,10 @@ SilcBool silc_hex2data(const char *hex, unsigned char *data, unsigned char l, h; int i; - if (data_size < strlen(hex) / 2) + if (data_size < strlen(hex) / 2) { + silc_set_errno(SILC_ERR_OVERFLOW); return FALSE; + } for (i = 0; i < strlen(hex) / 2; i++) { h = *cp++; @@ -670,8 +665,10 @@ SilcBool silc_data2hex(const unsigned char *data, SilcUInt32 data_len, char *cp = hex; int i; - if (hex_size - 1 < data_len * 2) + if (hex_size - 1 < data_len * 2) { + silc_set_errno(SILC_ERR_OVERFLOW); return FALSE; + } memset(hex, 0, hex_size); diff --git a/lib/silcutil/silcutil.h b/lib/silcutil/silcutil.h index e62e768d..b4d9eb45 100644 --- a/lib/silcutil/silcutil.h +++ b/lib/silcutil/silcutil.h @@ -44,21 +44,6 @@ ***/ int silc_gets(char *dest, int destlen, const char *src, int srclen, int begin); -/****f* silcutil/SilcUtilAPI/silc_check_line - * - * SYNOPSIS - * - * int silc_check_line(char *buf); - * - * DESCRIPTION - * - * Checks line for illegal characters. Return -1 when illegal character - * were found. This is used to check for bad lines when reading data from - * for example a configuration file. - * - ***/ -int silc_check_line(char *buf); - /****f* silcutil/SilcUtilAPI/silc_to_upper * * SYNOPSIS diff --git a/lib/silcutil/symbian/silcsymbiannet.cpp b/lib/silcutil/symbian/silcsymbiannet.cpp index 2c2fea50..1895b1dd 100644 --- a/lib/silcutil/symbian/silcsymbiannet.cpp +++ b/lib/silcutil/symbian/silcsymbiannet.cpp @@ -68,17 +68,17 @@ extern "C" { /* Deliver new stream to upper layer */ -static void silc_net_accept_stream(SilcSocketStreamStatus status, +static void silc_net_accept_stream(SilcResult status, SilcStream stream, void *context) { SilcNetListener listener = (SilcNetListener)context; /* In case of error, the socket has been destroyed already via silc_stream_destroy. */ - if (status != SILC_SOCKET_OK) + if (status != SILC_OK) return; - listener->callback(SILC_NET_OK, stream, listener->context); + listener->callback(SILC_OK, stream, listener->context); } } /* extern "C" */ @@ -186,7 +186,7 @@ silc_net_tcp_create_listener(const char **local_ip_addr, listener = (SilcNetListener)silc_calloc(1, sizeof(*listener)); if (!listener) { - callback(SILC_NET_NO_MEMORY, NULL, context); + callback(SILC_ERR_OUT_OF_MEMORY, NULL, context); return NULL; } listener->schedule = schedule; @@ -199,13 +199,13 @@ silc_net_tcp_create_listener(const char **local_ip_addr, listener->socks = (SilcSocket *)silc_calloc(local_ip_count, sizeof(*listener->socks)); if (!listener->socks) { - callback(SILC_NET_NO_MEMORY, NULL, context); + callback(SILC_ERR_OUT_OF_MEMORY, NULL, context); return NULL; } } else { listener->socks = (SilcSocket *)silc_calloc(1, sizeof(*listener->socks)); if (!listener->socks) { - callback(SILC_NET_NO_MEMORY, NULL, context); + callback(SILC_ERR_OUT_OF_MEMORY, NULL, context); return NULL; } @@ -277,7 +277,7 @@ silc_net_tcp_create_listener(const char **local_ip_addr, if (l) delete l; if (callback) - callback(SILC_NET_ERROR, NULL, context); + callback(SILC_ERR, NULL, context); if (listener) silc_net_close_listener(listener); return NULL; @@ -306,7 +306,7 @@ silc_net_tcp_create_listener2(const char *local_ip_addr, int *ports, listener = (SilcNetListener)silc_calloc(1, sizeof(*listener)); if (!listener) { - callback(SILC_NET_NO_MEMORY, NULL, context); + callback(SILC_ERR_OUT_OF_MEMORY, NULL, context); return NULL; } listener->schedule = schedule; @@ -319,13 +319,13 @@ silc_net_tcp_create_listener2(const char *local_ip_addr, int *ports, listener->socks = (SilcSocket *)silc_calloc(port_count, sizeof(*listener->socks)); if (!listener->socks) { - callback(SILC_NET_NO_MEMORY, NULL, context); + callback(SILC_ERR_OUT_OF_MEMORY, NULL, context); return NULL; } } else { listener->socks = (SilcSocket *)silc_calloc(1, sizeof(*listener->socks)); if (!listener->socks) { - callback(SILC_NET_NO_MEMORY, NULL, context); + callback(SILC_ERR_OUT_OF_MEMORY, NULL, context); return NULL; } @@ -424,7 +424,7 @@ silc_net_tcp_create_listener2(const char *local_ip_addr, int *ports, if (l) delete l; if (callback) - callback(SILC_NET_ERROR, NULL, context); + callback(SILC_ERR, NULL, context); if (listener) silc_net_close_listener(listener); return NULL; @@ -458,8 +458,8 @@ void silc_net_close_listener(SilcNetListener listener) /**************************** TCP/IP connecting *****************************/ -static void silc_net_connect_stream(SilcSocketStreamStatus status, - SilcStream stream, void *context); +static void silc_net_connect_stream(SilcResult status, + SilcStream stream, void *context); } /* extern "C" */ @@ -497,7 +497,7 @@ public: if (iStatus != KErrNone) { if (callback) - callback(SILC_NET_ERROR, NULL, context); + callback(SILC_ERR, NULL, context); sock->CancelConnect(); delete sock; ss->Close(); @@ -557,28 +557,16 @@ extern "C" { /* TCP stream creation callback */ -static void silc_net_connect_stream(SilcSocketStreamStatus status, +static void silc_net_connect_stream(SilcResult status, SilcStream stream, void *context) { SilcSymbianTCPConnect *conn = (SilcSymbianTCPConnect *)context; - SilcNetStatus net_status = SILC_NET_OK; SILC_LOG_DEBUG(("Socket stream creation status %d", status)); - if (status != SILC_SOCKET_OK) { - /* In case of error, the socket has been destroyed already via - silc_stream_destroy. */ - if (status == SILC_SOCKET_UNKNOWN_IP) - net_status = SILC_NET_UNKNOWN_IP; - else if (status == SILC_SOCKET_UNKNOWN_HOST) - net_status = SILC_NET_UNKNOWN_HOST; - else - net_status = SILC_NET_ERROR; - } - /* Call connection callback */ if (conn->callback) - conn->callback(net_status, stream, conn->context); + conn->callback(status, stream, conn->context); else if (stream) silc_stream_destroy(stream); @@ -609,7 +597,7 @@ SilcAsyncOperation silc_net_tcp_connect(const char *local_ip_addr, { SilcSymbianTCPConnect *conn; TInetAddr local, remote; - SilcNetStatus status; + SilcResult status; TInt ret; if (!remote_ip_addr || remote_port < 1 || !schedule || !callback) @@ -620,7 +608,7 @@ SilcAsyncOperation silc_net_tcp_connect(const char *local_ip_addr, conn = new SilcSymbianTCPConnect; if (!conn) { - callback(SILC_NET_NO_MEMORY, NULL, context); + callback(SILC_ERR_OUT_OF_MEMORY, NULL, context); return NULL; } conn->schedule = schedule; @@ -629,21 +617,21 @@ SilcAsyncOperation silc_net_tcp_connect(const char *local_ip_addr, conn->port = remote_port; conn->remote = strdup(remote_ip_addr); if (!conn->remote) { - status = SILC_NET_NO_MEMORY; + status = SILC_ERR_OUT_OF_MEMORY; goto err; } /* Allocate socket */ conn->sock = new RSocket; if (!conn->sock) { - status = SILC_NET_NO_MEMORY; + status = SILC_ERR_OUT_OF_MEMORY; goto err; } /* Allocate socket server */ conn->ss = new RSocketServ; if (!conn->ss) { - status = SILC_NET_NO_MEMORY; + status = SILC_ERR_OUT_OF_MEMORY; goto err; } @@ -651,7 +639,7 @@ SilcAsyncOperation silc_net_tcp_connect(const char *local_ip_addr, ret = conn->ss->Connect(); if (ret != KErrNone) { SILC_LOG_ERROR(("Error connecting to socket server, error %d", ret)); - status = SILC_NET_ERROR; + status = SILC_ERR; goto err; } @@ -663,7 +651,7 @@ SilcAsyncOperation silc_net_tcp_connect(const char *local_ip_addr, /* Start async operation */ conn->op = silc_async_alloc(silc_net_connect_abort, NULL, (void *)conn); if (!conn->op) { - status = SILC_NET_NO_MEMORY; + status = SILC_ERR_OUT_OF_MEMORY; goto err; } @@ -672,7 +660,7 @@ SilcAsyncOperation silc_net_tcp_connect(const char *local_ip_addr, sizeof(conn->remote_ip))) { SILC_LOG_ERROR(("Network (%s) unreachable: could not resolve the " "host", conn->remote)); - status = SILC_NET_HOST_UNREACHABLE; + status = SILC_ERR_UNREACHABLE; goto err; } @@ -680,7 +668,7 @@ SilcAsyncOperation silc_net_tcp_connect(const char *local_ip_addr, ret = conn->sock->Open(*conn->ss, KAfInet, KSockStream, KProtocolInetTcp); if (ret != KErrNone) { SILC_LOG_ERROR(("Cannot create socket, error %d", ret)); - status = SILC_NET_ERROR; + status = SILC_ERR; goto err; } @@ -696,7 +684,7 @@ SilcAsyncOperation silc_net_tcp_connect(const char *local_ip_addr, /* Connect to the host */ if (!silc_net_set_sockaddr(&remote, conn->remote_ip, remote_port)) { SILC_LOG_ERROR(("Cannot connect (cannot set address)")); - status = SILC_NET_ERROR; + status = SILC_ERR; goto err; } conn->Connect(remote); diff --git a/lib/silcutil/tests/test_silcasync.c b/lib/silcutil/tests/test_silcasync.c index 4e60ba42..92ff6669 100644 --- a/lib/silcutil/tests/test_silcasync.c +++ b/lib/silcutil/tests/test_silcasync.c @@ -122,7 +122,7 @@ int main(int argc, char **argv) if (argc > 1 && !strcmp(argv[1], "-d")) { silc_log_debug(TRUE); silc_log_debug_hexdump(TRUE); - silc_log_set_debug_string("*async*"); + silc_log_set_debug_string("*async*,*errno*"); } SILC_LOG_DEBUG(("Allocating scheduler")); diff --git a/lib/silcutil/tests/test_silcatomic.c b/lib/silcutil/tests/test_silcatomic.c index 23105f4e..59637427 100644 --- a/lib/silcutil/tests/test_silcatomic.c +++ b/lib/silcutil/tests/test_silcatomic.c @@ -17,7 +17,7 @@ int main(int argc, char **argv) if (argc > 1 && !strcmp(argv[1], "-d")) { silc_log_debug(TRUE); silc_log_debug_hexdump(TRUE); - silc_log_set_debug_string("*atomic*"); + silc_log_set_debug_string("*atomic*,*errno*"); } silc_atomic_init8(&ref8, 1); diff --git a/lib/silcutil/tests/test_silcbitops.c b/lib/silcutil/tests/test_silcbitops.c index adbd8d08..0c5b1e6e 100644 --- a/lib/silcutil/tests/test_silcbitops.c +++ b/lib/silcutil/tests/test_silcbitops.c @@ -12,7 +12,7 @@ int main(int argc, char **argv) silc_log_debug(TRUE); silc_log_quick(TRUE); silc_log_debug_hexdump(TRUE); - silc_log_set_debug_string("*bit*"); + silc_log_set_debug_string("*bit*,*err*"); } silc_bit_clear_bitmap(bitmap, size); @@ -82,7 +82,8 @@ int main(int argc, char **argv) SILC_LOG_DEBUG(("Test overflow")); if (silc_bit_set(bitmap, size, 1500)) goto err; - SILC_LOG_DEBUG(("Overflow detected")); + if (silc_errno == SILC_ERR_OVERFLOW) + SILC_LOG_DEBUG(("Overflow detected")); SILC_LOG_DEBUG(("Find first set bit")); bit = silc_bit_ffs(bitmap, size); diff --git a/lib/silcutil/tests/test_silcdll.c b/lib/silcutil/tests/test_silcdll.c index 00cf270f..e4c3b9eb 100644 --- a/lib/silcutil/tests/test_silcdll.c +++ b/lib/silcutil/tests/test_silcdll.c @@ -12,7 +12,7 @@ int main(int argc, char **argv) silc_log_debug(TRUE); silc_log_quick(TRUE); silc_log_debug_hexdump(TRUE); - silc_log_set_debug_string("*dll*"); + silc_log_set_debug_string("*dll*,*errno*"); } SILC_LOG_DEBUG(("Load shared object /lib/libc.so.6")); diff --git a/lib/silcutil/tests/test_silcenv.c b/lib/silcutil/tests/test_silcenv.c index 40c01f84..bc4871bb 100644 --- a/lib/silcutil/tests/test_silcenv.c +++ b/lib/silcutil/tests/test_silcenv.c @@ -10,7 +10,7 @@ int main(int argc, char **argv) silc_log_debug(TRUE); silc_log_quick(TRUE); silc_log_debug_hexdump(TRUE); - silc_log_set_debug_string("*env*"); + silc_log_set_debug_string("*env*,*errno*"); } silc_setenv("FOO", "BAR"); diff --git a/lib/silcutil/tests/test_silcfdstream.c b/lib/silcutil/tests/test_silcfdstream.c index f69ce14b..dfc23173 100644 --- a/lib/silcutil/tests/test_silcfdstream.c +++ b/lib/silcutil/tests/test_silcfdstream.c @@ -199,7 +199,7 @@ int main(int argc, char **argv) if (argc > 1 && !strcmp(argv[1], "-d")) { silc_log_debug(TRUE); silc_log_debug_hexdump(TRUE); - silc_log_set_debug_string("*fdstream*"); + silc_log_set_debug_string("*fdstream*,*errno*"); } SILC_LOG_DEBUG(("Allocating scheduler")); diff --git a/lib/silcutil/tests/test_silcfsm.c b/lib/silcutil/tests/test_silcfsm.c index 030deb56..782165f6 100644 --- a/lib/silcutil/tests/test_silcfsm.c +++ b/lib/silcutil/tests/test_silcfsm.c @@ -450,7 +450,7 @@ int main(int argc, char **argv) silc_log_debug(TRUE); silc_log_debug_hexdump(TRUE); silc_log_quick(TRUE); - silc_log_set_debug_string("*fsm*,*async*"); + silc_log_set_debug_string("*fsm*,*async*,*errno*"); } SILC_LOG_DEBUG(("Allocating scheduler")); diff --git a/lib/silcutil/tests/test_silchashtable.c b/lib/silcutil/tests/test_silchashtable.c index a09727b3..30e370d5 100644 --- a/lib/silcutil/tests/test_silchashtable.c +++ b/lib/silcutil/tests/test_silchashtable.c @@ -214,13 +214,13 @@ int main(int argc, char **argv) silc_log_debug(TRUE); silc_log_debug_hexdump(TRUE); silc_log_quick(TRUE); - silc_log_set_debug_string("*table*"); + silc_log_set_debug_string("*table*,*errno*"); } if (argc > 1 && !strcmp(argv[1], "-D")) { silc_log_debug(TRUE); dump = TRUE; - silc_log_set_debug_string("*table*"); + silc_log_set_debug_string("*table*,*errno*"); } if (!alloc_table()) diff --git a/lib/silcutil/tests/test_silclist.c b/lib/silcutil/tests/test_silclist.c index 5fca7447..f0783f37 100644 --- a/lib/silcutil/tests/test_silclist.c +++ b/lib/silcutil/tests/test_silclist.c @@ -17,7 +17,7 @@ int main(int argc, char **argv) if (argc > 1 && !strcmp(argv[1], "-d")) { silc_log_debug(TRUE); silc_log_debug_hexdump(TRUE); - silc_log_set_debug_string("*list*"); + silc_log_set_debug_string("*list*,*errno*"); } silc_list_init_prev(list, struct foo, next, prev); diff --git a/lib/silcutil/tests/test_silcmime.c b/lib/silcutil/tests/test_silcmime.c index e27f614f..d3b7d35d 100644 --- a/lib/silcutil/tests/test_silcmime.c +++ b/lib/silcutil/tests/test_silcmime.c @@ -19,7 +19,7 @@ int main(int argc, char **argv) if (argc > 1 && !strcmp(argv[1], "-d")) { silc_log_debug(TRUE); silc_log_debug_hexdump(TRUE); - silc_log_set_debug_string("*mime*"); + silc_log_set_debug_string("*mime*,*errno*"); } /* diff --git a/lib/silcutil/tests/test_silcnet.c b/lib/silcutil/tests/test_silcnet.c index 29748619..7b1551ce 100644 --- a/lib/silcutil/tests/test_silcnet.c +++ b/lib/silcutil/tests/test_silcnet.c @@ -10,9 +10,9 @@ typedef struct { SilcFSMThreadStruct thread; SilcNetListener server; SilcStream client_stream; - SilcNetStatus client_status; + SilcResult client_status; SilcStream server_stream; - SilcNetStatus server_status; + SilcResult server_status; SilcBool success; } *Foo; @@ -23,7 +23,7 @@ SILC_FSM_STATE(test_st_finish); SILC_FSM_STATE(test_st_connect); SILC_FSM_STATE(test_st_connected); -static void test_accept_connection(SilcNetStatus status, SilcStream stream, +static void test_accept_connection(SilcResult status, SilcStream stream, void *context) { Foo f = context; @@ -33,7 +33,7 @@ static void test_accept_connection(SilcNetStatus status, SilcStream stream, SILC_FSM_EVENT_SIGNAL(&f->sema); } -static void test_connected(SilcNetStatus status, SilcStream stream, +static void test_connected(SilcResult status, SilcStream stream, void *context) { Foo f = context; @@ -64,7 +64,7 @@ SILC_FSM_STATE(test_st_connected) SILC_LOG_DEBUG(("test_st_connected")); - if (f->server_status != SILC_NET_OK) { + if (f->server_status != SILC_OK) { SILC_LOG_DEBUG(("Creating connection failed")); return SILC_FSM_FINISH; } @@ -144,7 +144,7 @@ SILC_FSM_STATE(test_st_second) SILC_FSM_EVENT_WAIT(&f->sema); - if (f->client_status != SILC_NET_OK) { + if (f->client_status != SILC_OK) { /** Accepting new connection failed */ SILC_LOG_DEBUG(("Accepting failed %d", f->client_status)); silc_fsm_next(fsm, test_st_finish); @@ -199,7 +199,7 @@ int main(int argc, char **argv) if (argc > 1 && !strcmp(argv[1], "-d")) { silc_log_debug(TRUE); silc_log_debug_hexdump(TRUE); - silc_log_set_debug_string("*net*,*stream*"); + silc_log_set_debug_string("*net*,*stream*,*errno*"); } SILC_LOG_DEBUG(("Allocating scheduler")); diff --git a/lib/silcutil/tests/test_silcschedule.c b/lib/silcutil/tests/test_silcschedule.c index 0b87ca44..a86ba68e 100644 --- a/lib/silcutil/tests/test_silcschedule.c +++ b/lib/silcutil/tests/test_silcschedule.c @@ -94,7 +94,7 @@ int main(int argc, char **argv) silc_log_debug(TRUE); silc_log_quick(TRUE); silc_log_debug_hexdump(TRUE); - silc_log_set_debug_string("*sched*,*hash*"); + silc_log_set_debug_string("*sched*,*hash*,*errno*"); } SILC_LOG_DEBUG(("Allocating scheduler")); diff --git a/lib/silcutil/tests/test_silcstack.c b/lib/silcutil/tests/test_silcstack.c index 22474625..4b905385 100644 --- a/lib/silcutil/tests/test_silcstack.c +++ b/lib/silcutil/tests/test_silcstack.c @@ -15,7 +15,7 @@ int main(int argc, char **argv) silc_log_debug(TRUE); silc_log_debug_hexdump(TRUE); silc_log_quick(TRUE); - silc_log_set_debug_string("*stack*"); + silc_log_set_debug_string("*stack*,*errno*"); } SILC_LOG_DEBUG(("Allocating stack of default size (1024 bytes)")); diff --git a/lib/silcutil/tests/test_silcstringprep.c b/lib/silcutil/tests/test_silcstringprep.c index 62c0be2e..82fc8ca2 100644 --- a/lib/silcutil/tests/test_silcstringprep.c +++ b/lib/silcutil/tests/test_silcstringprep.c @@ -80,7 +80,7 @@ int main(int argc, char **argv) silc_log_debug(TRUE); silc_log_debug_hexdump(TRUE); silc_log_quick(TRUE); - silc_log_set_debug_string("*stringprep*,*utf8*"); + silc_log_set_debug_string("*stringprep*,*utf8*,*errno*"); } SILC_LOG_DEBUG(("--- Identifier string tests")); diff --git a/lib/silcutil/tests/test_silcstrutil.c b/lib/silcutil/tests/test_silcstrutil.c index c0235eea..a728dfd5 100644 --- a/lib/silcutil/tests/test_silcstrutil.c +++ b/lib/silcutil/tests/test_silcstrutil.c @@ -81,7 +81,7 @@ int main(int argc, char **argv) if (optarg) silc_log_set_debug_string(optarg); else - silc_log_set_debug_string("*strutil*"); + silc_log_set_debug_string("*strutil*,*errno*"); break; default: exit(1); diff --git a/lib/silcutil/tests/test_silcthread.c b/lib/silcutil/tests/test_silcthread.c index 19315701..da078b3e 100644 --- a/lib/silcutil/tests/test_silcthread.c +++ b/lib/silcutil/tests/test_silcthread.c @@ -28,7 +28,7 @@ int main(int argc, char **argv) silc_log_debug(TRUE); silc_log_quick(TRUE); silc_log_debug_hexdump(TRUE); - silc_log_set_debug_string("*thread*"); + silc_log_set_debug_string("*thread*,*errno*"); } schedule = silc_schedule_init(0, NULL, NULL); diff --git a/lib/silcutil/tests/test_silctime.c b/lib/silcutil/tests/test_silctime.c index 6e65550b..d269eb60 100644 --- a/lib/silcutil/tests/test_silctime.c +++ b/lib/silcutil/tests/test_silctime.c @@ -12,7 +12,7 @@ int main(int argc, char **argv) silc_log_debug(TRUE); silc_log_quick(TRUE); silc_log_debug_hexdump(TRUE); - silc_log_set_debug_string("*time*"); + silc_log_set_debug_string("*time*,*errno*"); } SILC_LOG_DEBUG(("Get current time")); diff --git a/lib/silcutil/tests/test_silctimer.c b/lib/silcutil/tests/test_silctimer.c index 11e17ed3..e0646cf7 100644 --- a/lib/silcutil/tests/test_silctimer.c +++ b/lib/silcutil/tests/test_silctimer.c @@ -66,7 +66,7 @@ int main(int argc, char **argv) silc_log_debug(TRUE); silc_log_quick(TRUE); silc_log_debug_hexdump(TRUE); - silc_log_set_debug_string("*timer*"); + silc_log_set_debug_string("*timer*,*errno*"); } schedule = silc_schedule_init(0, NULL, NULL); diff --git a/lib/silcutil/unix/silcunixnet.c b/lib/silcutil/unix/silcunixnet.c index cffa2cee8..de7eeaee 100644 --- a/lib/silcutil/unix/silcunixnet.c +++ b/lib/silcutil/unix/silcunixnet.c @@ -51,26 +51,31 @@ static SilcBool silc_net_set_sockaddr(SilcSockaddr *addr, const char *ip_addr, if (ip_addr) { if (!silc_net_is_ip(ip_addr)) { SILC_LOG_ERROR(("%s is not IP address", ip_addr)); + silc_set_errno_reason(SILC_ERR_BAD_IP, "%s is not an IP address", + ip_addr); return FALSE; } if (silc_net_is_ip4(ip_addr)) { /* IPv4 address */ len = sizeof(addr->sin.sin_addr); - silc_net_addr2bin(ip_addr, - (unsigned char *)&addr->sin.sin_addr.s_addr, len); + if (!silc_net_addr2bin(ip_addr, + (unsigned char *)&addr->sin.sin_addr.s_addr, len)) + return FALSE; addr->sin.sin_family = AF_INET; addr->sin.sin_port = port ? htons(port) : 0; } else { #ifdef HAVE_IPV6 /* IPv6 address */ len = sizeof(addr->sin6.sin6_addr); - silc_net_addr2bin(ip_addr, - (unsigned char *)&addr->sin6.sin6_addr, len); + if (!silc_net_addr2bin(ip_addr, + (unsigned char *)&addr->sin6.sin6_addr, len)) + return FALSE; addr->sin6.sin6_family = AF_INET6; addr->sin6.sin6_port = port ? htons(port) : 0; #else SILC_LOG_ERROR(("IPv6 support is not compiled in")); + silc_set_errno(SILC_ERR_NOT_SUPPORTED); return FALSE; #endif } @@ -89,15 +94,15 @@ static SilcBool silc_net_set_sockaddr(SilcSockaddr *addr, const char *ip_addr, /* Deliver new stream to upper layer */ -static void silc_net_accept_stream(SilcSocketStreamStatus status, +static void silc_net_accept_stream(SilcResult status, SilcStream stream, void *context) { SilcNetListener listener = context; - if (status != SILC_SOCKET_OK) + if (status != SILC_OK) return; - listener->callback(SILC_NET_OK, stream, listener->context); + listener->callback(SILC_OK, stream, listener->context); } /* Accept incoming connection and notify upper layer */ @@ -138,8 +143,10 @@ silc_net_tcp_create_listener(const char **local_ip_addr, SILC_LOG_DEBUG(("Creating TCP listener")); - if (port < 0 || !schedule || !callback) + if (port < 0 || !schedule || !callback) { + silc_set_errno(SILC_ERR_INVALID_ARGUMENT); goto err; + } listener = silc_calloc(1, sizeof(*listener)); if (!listener) @@ -176,7 +183,9 @@ silc_net_tcp_create_listener(const char **local_ip_addr, /* Create the socket */ sock = socket(server.sin.sin_family, SOCK_STREAM, 0); if (sock < 0) { - SILC_LOG_ERROR(("Cannot create socket: %s", strerror(errno))); + silc_set_errno_posix(errno); + SILC_LOG_ERROR(("Cannot create socket: %s", + silc_errno_string(silc_errno))); goto err; } @@ -191,7 +200,9 @@ silc_net_tcp_create_listener(const char **local_ip_addr, /* Bind the listener socket */ rval = bind(sock, &server.sa, SIZEOF_SOCKADDR(server)); if (rval < 0) { - SILC_LOG_ERROR(("Cannot bind socket: %s", strerror(errno))); + silc_set_errno_posix(errno); + SILC_LOG_ERROR(("Cannot bind socket: %s", + silc_errno_string(silc_errno))); close(sock); goto err; } @@ -199,7 +210,9 @@ silc_net_tcp_create_listener(const char **local_ip_addr, /* Specify that we are listenning */ rval = listen(sock, 64); if (rval < 0) { - SILC_LOG_ERROR(("Cannot set socket listenning: %s", strerror(errno))); + silc_set_errno_posix(errno); + SILC_LOG_ERROR(("Cannot set socket listenning: %s", + silc_errno_string(silc_errno))); close(sock); goto err; } @@ -240,8 +253,10 @@ silc_net_tcp_create_listener2(const char *local_ip_addr, int *ports, SILC_LOG_DEBUG(("Creating TCP listener")); - if (!schedule || !callback) + if (!schedule || !callback) { + silc_set_errno(SILC_ERR_INVALID_ARGUMENT); goto err; + } listener = silc_calloc(1, sizeof(*listener)); if (!listener) @@ -284,7 +299,9 @@ silc_net_tcp_create_listener2(const char *local_ip_addr, int *ports, if (sock < 0) { if (ignore_port_error) continue; - SILC_LOG_ERROR(("Cannot create socket: %s", strerror(errno))); + silc_set_errno_posix(errno); + SILC_LOG_ERROR(("Cannot create socket: %s", + silc_errno_string(silc_errno))); goto err; } @@ -294,7 +311,8 @@ silc_net_tcp_create_listener2(const char *local_ip_addr, int *ports, close(sock); if (ignore_port_error) continue; - SILC_LOG_ERROR(("Cannot set socket options: %s", strerror(errno))); + SILC_LOG_ERROR(("Cannot set socket options: %s", + silc_errno_string(silc_errno))); goto err; } @@ -304,7 +322,9 @@ silc_net_tcp_create_listener2(const char *local_ip_addr, int *ports, close(sock); if (ignore_port_error) continue; - SILC_LOG_ERROR(("Cannot bind socket: %s", strerror(errno))); + silc_set_errno_posix(errno); + SILC_LOG_ERROR(("Cannot bind socket: %s", + silc_errno_string(silc_errno))); goto err; } @@ -312,9 +332,11 @@ silc_net_tcp_create_listener2(const char *local_ip_addr, int *ports, rval = listen(sock, 64); if (rval < 0) { close(sock); - SILC_LOG_ERROR(("Cannot set socket listenning: %s", strerror(errno))); if (ignore_port_error) continue; + silc_set_errno_posix(errno); + SILC_LOG_ERROR(("Cannot set socket listenning: %s", + silc_errno_string(silc_errno))); goto err; } @@ -374,8 +396,10 @@ silc_net_udp_connect(const char *local_ip_addr, int local_port, SILC_LOG_DEBUG(("Creating UDP stream")); - if (!schedule) + if (!schedule) { + silc_set_errno(SILC_ERR_INVALID_ARGUMENT); goto err; + } /* Bind to local addresses */ SILC_LOG_DEBUG(("Binding to local address %s", @@ -389,20 +413,24 @@ silc_net_udp_connect(const char *local_ip_addr, int local_port, /* Create the socket */ sock = socket(server.sin.sin_family, SOCK_DGRAM, 0); if (sock < 0) { - SILC_LOG_ERROR(("Cannot create socket: %s", strerror(errno))); + silc_set_errno_posix(errno); + SILC_LOG_ERROR(("Cannot create socket: %s", + silc_errno_string(silc_errno))); goto err; } /* Set the socket options */ rval = silc_net_set_socket_opt(sock, SOL_SOCKET, SO_REUSEADDR, 1); if (rval < 0) { - SILC_LOG_ERROR(("Cannot set socket options: %s", strerror(errno))); + SILC_LOG_ERROR(("Cannot set socket options: %s", + silc_errno_string(silc_errno))); goto err; } #ifdef SO_REUSEPORT rval = silc_net_set_socket_opt(sock, SOL_SOCKET, SO_REUSEPORT, 1); if (rval < 0) { - SILC_LOG_ERROR(("Cannot set socket options: %s", strerror(errno))); + SILC_LOG_ERROR(("Cannot set socket options: %s", + silc_errno_string(silc_errno))); goto err; } #endif /* SO_REUSEPORT */ @@ -410,7 +438,8 @@ silc_net_udp_connect(const char *local_ip_addr, int local_port, /* Bind the listener socket */ rval = bind(sock, &server.sa, SIZEOF_SOCKADDR(server)); if (rval < 0) { - SILC_LOG_DEBUG(("Cannot bind socket: %s", strerror(errno))); + silc_set_errno_posix(errno); + SILC_LOG_DEBUG(("Cannot bind socket: %s", silc_errno_string(silc_errno))); goto err; } @@ -421,7 +450,9 @@ silc_net_udp_connect(const char *local_ip_addr, int local_port, rval = connect(sock, &server.sa, SIZEOF_SOCKADDR(server)); if (rval < 0) { - SILC_LOG_DEBUG(("Cannot connect UDP stream: %s", strerror(errno))); + silc_set_errno_posix(errno); + SILC_LOG_DEBUG(("Cannot connect UDP stream: %s", + silc_errno_string(silc_errno))); goto err; } } @@ -493,6 +524,7 @@ int silc_net_udp_receive(SilcStream stream, char *remote_ip_addr, len = recv(sock->sock, ret_data, data_size, 0); if (len < 0) { + silc_set_errno_posix(errno); if (errno == EAGAIN || errno == EINTR) { SILC_LOG_DEBUG(("Could not read immediately, will do it later")); silc_schedule_set_listen_fd(sock->schedule, sock->sock, @@ -502,7 +534,6 @@ int silc_net_udp_receive(SilcStream stream, char *remote_ip_addr, SILC_LOG_DEBUG(("Cannot read from UDP socket: %d:%s", sock->sock, strerror(errno))); silc_schedule_unset_listen_fd(sock->schedule, sock->sock); - sock->sock_error = errno; return -2; } @@ -553,6 +584,7 @@ int silc_net_udp_send(SilcStream stream, ret = sendto(sock->sock, data, data_len, 0, &remote.sa, SIZEOF_SOCKADDR(remote)); if (ret < 0) { + silc_set_errno_posix(errno); if (errno == EAGAIN || errno == EINTR) { SILC_LOG_DEBUG(("Could not send immediately, will do it later")); silc_schedule_set_listen_fd(sock->schedule, sock->sock, @@ -561,7 +593,6 @@ int silc_net_udp_send(SilcStream stream, } SILC_LOG_DEBUG(("Cannot send to UDP socket: %s", strerror(errno))); silc_schedule_unset_listen_fd(sock->schedule, sock->sock); - sock->sock_error = errno; return -2; } @@ -579,8 +610,7 @@ int silc_net_udp_send(SilcStream stream, /* Asynchronous TCP/IP connecting */ typedef struct { - SilcNetStatus status; - SilcSocketStreamStatus stream_status; + SilcResult status; SilcStream stream; SilcFSMStruct fsm; SilcFSMEventStruct event; @@ -629,7 +659,7 @@ SILC_FSM_STATE(silc_net_connect_st_start) "host", conn->remote)); /** Network unreachable */ - conn->status = SILC_NET_HOST_UNREACHABLE; + conn->status = SILC_ERR_UNREACHABLE; silc_fsm_next(fsm, silc_net_connect_st_finish); return SILC_FSM_CONTINUE; } @@ -652,6 +682,7 @@ SILC_FSM_STATE(silc_net_connect_st_start) } /** Cannot create socket */ + silc_set_errno_posix(errno); SILC_LOG_ERROR(("Cannot create socket: %s", strerror(errno))); silc_fsm_next(fsm, silc_net_connect_st_finish); return SILC_FSM_CONTINUE; @@ -673,6 +704,7 @@ SILC_FSM_STATE(silc_net_connect_st_start) rval = connect(sock, &desthost.sa, SIZEOF_SOCKADDR(desthost)); if (rval < 0) { if (errno != EINPROGRESS) { + silc_set_errno_posix(errno); shutdown(sock, 2); close(sock); @@ -683,7 +715,8 @@ SILC_FSM_STATE(silc_net_connect_st_start) } /** Cannot connect to remote host */ - SILC_LOG_ERROR(("Cannot connect to remote host: %s", strerror(errno))); + SILC_LOG_ERROR(("Cannot connect to remote host: %s", + silc_errno_string(silc_errno))); silc_fsm_next(fsm, silc_net_connect_st_finish); return SILC_FSM_CONTINUE; } @@ -710,12 +743,12 @@ SILC_FSM_STATE(silc_net_connect_st_start) return SILC_FSM_CONTINUE; } -static void silc_net_connect_wait_stream(SilcSocketStreamStatus status, +static void silc_net_connect_wait_stream(SilcResult status, SilcStream stream, void *context) { SilcNetConnect conn = context; conn->sop = NULL; - conn->stream_status = status; + conn->status = status; conn->stream = stream; SILC_FSM_CALL_CONTINUE(&conn->fsm); } @@ -750,21 +783,13 @@ SILC_FSM_STATE(silc_net_connect_st_connected) return SILC_FSM_CONTINUE; } -#if defined(ECONNREFUSED) - if (opt == ECONNREFUSED) - conn->status = SILC_NET_CONNECTION_REFUSED; -#endif /* ECONNREFUSED */ -#if defined(ETIMEDOUT) - if (opt == ETIMEDOUT) - conn->status = SILC_NET_CONNECTION_TIMEOUT; -#endif /* ETIMEDOUT */ -#if defined(ENETUNREACH) - if (opt == ENETUNREACH) - conn->status = SILC_NET_HOST_UNREACHABLE; -#endif /* ENETUNREACH */ + /* Set error */ + silc_set_errno_posix(opt); + conn->status = silc_errno; /** Connecting failed */ - SILC_LOG_DEBUG(("Connecting failed, error %s", strerror(opt))); + SILC_LOG_DEBUG(("Connecting failed, error %s", + silc_errno_string(silc_errno))); silc_fsm_next(fsm, silc_net_connect_st_finish); return SILC_FSM_CONTINUE; } @@ -788,21 +813,15 @@ SILC_FSM_STATE(silc_net_connect_st_stream) return SILC_FSM_CONTINUE; } - if (conn->stream_status != SILC_SOCKET_OK) { + if (conn->status != SILC_OK) { /** Stream creation failed */ - if (conn->stream_status == SILC_SOCKET_UNKNOWN_IP) - conn->status = SILC_NET_UNKNOWN_IP; - else if (conn->stream_status == SILC_SOCKET_UNKNOWN_HOST) - conn->status = SILC_NET_UNKNOWN_HOST; - else - conn->status = SILC_NET_ERROR; silc_fsm_next(fsm, silc_net_connect_st_finish); return SILC_FSM_CONTINUE; } /** Stream created successfully */ SILC_LOG_DEBUG(("Connected successfully, sock %d", conn->sock)); - conn->status = SILC_NET_OK; + conn->status = SILC_OK; silc_fsm_next(fsm, silc_net_connect_st_finish); return SILC_FSM_CONTINUE; } @@ -861,7 +880,7 @@ SilcAsyncOperation silc_net_tcp_connect(const char *local_ip_addr, conn = silc_calloc(1, sizeof(*conn)); if (!conn) { - callback(SILC_NET_NO_MEMORY, NULL, context); + callback(silc_errno, NULL, context); return NULL; } @@ -869,25 +888,25 @@ SilcAsyncOperation silc_net_tcp_connect(const char *local_ip_addr, conn->op = silc_async_alloc(silc_net_connect_abort, NULL, conn); if (!conn->op) { silc_free(conn); - callback(SILC_NET_NO_MEMORY, NULL, context); + callback(silc_errno, NULL, context); return NULL; } if (local_ip_addr) - conn->local_ip = strdup(local_ip_addr); - conn->remote = strdup(remote_ip_addr); + conn->local_ip = silc_strdup(local_ip_addr); + conn->remote = silc_strdup(remote_ip_addr); if (!conn->remote) { silc_async_free(conn->op); silc_free(conn->local_ip); silc_free(conn); - callback(SILC_NET_NO_MEMORY, NULL, context); + callback(silc_errno, NULL, context); return NULL; } conn->port = remote_port; conn->callback = callback; conn->context = context; conn->retry = 1; - conn->status = SILC_NET_ERROR; + conn->status = SILC_ERR; silc_fsm_init(&conn->fsm, conn, silc_net_connect_destructor, NULL, schedule); silc_fsm_start(&conn->fsm, silc_net_connect_st_start); @@ -907,7 +926,10 @@ void silc_net_close_connection(int sock) int silc_net_set_socket_nonblock(SilcSocket sock) { - return fcntl((int)sock, F_SETFL, fcntl(sock, F_GETFL, 0) | O_NONBLOCK); + int ret = fcntl((int)sock, F_SETFL, fcntl(sock, F_GETFL, 0) | O_NONBLOCK); + if (ret) + silc_set_errno_posix(errno); + return ret; } /* Converts the IP number string from numbers-and-dots notation to @@ -920,9 +942,17 @@ SilcBool silc_net_addr2bin(const char *addr, void *bin, SilcUInt32 bin_len) if (silc_net_is_ip4(addr)) { /* IPv4 address */ struct in_addr tmp; + + if (bin_len < 4) { + silc_set_errno(SILC_ERR_INVALID_ARGUMENT); + return FALSE; + } + ret = inet_aton(addr, &tmp); - if (bin_len < 4) + if (!ret) { + silc_set_errno_posix(errno); return FALSE; + } memcpy(bin, (unsigned char *)&tmp.s_addr, 4); #ifdef HAVE_IPV6 @@ -931,8 +961,10 @@ SilcBool silc_net_addr2bin(const char *addr, void *bin, SilcUInt32 bin_len) SilcSockaddr *s; /* IPv6 address */ - if (bin_len < 16) + if (bin_len < 16) { + silc_set_errno(SILC_ERR_INVALID_ARGUMENT); return FALSE; + } memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_INET6; diff --git a/lib/silcutil/unix/silcunixsocketstream.c b/lib/silcutil/unix/silcunixsocketstream.c index 4b5f0ac1..86c8491a 100644 --- a/lib/silcutil/unix/silcunixsocketstream.c +++ b/lib/silcutil/unix/silcunixsocketstream.c @@ -77,6 +77,7 @@ int silc_socket_stream_read(SilcStream stream, unsigned char *buf, if (!sock->qos) { len = read(sock->sock, buf, buf_len); if (len < 0) { + silc_set_errno_posix(errno); if (errno == EAGAIN || errno == EINTR) { SILC_LOG_DEBUG(("Could not read immediately, will do it later")); silc_schedule_set_listen_fd(sock->schedule, sock->sock, @@ -88,7 +89,6 @@ int silc_socket_stream_read(SilcStream stream, unsigned char *buf, SILC_LOG_DEBUG(("Cannot read from socket: %d:%s", sock->sock, strerror(errno))); silc_schedule_unset_listen_fd(sock->schedule, sock->sock); - sock->sock_error = errno; return -2; } @@ -121,6 +121,7 @@ int silc_socket_stream_read(SilcStream stream, unsigned char *buf, sock->qos->read_limit_bytes); len = read(sock->sock, qosbuf, len); if (len < 0) { + silc_set_errno_posix(errno); if (errno == EAGAIN || errno == EINTR) { SILC_LOG_DEBUG(("Could not read immediately, will do it later")); silc_schedule_set_listen_fd(sock->schedule, sock->sock, @@ -134,7 +135,6 @@ int silc_socket_stream_read(SilcStream stream, unsigned char *buf, silc_schedule_unset_listen_fd(sock->schedule, sock->sock); silc_schedule_task_del_by_context(sock->schedule, sock->qos); sock->qos->data_len = 0; - sock->sock_error = errno; return -2; } @@ -186,6 +186,7 @@ int silc_socket_stream_write(SilcStream stream, const unsigned char *data, ret = write(sock->sock, data, data_len); if (ret < 0) { + silc_set_errno_posix(errno); if (errno == EAGAIN || errno == EINTR) { SILC_LOG_DEBUG(("Could not write immediately, will do it later")); silc_schedule_set_listen_fd(sock->schedule, sock->sock, @@ -194,7 +195,6 @@ int silc_socket_stream_write(SilcStream stream, const unsigned char *data, } SILC_LOG_DEBUG(("Cannot write to socket: %s", strerror(errno))); silc_schedule_unset_listen_fd(sock->schedule, sock->sock); - sock->sock_error = errno; return -2; } @@ -230,27 +230,6 @@ int silc_socket_udp_stream_write(SilcStream stream, const unsigned char *data, return silc_socket_stream_write(stream, data, data_len); } -#if 0 -/* Returns human readable socket error message */ - -SilcBool silc_socket_get_error(SilcStream sock, char *error, - SilcUInt32 error_len) -{ - char *err; - - if (!sock->sock_error) - return FALSE; - - err = strerror(sock->sock_error); - if (strlen(err) > error_len) - return FALSE; - - memset(error, 0, error_len); - memcpy(error, err, strlen(err)); - return TRUE; -} -#endif - /* Closes socket */ SilcBool silc_socket_stream_close(SilcStream stream) diff --git a/lib/silcutil/unix/silcunixthread.c b/lib/silcutil/unix/silcunixthread.c index 9ffb365c..1f13f619 100644 --- a/lib/silcutil/unix/silcunixthread.c +++ b/lib/silcutil/unix/silcunixthread.c @@ -61,7 +61,8 @@ SilcThread silc_thread_create(SilcThreadStart start_func, void *context, c->context = context; if (pthread_attr_init(&attr)) { - SILC_LOG_ERROR(("Thread error: %s", strerror(errno))); + silc_set_errno_posix(errno); + SILC_LOG_ERROR(("Thread error: %s", silc_errno_string(silc_errno))); silc_free(c); return NULL; } @@ -69,7 +70,8 @@ SilcThread silc_thread_create(SilcThreadStart start_func, void *context, if (pthread_attr_setdetachstate(&attr, waitable ? PTHREAD_CREATE_JOINABLE : PTHREAD_CREATE_DETACHED)) { - SILC_LOG_ERROR(("Thread error: %s", strerror(errno))); + silc_set_errno_posix(errno); + SILC_LOG_ERROR(("Thread error: %s", silc_errno_string(silc_errno))); pthread_attr_destroy(&attr); silc_free(c); return NULL; @@ -77,7 +79,8 @@ SilcThread silc_thread_create(SilcThreadStart start_func, void *context, ret = pthread_create(&thread, &attr, silc_thread_start, c); if (ret) { - SILC_LOG_ERROR(("Thread error: %s", strerror(errno))); + silc_set_errno_posix(errno); + SILC_LOG_ERROR(("Thread error: %s", silc_errno_string(silc_errno))); pthread_attr_destroy(&attr); silc_free(c); return NULL; @@ -149,7 +152,11 @@ SilcBool silc_mutex_alloc(SilcMutex *mutex) *mutex = silc_calloc(1, sizeof(**mutex)); if (*mutex == NULL) return FALSE; - pthread_mutex_init(&(*mutex)->mutex, NULL); + if (pthread_mutex_init(&(*mutex)->mutex, NULL)) { + silc_set_errno_posix(errno); + silc_free(*mutex); + return FALSE; + } (*mutex)->locked = FALSE; return TRUE; #else @@ -212,7 +219,11 @@ SilcBool silc_rwlock_alloc(SilcRwLock *rwlock) *rwlock = silc_calloc(1, sizeof(**rwlock)); if (*rwlock == NULL) return FALSE; - pthread_rwlock_init(&(*rwlock)->rwlock, NULL); + if (pthread_rwlock_init(&(*rwlock)->rwlock, NULL)) { + silc_set_errno_posix(errno); + silc_free(*rwlock); + return FALSE; + } return TRUE; #else return FALSE; @@ -270,7 +281,11 @@ SilcBool silc_cond_alloc(SilcCond *cond) *cond = silc_calloc(1, sizeof(**cond)); if (*cond == NULL) return FALSE; - pthread_cond_init(&(*cond)->cond, NULL); + if (pthread_cond_init(&(*cond)->cond, NULL)) { + silc_set_errno_posix(errno); + silc_free(*cond); + return FALSE; + } return TRUE; #else return FALSE; @@ -329,7 +344,7 @@ SilcBool silc_cond_timedwait(SilcCond cond, SilcMutex mutex, defined(HAVE_PTHREAD_ONCE)) static pthread_key_t key; -static pthread_once_t key_once; +static pthread_once_t key_once = PTHREAD_ONCE_INIT; static void silc_thread_tls_destructor(void *context) { diff --git a/lib/silcutil/unix/silcunixutil.c b/lib/silcutil/unix/silcunixutil.c index 50e01d07..ef608f92 100644 --- a/lib/silcutil/unix/silcunixutil.c +++ b/lib/silcutil/unix/silcunixutil.c @@ -71,7 +71,8 @@ int silc_gettimeofday(struct timeval *p) { #if defined(HAVE_CLOCK_GETTIME) struct timespec tp; - clock_gettime(CLOCK_REALTIME, &tp); + if (clock_gettime(CLOCK_REALTIME, &tp)) + return -1; p->tv_sec = tp.tv_sec; p->tv_usec = tp.tv_nsec / 1000; return 0; diff --git a/lib/silcutil/win32/silcwin32net.c b/lib/silcutil/win32/silcwin32net.c index 5c4181f6..0aba454f 100644 --- a/lib/silcutil/win32/silcwin32net.c +++ b/lib/silcutil/win32/silcwin32net.c @@ -51,6 +51,8 @@ static SilcBool silc_net_set_sockaddr(SilcSockaddr *addr, const char *ip_addr, if (ip_addr) { if (!silc_net_is_ip(ip_addr)) { SILC_LOG_ERROR(("%s is not IP address", ip_addr)); + silc_set_errno_reason(SILC_ERR_BAD_IP, "%s is not an IP address", + ip_addr); return FALSE; } @@ -93,15 +95,15 @@ static SilcBool silc_net_set_sockaddr(SilcSockaddr *addr, const char *ip_addr, /* Deliver new stream to upper layer */ -static void silc_net_accept_stream(SilcSocketStreamStatus status, +static void silc_net_accept_stream(SilcResult status, SilcStream stream, void *context) { SilcNetListener listener = context; - if (status != SILC_SOCKET_OK) + if (status != SILC_OK) return; - listener->callback(SILC_NET_OK, stream, listener->context); + listener->callback(SILC_OK, stream, listener->context); } /* Accept incoming connection and notify upper layer */ @@ -143,8 +145,10 @@ silc_net_tcp_create_listener(const char **local_ip_addr, SILC_LOG_DEBUG(("Creating TCP listener")); - if (port < 0 || !schedule || !callback) + if (port < 0 || !schedule || !callback) { + silc_set_errno(SILC_ERR_INVALID_ARGUMENT); goto err; + } listener = silc_calloc(1, sizeof(*listener)); if (!listener) @@ -181,15 +185,17 @@ silc_net_tcp_create_listener(const char **local_ip_addr, /* Create the socket */ sock = socket(server.sin.sin_family, SOCK_STREAM, 0); if (sock == INVALID_SOCKET) { - SILC_LOG_ERROR(("Cannot create socket, error %d", WSAGetLastError())); + silc_set_errno_posix(WSAGetLastError()); + SILC_LOG_ERROR(("Cannot create socket, error %s", + silc_errno_string(silc_errno))); goto err; } /* Set the socket options */ rval = silc_net_set_socket_opt(sock, SOL_SOCKET, SO_REUSEADDR, 1); if (rval == SOCKET_ERROR) { - SILC_LOG_ERROR(("Cannot set socket options, error %d", - WSAGetLastError())); + SILC_LOG_ERROR(("Cannot set socket options, error %s", + silc_errno_string(silc_errno))); closesocket(sock); goto err; } @@ -197,7 +203,9 @@ silc_net_tcp_create_listener(const char **local_ip_addr, /* Bind the listener socket */ rval = bind(sock, &server.sa, SIZEOF_SOCKADDR(server)); if (rval == SOCKET_ERROR) { - SILC_LOG_ERROR(("Cannot bind socket, error %d", WSAGetLastError())); + silc_set_errno_posix(WSAGetLastError()); + SILC_LOG_ERROR(("Cannot bind socket, error %s", + silc_errno_string(silc_errno))); closesocket(sock); goto err; } @@ -205,8 +213,9 @@ silc_net_tcp_create_listener(const char **local_ip_addr, /* Specify that we are listenning */ rval = listen(sock, SOMAXCONN); if (rval == SOCKET_ERROR) { - SILC_LOG_ERROR(("Cannot set socket listenning, error %d", - WSAGetLastError())); + silc_set_errno_posix(WSAGetLastError()); + SILC_LOG_ERROR(("Cannot set socket listenning, error %s", + silc_errno_string(silc_errno))); closesocket(sock); goto err; } @@ -245,8 +254,10 @@ silc_net_tcp_create_listener2(const char *local_ip_addr, int *ports, SILC_LOG_DEBUG(("Creating TCP listener")); - if (!schedule || !callback) + if (!schedule || !callback) { + silc_set_errno(SILC_ERR_INVALID_ARGUMENT); goto err; + } listener = silc_calloc(1, sizeof(*listener)); if (!listener) @@ -289,7 +300,9 @@ silc_net_tcp_create_listener2(const char *local_ip_addr, int *ports, if (sock == INVALID_SOCKET) { if (ignore_port_error) continue; - SILC_LOG_ERROR(("Cannot create socket, error %d", WSAGetLastError())); + silc_set_errno_posix(WSAGetLastError()); + SILC_LOG_ERROR(("Cannot create socket, error %s", + silc_errno_string(silc_errno))); goto err; } @@ -299,8 +312,8 @@ silc_net_tcp_create_listener2(const char *local_ip_addr, int *ports, closesocket(sock); if (ignore_port_error) continue; - SILC_LOG_ERROR(("Cannot set socket options, error %d", - WSAGetLastError())); + SILC_LOG_ERROR(("Cannot set socket options, error %s", + silc_errno_string(silc_errno))); goto err; } @@ -310,7 +323,9 @@ silc_net_tcp_create_listener2(const char *local_ip_addr, int *ports, closesocket(sock); if (ignore_port_error) continue; - SILC_LOG_ERROR(("Cannot bind socket, error %d", WSAGetLastError())); + silc_set_errno_posix(WSAGetLastError()); + SILC_LOG_ERROR(("Cannot bind socket, error %s", + silc_errno_string(silc_errno))); goto err; } @@ -320,8 +335,9 @@ silc_net_tcp_create_listener2(const char *local_ip_addr, int *ports, closesocket(sock); if (ignore_port_error) continue; - SILC_LOG_ERROR(("Cannot set socket listenning, error %d", - WSAGetLastError())); + silc_set_errno_posix(WSAGetLastError()); + SILC_LOG_ERROR(("Cannot set socket listenning, error %s", + silc_errno_string(silc_errno))); goto err; } @@ -398,6 +414,7 @@ silc_net_udp_connect(const char *local_ip_addr, int local_port, sock = socket(server.sin.sin_family, SOCK_DGRAM, 0); if (sock == INVALID_SOCKET) { SILC_LOG_ERROR(("Cannot create socket")); + silc_set_errno_posix(WSAGetLastError()); goto err; } @@ -419,6 +436,7 @@ silc_net_udp_connect(const char *local_ip_addr, int local_port, rval = bind(sock, &server.sa, SIZEOF_SOCKADDR(server)); if (rval == SOCKET_ERROR) { SILC_LOG_DEBUG(("Cannot bind socket")); + silc_set_errno_posix(WSAGetLastError()); goto err; } @@ -430,6 +448,7 @@ silc_net_udp_connect(const char *local_ip_addr, int local_port, rval = connect(sock, &server.sa, SIZEOF_SOCKADDR(server)); if (rval == SOCKET_ERROR) { SILC_LOG_DEBUG(("Cannot connect UDP stream")); + silc_set_errno_posix(WSAGetLastError()); goto err; } } @@ -480,15 +499,16 @@ int silc_net_udp_receive(SilcStream stream, char *remote_ip_addr, if (len == SOCKET_ERROR) { err = WSAGetLastError(); + silc_set_errno_posix(err); if (err == WSAEWOULDBLOCK) { SILC_LOG_DEBUG(("Could not read immediately, will do it later")); silc_schedule_set_listen_fd(sock->schedule, sock->sock, SILC_TASK_READ, FALSE); return -1; } - SILC_LOG_DEBUG(("Cannot read from UDP socket: %d", sock->sock)); + SILC_LOG_DEBUG(("Cannot read from UDP socket: %d: %s", sock->sock, + silc_errno_string(silc_errno))); silc_schedule_unset_listen_fd(sock->schedule, sock->sock); - sock->sock_error = err; return -2; } @@ -539,15 +559,16 @@ int silc_net_udp_send(SilcStream stream, SIZEOF_SOCKADDR(remote)); if (ret == SOCKET_ERROR) { err = WSAGetLastError(); + silc_set_errno_posix(err); if (err == WSAEWOULDBLOCK) { SILC_LOG_DEBUG(("Could not send immediately, will do it later")); silc_schedule_set_listen_fd(sock->schedule, sock->sock, SILC_TASK_READ | SILC_TASK_WRITE, FALSE); return -1; } - SILC_LOG_DEBUG(("Cannot send to UDP socket: %s", strerror(errno))); + SILC_LOG_DEBUG(("Cannot send to UDP socket: %s", + silc_errno_string(silc_errno))); silc_schedule_unset_listen_fd(sock->schedule, sock->sock); - sock->sock_error = err; return -2; } @@ -564,8 +585,7 @@ int silc_net_udp_send(SilcStream stream, /******************************* TCP Stream *********************************/ typedef struct { - SilcNetStatus status; - SilcSocketStreamStatus stream_status; + SilcResult status; SilcStream stream; SilcFSMStruct fsm; SilcFSMThreadStruct thread; @@ -586,12 +606,12 @@ SILC_FSM_STATE(silc_net_connect_st_start); SILC_FSM_STATE(silc_net_connect_st_stream); SILC_FSM_STATE(silc_net_connect_st_finish); -static void silc_net_connect_wait_stream(SilcSocketStreamStatus status, +static void silc_net_connect_wait_stream(SilcResult status, SilcStream stream, void *context) { SilcNetConnect conn = context; conn->sop = NULL; - conn->stream_status = status; + conn->status = status; conn->stream = stream; SILC_FSM_CALL_CONTINUE(&conn->thread); } @@ -632,7 +652,7 @@ SILC_FSM_STATE(silc_net_connect_st_start) "host, error %d", conn->remote, WSAGetLastError())); /** Network unreachable */ - conn->status = SILC_NET_HOST_UNREACHABLE; + conn->status = SILC_ERR_UNREACHABLE; return SILC_FSM_FINISH; } @@ -651,7 +671,9 @@ SILC_FSM_STATE(silc_net_connect_st_start) } /** Cannot create socket */ - SILC_LOG_ERROR(("Cannot create socket, error %d", WSAGetLastError())); + silc_set_errno_posix(err); + SILC_LOG_ERROR(("Cannot create socket, error %d", + silc_errno_string(silc_errno))); return SILC_FSM_FINISH; } @@ -678,22 +700,12 @@ SILC_FSM_STATE(silc_net_connect_st_start) goto retry; } - switch (err) { - case WSAETIMEDOUT: - conn->status = SILC_NET_CONNECTION_TIMEOUT; - break; - case WSAECONNREFUSED: - conn->status = SILC_NET_CONNECTION_REFUSED; - break; - case WSAEHOSTUNREACH: - conn->status = SILC_NET_HOST_UNREACHABLE; - break; - default: - break; - } + /* Set error */ + silc_set_errno_posix(err); + conn->status = silc_errno; - SILC_LOG_ERROR(("Cannot connect to remote host, error %d", - WSAGetLastError())); + SILC_LOG_ERROR(("Cannot connect to remote host: %s", + silc_errno_string(silc_errno))); return SILC_FSM_FINISH; } } @@ -728,21 +740,14 @@ SILC_FSM_STATE(silc_net_connect_st_stream) if (conn->aborted) return SILC_FSM_FINISH; - if (conn->stream_status != SILC_SOCKET_OK) { + if (conn->status != SILC_OK) { /** Stream creation failed */ - if (conn->stream_status == SILC_SOCKET_UNKNOWN_IP) - conn->status = SILC_NET_UNKNOWN_IP; - else if (conn->stream_status == SILC_SOCKET_UNKNOWN_HOST) - conn->status = SILC_NET_UNKNOWN_HOST; - else - conn->status = SILC_NET_ERROR; - return SILC_FSM_FINISH; } /** Stream created successfully */ SILC_LOG_DEBUG(("Connected successfully, sock %d", conn->sock)); - conn->status = SILC_NET_OK; + conn->status = SILC_OK; return SILC_FSM_FINISH; } @@ -792,15 +797,17 @@ SilcAsyncOperation silc_net_tcp_connect(const char *local_ip_addr, { SilcNetConnect conn; - if (!remote_ip_addr || remote_port < 1 || !schedule || !callback) + if (!remote_ip_addr || remote_port < 1 || !schedule || !callback) { + silc_set_errno(SILC_ERR_INVALID_ARGUMENT); return NULL; + } SILC_LOG_DEBUG(("Creating connection to host %s port %d", remote_ip_addr, remote_port)); conn = silc_calloc(1, sizeof(*conn)); if (!conn) { - callback(SILC_NET_NO_MEMORY, NULL, context); + callback(SILC_ERR_OUT_OF_MEMORY, NULL, context); return NULL; } @@ -808,25 +815,25 @@ SilcAsyncOperation silc_net_tcp_connect(const char *local_ip_addr, conn->op = silc_async_alloc(silc_net_connect_abort, NULL, conn); if (!conn->op) { silc_free(conn); - callback(SILC_NET_NO_MEMORY, NULL, context); + callback(SILC_ERR_OUT_OF_MEMORY, NULL, context); return NULL; } if (local_ip_addr) - conn->local_ip = strdup(local_ip_addr); - conn->remote = strdup(remote_ip_addr); + conn->local_ip = silc_strdup(local_ip_addr); + conn->remote = silc_strdup(remote_ip_addr); if (!conn->remote) { silc_async_free(conn->op); silc_free(conn->local_ip); silc_free(conn); - callback(SILC_NET_NO_MEMORY, NULL, context); + callback(SILC_ERR_OUT_OF_MEMORY, NULL, context); return NULL; } conn->port = remote_port; conn->callback = callback; conn->context = context; conn->retry = 1; - conn->status = SILC_NET_ERROR; + conn->status = SILC_ERR; silc_fsm_init(&conn->fsm, conn, silc_net_connect_destructor, NULL, schedule); silc_fsm_start(&conn->fsm, silc_net_connect_st_thread); @@ -858,34 +865,41 @@ SilcBool silc_net_addr2bin(const char *addr, void *bin, SilcUInt32 bin_len) ret[c++] = d; d = 0; if (c > 3) - return FALSE; + goto err; continue; } if (!isdigit((int)addr[i - 1])) - return FALSE; + goto err; d = 10 * d + addr[i - 1] - '0'; if (d > 255) - return FALSE; + goto err; } if (c != 3) - return FALSE; + goto err; ret[c] = d; - if (bin_len < sizeof(ret)) + if (bin_len < sizeof(ret)) { + silc_set_errno(SILC_ERR_OVERFLOW); return FALSE; + } memcpy(bin, ret, sizeof(ret)); return TRUE; + + err: + return FALSE; } else { #ifdef HAVE_IPV6 struct addrinfo hints, *ai; SilcSockaddr *s; /* IPv6 address */ - if (bin_len < 16) + if (bin_len < 16) { + silc_set_errno(SILC_ERR_INVALID_ARGUMENT); return FALSE; + } memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_INET6; diff --git a/lib/silcutil/win32/silcwin32socketstream.c b/lib/silcutil/win32/silcwin32socketstream.c index ac12c82c..035c1618 100644 --- a/lib/silcutil/win32/silcwin32socketstream.c +++ b/lib/silcutil/win32/silcwin32socketstream.c @@ -68,6 +68,7 @@ int silc_socket_stream_read(SilcStream stream, unsigned char *buf, silc_schedule_get_fd_events(sock->schedule, sock->sock) | SILC_TASK_READ, FALSE); + silc_set_errno(SILC_ERR_WOULD_BLOCK); return -1; } @@ -75,6 +76,7 @@ int silc_socket_stream_read(SilcStream stream, unsigned char *buf, len = recv(fd, buf, buf_len, 0); if (len == SOCKET_ERROR) { len = WSAGetLastError(); + silc_set_errno_posix(ret); if (len == WSAEWOULDBLOCK || len == WSAEINTR) { SILC_LOG_DEBUG(("Could not read immediately, will do it later")); silc_schedule_set_listen_fd(sock->schedule, sock->sock, @@ -85,7 +87,6 @@ int silc_socket_stream_read(SilcStream stream, unsigned char *buf, } SILC_LOG_DEBUG(("Cannot read from socket: %d", sock->sock)); silc_schedule_unset_listen_fd(sock->schedule, sock->sock); - sock->sock_error = len; return -2; } @@ -111,6 +112,7 @@ int silc_socket_stream_write(SilcStream stream, const unsigned char *data, ret = send(fd, data, data_len, 0); if (ret == SOCKET_ERROR) { ret = WSAGetLastError(); + silc_set_errno_posix(ret); if (ret == WSAEWOULDBLOCK) { SILC_LOG_DEBUG(("Could not write immediately, will do it later")); silc_schedule_set_listen_fd(sock->schedule, sock->sock, @@ -119,7 +121,6 @@ int silc_socket_stream_write(SilcStream stream, const unsigned char *data, } SILC_LOG_DEBUG(("Cannot write to socket")); silc_schedule_unset_listen_fd(sock->schedule, sock->sock); - sock->sock_error = ret; return -2; } diff --git a/lib/silcutil/win32/silcwin32thread.c b/lib/silcutil/win32/silcwin32thread.c index cdcd50c0..fa35683d 100644 --- a/lib/silcutil/win32/silcwin32thread.c +++ b/lib/silcutil/win32/silcwin32thread.c @@ -74,6 +74,7 @@ SilcThread silc_thread_create(SilcThreadStart start_func, void *context, if (!thread->thread) { SILC_LOG_ERROR(("Could not create new thread")); + silc_set_errno_reason(SILC_ERR, "Could not create new thread"); silc_free(thread); return NULL; } diff --git a/lib/silcutil/win32/silcwin32util.c b/lib/silcutil/win32/silcwin32util.c index 1e6549b7..0148a8e0 100644 --- a/lib/silcutil/win32/silcwin32util.c +++ b/lib/silcutil/win32/silcwin32util.c @@ -45,7 +45,7 @@ char *silc_get_username(void) DWORD maxlen = 128; char username[128]; GetUserName(username, &maxlen); - return strdup(username); + return silc_strdup(username); } char *silc_get_real_name(void) diff --git a/win32/libsilc/libsilc.def b/win32/libsilc/libsilc.def index 2490ade6..a2949c2e 100644 --- a/win32/libsilc/libsilc.def +++ b/win32/libsilc/libsilc.def @@ -340,7 +340,6 @@ EXPORTS silc_file_write @ 341 ; silc_file_writefile @ 342 ; silc_file_writefile_mode @ 343 ; - silc_check_line @ 344 ; silc_fingerprint @ 345 ; silc_format @ 346 ; silc_get_input @ 347 ; -- 2.24.0