Added SILC errno API. Added SilcResult, generic error code and
authorPekka Riikonen <priikone@silcnet.org>
Sat, 22 Dec 2007 18:03:49 +0000 (18:03 +0000)
committerPekka Riikonen <priikone@silcnet.org>
Sat, 22 Dec 2007 18:03:49 +0000 (18:03 +0000)
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.

75 files changed:
CHANGES.RUNTIME
TODO
includes/silc.h.in
lib/silcclient/client_connect.c
lib/silcclient/client_listener.c
lib/silcclient/silcclient.h
lib/silchttp/silchttpserver.c
lib/silcutil/Makefile.ad
lib/silcutil/silcbase64.c
lib/silcutil/silcbitops.c
lib/silcutil/silcbitops.h
lib/silcutil/silcbuffer.h
lib/silcutil/silcbuffmt.c
lib/silcutil/silcconfig.c
lib/silcutil/silcdll.c
lib/silcutil/silcerrno.c [new file with mode: 0644]
lib/silcutil/silcerrno.h [new file with mode: 0644]
lib/silcutil/silcfdstream.c
lib/silcutil/silcfdstream.h
lib/silcutil/silcfileutil.c
lib/silcutil/silcfileutil.h
lib/silcutil/silcfsm.c
lib/silcutil/silcfsm.h
lib/silcutil/silchashtable.c
lib/silcutil/silclog.c
lib/silcutil/silclog.h
lib/silcutil/silcmemory.c
lib/silcutil/silcmemory.h
lib/silcutil/silcmime.c
lib/silcutil/silcnet.c
lib/silcutil/silcnet.h
lib/silcutil/silcnet_i.h
lib/silcutil/silcschedule.c
lib/silcutil/silcsocketstream.c
lib/silcutil/silcsocketstream.h
lib/silcutil/silcsocketstream_i.h
lib/silcutil/silcstack.c
lib/silcutil/silcstream.h
lib/silcutil/silcstrutil.c
lib/silcutil/silcthread.c
lib/silcutil/silcthread_i.h
lib/silcutil/silctime.c
lib/silcutil/silctimer.c
lib/silcutil/silctimer_i.h
lib/silcutil/silcutf8.c
lib/silcutil/silcutil.c
lib/silcutil/silcutil.h
lib/silcutil/symbian/silcsymbiannet.cpp
lib/silcutil/tests/test_silcasync.c
lib/silcutil/tests/test_silcatomic.c
lib/silcutil/tests/test_silcbitops.c
lib/silcutil/tests/test_silcdll.c
lib/silcutil/tests/test_silcenv.c
lib/silcutil/tests/test_silcfdstream.c
lib/silcutil/tests/test_silcfsm.c
lib/silcutil/tests/test_silchashtable.c
lib/silcutil/tests/test_silclist.c
lib/silcutil/tests/test_silcmime.c
lib/silcutil/tests/test_silcnet.c
lib/silcutil/tests/test_silcschedule.c
lib/silcutil/tests/test_silcstack.c
lib/silcutil/tests/test_silcstringprep.c
lib/silcutil/tests/test_silcstrutil.c
lib/silcutil/tests/test_silcthread.c
lib/silcutil/tests/test_silctime.c
lib/silcutil/tests/test_silctimer.c
lib/silcutil/unix/silcunixnet.c
lib/silcutil/unix/silcunixsocketstream.c
lib/silcutil/unix/silcunixthread.c
lib/silcutil/unix/silcunixutil.c
lib/silcutil/win32/silcwin32net.c
lib/silcutil/win32/silcwin32socketstream.c
lib/silcutil/win32/silcwin32thread.c
lib/silcutil/win32/silcwin32util.c
win32/libsilc/libsilc.def

index f333c3e1189e193da1779520ce3447839ca10538..f0995733a291817c93f8038e36d84154944434e6 100644 (file)
@@ -1,3 +1,19 @@
+Sat Dec 22 19:55:28 EET 2007  Pekka Riikonen <priikone@silcnet.org>
+
+       * 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 <priikone@silcnet.org>
 
        * Added SILC Bit Operations API to lib/silcutil/silcbitops.[ch].
diff --git a/TODO b/TODO
index 20ff6e95956a77a905161ecdddcb11fb33143e0c..3dccfb86103c677db86737ba366b273745a7c29e 100644 (file)
--- 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
index cb2f0b7b04454cda92da963dfe2c36607af5a9ec..4a20535e7e381ea1a96a9a6aad736fc052febbb4 100644 (file)
@@ -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"
index de87143f047ff3f9dc6be0eb51df4c66b2743fd9..aeaa374fd231991dd57b6610d0856390d70ff264 100644 (file)
@@ -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) */
index d6af269f65df0f19ff3fe6aaaf274e52b9d2f5fa..24ae0c74104b2cf62e14ed42a0b8b4e272c6d14b 100644 (file)
@@ -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)
 {
index 1edc5e90a12c98db512d5caf4524bb0dac9857c5..5e6c0d42f822bf861a193f5d64dbc9c342ae4e37 100644 (file)
@@ -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
index 661f1d9e1573bd4439d40967a09aec9e6390e705..f43b26a354d8fd0703d82beab9929246e57586df 100644 (file)
@@ -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)
 {
index f15910f503d5e9fb4180c6c6c77b488c229a8305..3999d3b754952bb3feba75f1691f1cfe22e8b367 100644 (file)
@@ -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
index 441ccbc888c5f8d1c2fc4b5463a8d673d4a793ec..ba9b2c8de95f20f8cf1e6b52c19149ab0473a43b 100644 (file)
@@ -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:
index 4eeca5757ec1398e2447a8d7346bc2dc37c91484..405ed539b5f7535b55620c21313d02e924f3c8a3 100644 (file)
@@ -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;
 }
 
index 4aa91c2e7c8e94e807a9aa294b3fac112088e3a9..86073b6f3534efb7f4e937c41af41778601d5dee 100644 (file)
@@ -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,
index 0a249cb0c812841954863e94dc78d532d3f80c7a..30f11dc344d7c9177988f2d3a9ba79e528abb751 100644 (file)
@@ -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);
 }
index 36d9b4817bae692966f26b8d3b815b2d69da7348..3a789fc90c29935357036dcae871f38dbe43cc38 100644 (file)
@@ -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;
     }
index 4950700577da98f8d0074350acb17d4119b6c7fd..55524a32077ce3919cac0be5edfbe353dc7d6b08 100644 (file)
@@ -4,7 +4,7 @@
 
   Author: Giovanni Giacobbi <giovanni@giacobbi.net>
 
-  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
index 20acef0b20a8889babdd865f64dc8cd306448450..59ca44d50b778af146017d794194294f96567d36 100644 (file)
@@ -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 (file)
index 0000000..1739b2d
--- /dev/null
@@ -0,0 +1,394 @@
+/*
+
+  silcerrno.c
+
+  Author: Pekka Riikonen <priikone@silcnet.org>
+
+  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 (file)
index 0000000..74a2b12
--- /dev/null
@@ -0,0 +1,196 @@
+/*
+
+  silcerrno.h
+
+  Author: Pekka Riikonen <priikone@silcnet.org>
+
+  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 */
index d2875f95a69dce8a5e746e28d1533e7d301c6f2f..ea043f2bec1b57945e7119b77bcde8e1ff0f3139 100644 (file)
@@ -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;
   }
 
index 604c0b9022a810035bb4fcdba4a4cccf37bdc8ad..285c796d07dcd6bfeaf06100e4349a11c0c845a8 100644 (file)
@@ -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 */
index c28ba38ffcbf41b9faed74c2a3b327da3b7b393f..ea48479bde029971bfc15d6e37d695f73545031c 100644 (file)
@@ -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;
 }
index 70887760e0dad3e455e44796b141950369fbc47d..151f45a4f0572c8951c4111b4674ad92affcbacb 100644 (file)
@@ -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);
index d87e0406cd5d83b14f4c34c8d0e8104899dfa04e..3cef6d969506a8f374feb54fdcb5e3a89029b0cf 100644 (file)
@@ -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);
index 701182e375501a2829ee18c156dab0a3142b2299..c723bad0672fb4912b616020c0912ee1a13d005a 100644 (file)
@@ -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
  *
index dd59263fa85dfcfa9af8b0954ec33f5a525b003f..027325b0affe559eda69fcdc71b6f06b7ddfae5d 100644 (file)
@@ -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;
index 481dfccb2da60307361bade1483ed190f454dd9a..267e7305619af43d593d8c1f2412444cb201bf73 100644 (file)
@@ -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);
index 4ae8ca9ccf08ad1034e9391e07a808833aa7fed7..80db7783cc046fc26fc4cb50ecc146d91958b605 100644 (file)
@@ -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 */
 /***/
 
index 067cf1a38da069755112078a6d059a84287e876f..ec8eb1e39be41c7d7f214e0ba7ff21969d50334d 100644 (file)
 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 */
index a016a20432f75715d91009f5e0fe0d81cc7a523d..7dc60062ef1b440c5e4af4f14048b5fe46504546 100644 (file)
@@ -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"
index c3851ea26f7ec99b3d9de714a3779a3a33975a0d..04b23adb5fc09b542f5c9fc62753303581cbeaad 100644 (file)
@@ -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;
index 17c17d83201ddb20df6b18c607fa2e223e7101eb..027d70891bb86c623fd382c9bd2ae5b821128e4d 100644 (file)
@@ -4,7 +4,7 @@
 
   Author: Pekka Riikonen <priikone@silcnet.org>
 
-  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);
 }
index ffd5bfc337e1c0e1a327d80d10206aaeebe38065..4d44ecedadbcf1afe50818547fad72115070966c 100644 (file)
  ***/
 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
index a5ec1038ac3354da86d39547f06969132ddc5148..f86819700fa8761f5a3dcaa969a4f24773c46403 100644 (file)
@@ -4,7 +4,7 @@
 
   Author: Pekka Riikonen <priikone@silcnet.org>
 
-  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 */
index ccd9abdb41328775a331181b00427daeaf7f035e..d2ad0c924ccac83c9b124e9485bea30b5b42d470 100644 (file)
@@ -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),
index e4b59f5a601c6d0019632438514f780a48729507..5e3357433f3b7120114ca103d1f13c891bf6f073 100644 (file)
@@ -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,
index e9fd435782959fd2e3298047571d4c2c77e9e3bb..42990936f8bf73b3f378f437e9d51d34d719b0e7 100644 (file)
 #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
index 50385df3bddd38233031412e16383475bf78998d..b82024fa711cd6b3ffd006e68a98c44a45a27a74 100644 (file)
@@ -4,7 +4,7 @@
 
   Author: Pekka Riikonen <priikone@silcnet.org>
 
-  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 */
index 02e2e0c203b145a72ad1f3e3153afdefd4af335e..509331f28a50c506102e4bed61cfc12cdece59b7 100644 (file)
@@ -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;
 }
index 3067313ba946d5a04ff4b84235497fc65d6309d6..8195a15f3c547c8d8dadb098ec6e7cb746ba3687 100644 (file)
@@ -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);
index e7344ad5b9d76fa5e3b351b570544bd17bc44ebf..1655f213459470ab4a4765d0d55a12b9ba7c9440 100644 (file)
@@ -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);
index 3ada012c14e86c3c264c0f275a0476fbd1f2d523..8e51a15d13ef4c182382cf029f3b0f41512c3deb 100644 (file)
@@ -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;
       }
 
index 0038a616d862475504b005b4b0520c83db81ba3a..c67fce0824c8a128bd17244375afe7b05929364a 100644 (file)
    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. */
index 5a91717213dbdee352a43b501105e5dac90e9c1c..4dc7f2172ec5470d0a78ff4736aefa5e38d2ffba 100644 (file)
@@ -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;
index 3973752edc2a163b03a90f51315c8c65718defa7..0313a3158698f8a7ea502cc688ad10311e07d6dd 100644 (file)
@@ -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
index cefaac0413e99332dc635de04773ab05b1f14aa5..1ecfdcdf7dd57293724a0a6d080ea23f88e859d9 100644 (file)
@@ -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 */
index 1faf14c9deb6422a459cf7d597d77cc03a93c891..8bbb5ece2a23d8242835b07032af9af47c4d649c 100644 (file)
@@ -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);
 
index a191f46b0a24e7444577b914daa306791822d64d..fe012c6bdeb9de5579ad99b882dfbf23020ef3a5 100644 (file)
@@ -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);
 
index e62e768d15d0bede90cb82b3f191969e0ea07bde..b4d9eb451063d466af2417f00b0dce1e5f7047bc 100644 (file)
  ***/
 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
index 2c2fea50c374866a65086f3cf8db81fb1e0a27fd..1895b1dda42aa80fe923ef239d5a1227bc7d475b 100644 (file)
@@ -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);
index 4e60ba4220d48bedb67f9ae5b41ec1cdc7b2ec28..92ff6669157fbb2cd22aa91fec59c3c5f6751d41 100644 (file)
@@ -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"));
index 23105f4ee01dc6f607c56fc511b2b6f3ab3b46e7..59637427bbeac05c8ec241dd7f26ee1a50725988 100644 (file)
@@ -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);
index adbd8d086654377782dad02b8aa3100a8f1a8547..0c5b1e6eb599a1d946233d3385a327c26e0977ba 100644 (file)
@@ -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);
index 00cf270fa487f835ba86666df284ac10483dd77e..e4c3b9ebd70e869482dfcadcf59a36553fe4a65d 100644 (file)
@@ -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"));
index 40c01f84ccbd8bff00f869cb4c7095d6a258e94e..bc4871bb212436d40c433272f2416420cfc20d2a 100644 (file)
@@ -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");
index f69ce14bad3c46c3576a468115dbb2a6bcce023e..dfc231733b92040517a864e970f4f1dac5c205b6 100644 (file)
@@ -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"));
index 030deb56ac35a7dc49331b3fbccc9afcd7ad79cf..782165f65c7ea09298259afa8ee40ca9e96487f1 100644 (file)
@@ -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"));
index a09727b3cee0a6e58939331de00bd7390d3f33c8..30e370d55b18360dac0b5b50eddc23ab7d8b9b88 100644 (file)
@@ -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())
index 5fca7447e09f8ed8827320a353d58d3a7d7f8b74..f0783f37473774c858a1b01a22332c6bd07a14b2 100644 (file)
@@ -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);
index e27f614f50a3407902826c5326b315dfd4538985..d3b7d35d9fe956a74dc03d51087c703eb11b8760 100644 (file)
@@ -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*");
   }
 
   /* 
index 29748619abd1c56ae56424b2842e276f31bc2bc3..7b1551cebbd5859dba12740319c92f6e98407735 100644 (file)
@@ -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"));
index 0b87ca443e76ab259aefc64c1c1a69b249bd57a1..a86ba68e2ddcc13714bef3c86975d84fddf30f2b 100644 (file)
@@ -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"));
index 22474625d27804888001e0c6c5631f916fabec5e..4b905385744a881edfde57a8c34c3e348840b401 100644 (file)
@@ -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)"));
index 62c0be2eb7b5a2e0079630772c324eb1786642a2..82fc8ca2cf8bee216c6926c69ca93c170e50ce3a 100644 (file)
@@ -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"));
index c0235eea3bc566035f90d8e09596f0f471ef4220..a728dfd5f16c5f2606cf61357417c81e09835835 100644 (file)
@@ -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);
index 19315701ad8697860d1ada1551d8aa1fbd9ea3b6..da078b3e8af34b79a7bfa783b79e08720bb149ec 100644 (file)
@@ -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);
index 6e65550bc58b1fba16ba93259daff6332ef4ddd6..d269eb60fccf550fb1683870a3f2ecaa0acc24b2 100644 (file)
@@ -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"));
index 11e17ed3228d0cda2760cb9b779c20e4b6bae2ed..e0646cf7bd78a5567113121352014328456600be 100644 (file)
@@ -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);
index cffa2cee86786ec2a104b1dfe13f6e36bf17ce53..de7eeaee881d333af97733a7747d21f275bbc8bf 100644 (file)
@@ -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;
index 4b5f0ac11efffb255ed0da5d651c5187ab89ce2a..86c8491a9e95fced746b6086aea981034fd96dbd 100644 (file)
@@ -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)
index 9ffb365c471e560d52d55fa968759b9cf476e713..1f13f6190035fb21786fd543a7e5c1fb695993ea 100644 (file)
@@ -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)
 {
index 50e01d07b92282fbb31db4980053741b6cc2ee9b..ef608f92e54b699f18f489f2a0776040bc300b37 100644 (file)
@@ -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;
index 5c4181f66dafe91954c7f591af1b6acf34c913a8..0aba454f50edcc9e0ba0694a961a8971c62f667d 100644 (file)
@@ -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;
index ac12c82c94a7eb0416c911f9e0807e1841c1bc77..035c161809a13457d8afe2c4597448893cfef871 100644 (file)
@@ -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;
   }
 
index cdcd50c0df9a0b32ee87af27387f3beead8e2660..fa35683dbe4b19b5ebd96de2d9f8d52c45d1ca2a 100644 (file)
@@ -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;
   }
index 1e6549b78b519977c4eddadf9628ef47dc255465..0148a8e02b19e7f40cb7d752bdd8a9486685daf4 100644 (file)
@@ -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)
index 2490ade6450d4a6902c2f4581ca7628a368b4ba2..a2949c2e55799114372bc19d289f07657c7dd727 100644 (file)
@@ -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 ;