Added preliminary Symbian support.
authorPekka Riikonen <priikone@silcnet.org>
Mon, 1 Jan 2007 12:25:16 +0000 (12:25 +0000)
committerPekka Riikonen <priikone@silcnet.org>
Mon, 1 Jan 2007 12:25:16 +0000 (12:25 +0000)
Added silc_snprintf.
Added SilcRng argument to silc_pkcs_encrypt API.

59 files changed:
CHANGES
TODO
configure.ad
doc/draft-riikonen-silc-pp-09.nroff
doc/draft-riikonen-silc-spec-09.nroff
includes/silc.h.in
includes/silcepoc.h [deleted file]
includes/silcsymbian.h [new file with mode: 0644]
lib/configure.ad
lib/contrib/regexpr.c
lib/silcapputil/silcapputil.c
lib/silcasn1/silcasn1_decode.c
lib/silcclient/client_entry.c
lib/silcclient/client_ftp.c
lib/silcclient/client_keyagr.c
lib/silccore/silcpacket.c
lib/silccrypt/silcpk.c
lib/silccrypt/silcpk_i.h
lib/silccrypt/silcpkcs.c
lib/silccrypt/silcpkcs.h
lib/silccrypt/silcpkcs1.c
lib/silchttp/silchttpphp.c
lib/silchttp/silchttpserver.c
lib/silcserver/server_send.c
lib/silcserver/server_st_accept.c
lib/silcsftp/sftp_fs_memory.c
lib/silcskr/silcskr.c
lib/silcutil/Makefile.ad
lib/silcutil/silclog.c
lib/silcutil/silcmime.c
lib/silcutil/silcnet.c
lib/silcutil/silcnet.h
lib/silcutil/silcnet_i.h
lib/silcutil/silcsocketstream.c
lib/silcutil/silcsocketstream.h
lib/silcutil/silcsocketstream_i.h
lib/silcutil/silcstrutil.c
lib/silcutil/silcstrutil.h
lib/silcutil/silctime.c
lib/silcutil/silctypes.h
lib/silcutil/silcutf8.c
lib/silcutil/silcutil.c
lib/silcutil/symbian/Makefile.am [deleted file]
lib/silcutil/symbian/silcepocsockconn.cpp [deleted file]
lib/silcutil/symbian/silcepocthread.cpp [deleted file]
lib/silcutil/symbian/silcepocutil.cpp [deleted file]
lib/silcutil/symbian/silcsymbiannet.cpp [new file with mode: 0644]
lib/silcutil/symbian/silcsymbianscheduler.cpp [new file with mode: 0644]
lib/silcutil/symbian/silcsymbiansocketstream.cpp [new file with mode: 0644]
lib/silcutil/symbian/silcsymbiansocketstream.h [new file with mode: 0644]
lib/silcutil/symbian/silcsymbianthread.cpp [new file with mode: 0644]
lib/silcutil/symbian/silcsymbianutil.cpp [new file with mode: 0644]
lib/silcutil/tests/test_silchashtable.c
lib/silcutil/unix/silcunixnet.c
lib/silcutil/unix/silcunixsocketstream.c
lib/silcutil/unix/silcunixthread.c
symbian/silcdefs.h [new file with mode: 0644]
symbian/silcdistdefs.h [new file with mode: 0644]
tutorial/mybot/mybot.c

diff --git a/CHANGES b/CHANGES
index 96f924c471ca7f9abcc0acf3e08dfa4dbf770d5f..20856172133d29f915832ea630ad1125913fbada 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,12 @@
+Sat Dec 30 23:23:17 EET 2006  Pekka Riikonen <priikone@silcnet.org>
+
+       * Added preliminary Symbian support.  Changes around the source
+         tree.  The symbian/ directory now includes Carbide.c++ project
+         files to compile the sources.
+
+       * Added silc_snprintf.  Affected files are
+          lib/silcutil/silcstrutil.[ch].
+
 Thu Dec 21 18:01:51 EET 2006  Pekka Riikonen <priikone@silcnet.org>
 
        * Changed SILC_FSM_[CONTINUE|YIELD|WAIT|FINISH] enums to
diff --git a/TODO b/TODO
index 9a8d4881008303b76dad8f1c112d717014c9784c..22cd60b3f0725088099f86761ffd4b8618db7d81 100644 (file)
--- a/TODO
+++ b/TODO
@@ -161,6 +161,10 @@ lib/silccrypt                      ****PARTLY DONE****
 lib/silcutil                   ****PARTLY DONE****
 ============
 
+ o The regex code from lib/contrib might compile fine on all platforms.
+   No need to make it silcutil/unix/ specific.  Add them to generic
+   silcutil.c.
+
  o silc_stringprep to non-allocating version.
 
  o Compression routines are missing.  The protocol supports packet
@@ -310,13 +314,11 @@ lib/silcmath
  o All utility functions should be made non-allocating ones.
 
 
-lib/silcutil/epoc/*
-===================
-
-  o lib/silcutil/epoc routines missing or not completed.
+lib/silcutil/symbian/          ****PARTLY DONE****
+=====================
 
-  o The PKCS#1 also calls global RNG (even though it is not used
-    currently in SILC, the interface allows its use).
+  o lib/silcutil/symbian routines missing or not completed.
+    (****TESTING NEEDED)
 
   o Something needs to be thought to the logging globals as well,
     like silc_debug etc.  They won't work on EPOC.  Perhaps logging
index 90c55578620cb88cc25988ab15659cf0f00cc8f7..5f0141834d31316f5557e74661a21a7768fe0d3c 100644 (file)
@@ -3,7 +3,7 @@
 #
 #  Author: Pekka Riikonen <priikone@silcnet.org>
 #
-#  Copyright (C) 2000 - 2006 Pekka Riikonen
+#  Copyright (C) 2000 - 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
@@ -178,7 +178,7 @@ AC_CHECK_FUNCS(setrlimit time ctime utime gettimeofday getrusage)
 AC_CHECK_FUNCS(chmod fcntl stat fstat getenv putenv strerror)
 AC_CHECK_FUNCS(getpid getgid getsid getpgid getpgrp getuid)
 AC_CHECK_FUNCS(setgroups initgroups nl_langinfo epoll_wait)
-AC_CHECK_FUNCS(strchr strstr strcpy strncpy memcpy memset memmove)
+AC_CHECK_FUNCS(strchr snprintf strstr strcpy strncpy memcpy memset memmove)
 
 #ifdef SILC_DIST_SIM
 # SIM support checking
@@ -1142,9 +1142,9 @@ AC_ARG_WITH(win32,
   ])
 AM_CONDITIONAL(SILC_WIN32, test x$win32_support = xtrue)
 
-# Native EPOC support (disabled by default)
+# Native Symbian OS support (disabled by default)
 #
-AM_CONDITIONAL(SILC_EPOC, test xfalse = xtrue)
+AM_CONDITIONAL(SILC_SYMBIAN, test xfalse = xtrue)
 
 # Native BeOS support (disabled by default)
 #
index 1273025966d6e2ffc4fbf098a78823facb0da884..53c73e45a22c84ad267c340e14d06233005c04dd 100644 (file)
@@ -1838,6 +1838,10 @@ on channel.  This means that channel uses channel private keys which
 are not server generated.  For this reason server cannot send this
 packet as it does not know the key.
 
+The destination ID in the packet SHOULD be the entity to whom the
+packet is sent.  Using Channel ID as destination ID is not
+necessary as the Channel ID is included in the Channel Key Payload.
+
 The payload may only be sent with SILC_PACKET_CHANNEL_KEY packet.
 It MUST NOT be sent in any other packet type.  The following diagram
 represents the Channel Key Payload.
@@ -2344,7 +2348,7 @@ types.  The following diagram represents the Key Agreement Payload.
 ~                           Hostname                            ~
 |                                                               |
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-|                             Port                              |
+|            Protocol           |             Port              |
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 .in 3
 
@@ -2361,10 +2365,16 @@ o Hostname (variable length) - The hostname or IP address where
   MAY fill this field when sending the payload.  If the receiver
   sends this payload as reply to the request it MUST fill this field.
 
-o Port (4 bytes) - The port where the SKE protocol is bound.
+o Protocol (2 bytes) - The internet protocol used for the key
+  agreement connection.  Possible values are 0 for TCP and 1 for
+  UDP.  Other values are unsupported.  This is a 16 bit MSB first
+  order value.  If Hostname field is not present, the value in
+  this field is ignored.
+
+o Port (2 bytes) - The port where the SKE protocol is bound.
   The sender MAY fill this field when sending the payload.  If
   the receiver sends this payload as reply to the request it
-  MUST fill this field.  This is a 32 bit MSB first order value.
+  MUST fill this field.  This is a 16 bit MSB first order value.
 .in 3
 
 
index 6d7b93c6dfbd528f7f68dd3f9a2eff992e40815b..f5c95784ae4d2d1ad1dfc1879b044666bc71ec5c 100644 (file)
@@ -1239,10 +1239,10 @@ debugging mode.
 .ti 0
 3.10.1.1 CBC Mode
 
-The "cbc" encryption mode is CBC mode with inter-packet chaining.  This
-means that the Initialization Vector (IV) for the next encryption block
-is the previous ciphertext block.  The very first IV MUST be random and
-is generated as described in [SILC3].
+The "cbc" encryption mode is the standard cipher-block chaining mode.
+The very first IV is derived from the SILC Key Exchange protocol.
+Subsequent IVs for encryption is the previous ciphertext block.  The very
+first IV MUST be random and is generated as described in [SILC3].
 
 
 .ti 0
@@ -1368,19 +1368,12 @@ stream to perform the decryption.
 
 The "rcbc" encryption mode is CBC mode with randomized IV.  This means
 that each IV for each packet MUST be chosen randomly.  When encrypting
-more than one block the normal inter-packet chaining is used, but for
-the first block new random IV is selected in each packet.  In this mode
-the IV is appended at the end of the last ciphertext block and thus
-delivered to the recipient.  This mode increases the ciphertext size by
-one ciphertext block.  Note also that some data payloads in SILC are
-capable of delivering the IV to the recipient.  When explicitly
-encrypting these payloads with randomized CBC the IV MUST NOT be appended
-at the end of the ciphertext, but is placed at the specified location
-in the payload.  However, Message Payload for example has the IV at
-the location which is equivalent to placing it after the last ciphertext
-block.  When using CBC mode with such payloads it is actually equivalent
-to using randomized CBC since the IV is selected in random and included
-in the ciphertext.
+more than one block the normal IV chaining is used, but for the first
+block new random IV is selected in each packet.  In this mode the IV
+is appended to the ciphertext.  If this mode is used to secure the SILC
+session, the IV Included flag must be negotiated in SILC Key Exchange
+protocol.  It may also be used to secure Message Payloads which can
+deliver the IV to the recipient.
 
 
 .ti 0
@@ -2403,7 +2396,9 @@ processing is equivalent to normal SKE negotiation.
 After both parties have regenerated the session key, both MUST send
 SILC_PACKET_REKEY_DONE packet to each other.  These packets are still
 secured with the old key.  After these packets, the subsequent packets
-MUST be protected with the new key.
+MUST be protected with the new key.  Note that, in case SKE was performed
+again the SILC_PACKET_SUCCESS is not sent.  The SILC_PACKET_REKEY_DONE
+is sent in its stead.
 
 
 .ti 0
index 5eaf86c88d5e1f241da561fd1c8a027bee252ef8..fce93cb0ff475170029025065a5e5bbb3c63e4c5 100644 (file)
@@ -37,35 +37,19 @@ extern "C" {
 #endif
 #endif
 
-#if defined(__EPOC32__)
-#ifndef SILC_EPOC
-#define SILC_EPOC
-#undef SILC_UNIX
-#endif
-#endif
-
-#ifdef BEOS
-#ifndef SILC_BEOS
-#define SILC_BEOS
-#undef SILC_UNIX
-#endif
-#elif defined(__BEOS__)
-#ifndef SILC_BEOS
-#define SILC_BEOS
-#undef SILC_UNIX
-#endif
-#endif
-
-#if defined(OS2)
-#ifndef SILC_OS2
-#define SILC_OS2
+#if defined(__EPOC32__) || defined(__SYMBIAN32__)
+#ifndef SILC_SYMBIAN
+#define SILC_SYMBIAN
 #undef SILC_UNIX
+#undef SILC_WIN32
 #endif
 #endif
 
 #if defined(__MACH__) && defined(__APPLE__)
 #ifndef SILC_MACOSX
 #define SILC_MACOSX
+#undef SILC_WIN32
+#undef SILC_SYMBIAN
 #endif
 #endif
 
@@ -84,8 +68,13 @@ extern "C" {
 
 #if defined(HAVE_SILCDEFS_H)
 /* Automatically generated configuration header */
+#ifndef SILC_SYMBIAN
 #include "silcdefs.h"
 #include "silcdistdefs.h"
+#else
+#include "../symbian/silcdefs.h"
+#include "../symbian/silcdistdefs.h"
+#endif /* SILC_SYMBIAN */
 #endif /* HAVE_SILCDEFS_H */
 
 /* Platform specific includes */
@@ -94,16 +83,8 @@ extern "C" {
 #include "silcwin32.h"
 #endif
 
-#if defined(SILC_EPOC)
-#include "silcepoc.h"
-#endif
-
-#if defined(SILC_BEOS)
-#include "silcbeos.h"
-#endif
-
-#if defined(SILC_OS2)
-#include "silcos2.h"
+#if defined(SILC_SYMBIAN)
+#include "silcsymbian.h"
 #endif
 
 #ifndef DLLAPI
@@ -140,9 +121,12 @@ extern "C" {
 #include <unistd.h>
 #include <sys/time.h>
 #include <pwd.h>
-#include <grp.h>
 #include <sys/times.h>
 
+#ifdef HAVE_GRP_H
+#include <grp.h>
+#endif
+
 #if defined(HAVE_GETOPT_H) && defined(HAVE_GETOPT)
 #include <getopt.h>
 #else
@@ -232,6 +216,7 @@ extern "C" {
 
 /* Include generic SILC type definitions */
 #include "silctypes.h"
+#include "silcmutex.h"
 #include "silcatomic.h"
 #include "silcversion.h"
 
@@ -245,7 +230,6 @@ extern "C" {
 
 /* More SILC util library includes */
 #include "silctime.h"
-#include "silcmutex.h"
 #include "silccond.h"
 #include "silcthread.h"
 #include "silcschedule.h"
diff --git a/includes/silcepoc.h b/includes/silcepoc.h
deleted file mode 100644 (file)
index ab57922..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
-
-  silcepoc.h 
-
-  Author: Pekka Riikonen <priikone@silcnet.org>
-
-  Copyright (C) 2002 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.
-
-*/
-/* Native EPOC specific includes and definitions. */
-
-#ifndef SILCEPOC_H
-#define SILCEPOC_H
-
-#include <e32std.h>
-#include <e32base.h>
-#include <e32cons.h>
-#include <e32svr.h>
-#include <e32hal.h>
-#include <w32std.h>
-#include <apgtask.h>
-#include <es_sock.h>
-#include <in_sock.h>
-
-#endif
diff --git a/includes/silcsymbian.h b/includes/silcsymbian.h
new file mode 100644 (file)
index 0000000..396a121
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+
+  silcsymbian.h
+
+  Author: Pekka Riikonen <priikone@silcnet.org>
+
+  Copyright (C) 2002 - 2006 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.
+
+*/
+/* Native Symbian specific includes and definitions. */
+
+#ifndef SILCSYMBIAN_H
+#define SILCSYMBIAN_H
+
+/* Various hacks follow */
+
+/* Do not treat conversions from 'unsigned char *' to 'char *' as errors
+   with WINSCW */
+#ifdef __WINSCW__
+#pragma mpwc_relax on
+#endif /* __WINSCW__ */
+
+/* Define the need for wchar_t, otherwise the stddef.h may not define it,
+   as it is not guaranteed that the stddef.h used is from Symbian headers
+   (due to some include path ordering problem in some cases). */
+#ifndef __need_wchar_t
+#define __need_wchar_t
+#endif /* __need_wchar_t */
+
+/* And just in case, include stddef.h here to get the Symbian one as
+   early as possible. */
+#include <stddef.h>
+
+#endif /* SILCSYMBIAN_H */
index 889a74b1ae47fd76da5c3467f8b23d95b2184fa7..5f13377fbedd59f9d5562a91b62617bd6256efbd 100644 (file)
@@ -4,7 +4,7 @@
 #
 #  Author: Pekka Riikonen <priikone@silcnet.org>
 #
-#  Copyright (C) 2005 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
@@ -209,7 +209,6 @@ lib/silcutil/unix/Makefile
 lib/silcutil/win32/Makefile
 lib/silcutil/beos/Makefile
 lib/silcutil/os2/Makefile
-lib/silcutil/epoc/Makefile
 lib/silcapputil/Makefile
 #ifdef SILC_DIST_SFTP
 lib/silcsftp/Makefile
index 1ddde56c537dfd66a0a7c77d28bb324734235cb8..65917bc77314808576e81441f304241d067ee86f 100644 (file)
@@ -29,6 +29,7 @@ $Id$
 
 */
 
+#include "silc.h"
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -40,7 +41,6 @@ $Id$
 
 #include <stdio.h>
 #include <assert.h>
-//#include "silc.h"
 #include "regexpr.h"
 
 #define MACRO_BEGIN do {
index c8a9a35a1ca0b39f0d09555da630e2fc9e10f4bc..32018654de19f937f2c002935f91b0fd745f95a8 100644 (file)
@@ -40,7 +40,7 @@ static char *silc_create_pk_identifier(void)
     return NULL;
 
   /* Create default email address, whether it is right or not */
-  snprintf(email, sizeof(email), "%s@%s", username, hostname);
+  silc_snprintf(email, sizeof(email), "%s@%s", username, hostname);
 
   ident = silc_pkcs_silc_encode_identifier(username, hostname, realname,
                                           email, NULL, NULL);
@@ -123,9 +123,9 @@ New pair of keys will be created.  Please, answer to following questions.\n\
     if (interactive) {
       memset(line, 0, sizeof(line));
       if (def)
-       snprintf(line, sizeof(line), "Identifier [%s]: ", def);
+       silc_snprintf(line, sizeof(line), "Identifier [%s]: ", def);
       else
-       snprintf(line, sizeof(line),
+       silc_snprintf(line, sizeof(line),
               "Identifier (eg. UN=jon, HN=jon.dummy.com, "
               "RN=Jon Johnson, E=jon@dummy.com): ");
 
@@ -153,7 +153,7 @@ New pair of keys will be created.  Please, answer to following questions.\n\
   if (!pkfile) {
     if (interactive) {
       memset(line, 0, sizeof(line));
-      snprintf(line, sizeof(line), "Public key filename [public_key.pub]: ");
+      silc_snprintf(line, sizeof(line), "Public key filename [public_key.pub]: ");
       pkfile = silc_get_input(line, FALSE);
     }
     if (!pkfile)
@@ -163,7 +163,7 @@ New pair of keys will be created.  Please, answer to following questions.\n\
   if (!prvfile) {
     if (interactive) {
       memset(line, 0, sizeof(line));
-      snprintf(line, sizeof(line), "Private key filename [private_key.prv]: ");
+      silc_snprintf(line, sizeof(line), "Private key filename [private_key.prv]: ");
       prvfile = silc_get_input(line, FALSE);
     }
     if (!prvfile)
@@ -753,11 +753,11 @@ SilcBool silc_parse_version_string(const char *version,
   min = atoi(cp);
 
   memset(buf, 0, sizeof(buf));
-  snprintf(buf, sizeof(buf) - 1, "%d%d", maj, min);
+  silc_snprintf(buf, sizeof(buf) - 1, "%d%d", maj, min);
   if (protocol_version)
     *protocol_version = atoi(buf);
   memset(buf, 0, sizeof(buf));
-  snprintf(buf, sizeof(buf) - 1, "%d.%d", maj, min);
+  silc_snprintf(buf, sizeof(buf) - 1, "%d.%d", maj, min);
   if (protocol_version_string)
     *protocol_version_string = strdup(buf);
 
@@ -779,11 +779,11 @@ SilcBool silc_parse_version_string(const char *version,
   }
 
   memset(buf, 0, sizeof(buf));
-  snprintf(buf, sizeof(buf) - 1, "%d%d", maj, min);
+  silc_snprintf(buf, sizeof(buf) - 1, "%d%d", maj, min);
   if (software_version)
     *software_version = atoi(buf);
   memset(buf, 0, sizeof(buf));
-  snprintf(buf, sizeof(buf) - 1, "%d.%d", maj, min);
+  silc_snprintf(buf, sizeof(buf) - 1, "%d.%d", maj, min);
   if (software_version_string)
     *software_version_string = strdup(buf);
 
@@ -815,7 +815,7 @@ SilcUInt32 silc_version_to_num(const char *version)
     min = atoi(cp + 1);
 
   memset(buf, 0, sizeof(buf));
-  snprintf(buf, sizeof(buf) - 1, "%d%d", maj, min);
+  silc_snprintf(buf, sizeof(buf) - 1, "%d%d", maj, min);
   return (SilcUInt32)atoi(buf);
 }
 
@@ -987,11 +987,11 @@ char *silc_id_render(void *id, SilcIdType id_type)
       }
 
       memset(tmp, 0, sizeof(tmp));
-      snprintf(tmp, sizeof(tmp) - 1, ",%d,", ntohs(server_id->port));
+      silc_snprintf(tmp, sizeof(tmp) - 1, ",%d,", ntohs(server_id->port));
       _PUT_STRING(rid, tmp);
       SILC_PUT16_MSB(server_id->rnd, tmps);
       memset(tmp, 0, sizeof(tmp));
-      snprintf(tmp, sizeof(tmp) - 1, "[%02x %02x]", tmps[0], tmps[1]);
+      silc_snprintf(tmp, sizeof(tmp) - 1, "[%02x %02x]", tmps[0], tmps[1]);
       _PUT_STRING(rid, tmp);
     }
     break;
@@ -1017,10 +1017,10 @@ char *silc_id_render(void *id, SilcIdType id_type)
       }
 
       memset(tmp, 0, sizeof(tmp));
-      snprintf(tmp, sizeof(tmp) - 1, ",%02x,", client_id->rnd);
+      silc_snprintf(tmp, sizeof(tmp) - 1, ",%02x,", client_id->rnd);
       _PUT_STRING(rid, tmp);
       memset(tmp, 0, sizeof(tmp));
-      snprintf(tmp, sizeof(tmp) - 1, "[%02x %02x %02x %02x...]",
+      silc_snprintf(tmp, sizeof(tmp) - 1, "[%02x %02x %02x %02x...]",
               client_id->hash[0], client_id->hash[1],
               client_id->hash[2], client_id->hash[3]);
       _PUT_STRING(rid, tmp);
@@ -1048,11 +1048,11 @@ char *silc_id_render(void *id, SilcIdType id_type)
       }
 
       memset(tmp, 0, sizeof(tmp));
-      snprintf(tmp, sizeof(tmp) - 1, ",%d,", ntohs(channel_id->port));
+      silc_snprintf(tmp, sizeof(tmp) - 1, ",%d,", ntohs(channel_id->port));
       _PUT_STRING(rid, tmp);
       SILC_PUT16_MSB(channel_id->rnd, tmps);
       memset(tmp, 0, sizeof(tmp));
-      snprintf(tmp, sizeof(tmp) - 1, "[%02x %02x]", tmps[0], tmps[1]);
+      silc_snprintf(tmp, sizeof(tmp) - 1, "[%02x %02x]", tmps[0], tmps[1]);
       _PUT_STRING(rid, tmp);
     }
     break;
index fd162c7a5440f7a2a87b445d922278b577549a3d..911515b2b88ae472c2ba7d5ac2d26cc4ad1e0d05 100644 (file)
@@ -528,7 +528,7 @@ silc_asn1_decoder(SilcAsn1 asn1, SilcStack stack1, SilcAsn1Tag type,
          /* Set two OID values */
          memset(&tmpb, 0, sizeof(tmpb));
          memset(tmpstr, 0, sizeof(tmpstr));
-         snprintf(tmpstr, sizeof(tmpstr) - 1, "%lu.%lu",
+         silc_snprintf(tmpstr, sizeof(tmpstr) - 1, "%lu.%lu",
                   (unsigned long)(rdata[0] & 0xff) / 40,
                   (unsigned long)(rdata[0] & 0xff) % 40);
          silc_buffer_sstrformat(asn1->stack1, &tmpb, tmpstr, SILC_STR_END);
@@ -550,7 +550,7 @@ silc_asn1_decoder(SilcAsn1 asn1, SilcStack stack1, SilcAsn1Tag type,
            oid |= rdata[i];
 
            memset(tmpstr, 0, sizeof(tmpstr));
-           snprintf(tmpstr, sizeof(tmpstr) - 1, ".%lu", (unsigned long)oid);
+           silc_snprintf(tmpstr, sizeof(tmpstr) - 1, ".%lu", (unsigned long)oid);
            silc_buffer_sstrformat(asn1->stack1, &tmpb, tmpstr, SILC_STR_END);
          }
          *oidstr = tmpb.head;
index e3f2eafa2fd1601f65beaeecfeafa8d8e0dfb79b..a58298fc05f81ebf0610ce48f9455910eb0d097f 100644 (file)
@@ -423,6 +423,7 @@ SilcUInt16 silc_client_get_clients_by_list(SilcClient client,
   SilcUInt32 *res_argv_lens = NULL, *res_argv_types = NULL, res_argc = 0;
   SilcUInt16 idp_len, cmd_ident;
   SilcID id;
+  va_list tmp;
   int i;
 
   SILC_LOG_DEBUG(("Resolve clients from Client ID list"));
@@ -490,7 +491,7 @@ SilcUInt16 silc_client_get_clients_by_list(SilcClient client,
 
   /* We have the clients in cache, get them and call the completion */
   silc_client_get_clients_list_cb(client, conn, SILC_COMMAND_WHOIS,
-                                 SILC_STATUS_OK, SILC_STATUS_OK, in, NULL);
+                                 SILC_STATUS_OK, SILC_STATUS_OK, in, tmp);
   return 0;
 
  err:
@@ -1086,7 +1087,7 @@ SilcClientEntry silc_client_nickname_format(SilcClient client,
        }
 
        memset(tmp, 0, sizeof(tmp));
-       snprintf(tmp, sizeof(tmp) - 1, "%d", ++max);
+       silc_snprintf(tmp, sizeof(tmp) - 1, "%d", ++max);
        len = strlen(tmp);
        memcpy(&newnick[off], tmp, len);
        off += len;
index 9eec97400df16a58c9b9612ec67c2bcca9b23cad..09aac70782c21c3f1854aef78c0ac50b6bc8ab20 100644 (file)
@@ -317,7 +317,7 @@ static void silc_client_ftp_open_handle(SilcSFTP sftp,
 
   /* Open the actual local file */
   memset(path, 0, sizeof(path));
-  snprintf(path, sizeof(path) - 1, "%s%s", session->path ?
+  silc_snprintf(path, sizeof(path) - 1, "%s%s", session->path ?
           session->path : "", session->filepath);
   session->fd = silc_file_open(path, O_RDWR | O_CREAT | O_EXCL);
   if (session->fd < 0) {
index 34a160b98f148e8b0706bd84c838c962d6062e91..a0c791d81cbe90fb316f904e8095e4941a095137 100644 (file)
@@ -416,7 +416,7 @@ void silc_client_send_key_agreement(SilcClient client,
       port = params->local_port;
       if (!port) {
        /* Get listener port */
-       int sock;
+       SilcSocket sock;
        silc_socket_stream_get_info(stream, &sock, NULL, NULL, NULL);
        port = silc_net_get_local_port(sock);
       }
index afc3e27dcd1d6b118f121fa71c26b9cf5b2fc479..6de9eb089a91860680de499226a1a3189e2077bd 100644 (file)
@@ -325,7 +325,7 @@ static inline SilcBool silc_packet_stream_read(SilcPacketStream ps,
       }
 
       /* See if remote packet stream exist for this sender */
-      snprintf(tuple, sizeof(tuple), "%d%s", remote_port, remote_ip);
+      silc_snprintf(tuple, sizeof(tuple), "%d%s", remote_port, remote_ip);
       silc_mutex_lock(ps->sc->engine->lock);
       if (silc_hash_table_find(ps->sc->engine->udp_remote, tuple, NULL,
                               (void *)&remote)) {
@@ -796,7 +796,7 @@ void silc_packet_stream_destroy(SilcPacketStream stream)
   } else {
     /* Delete from UDP remote hash table */
     char tuple[64];
-    snprintf(tuple, sizeof(tuple), "%d%s", stream->remote_udp->remote_port,
+    silc_snprintf(tuple, sizeof(tuple), "%d%s", stream->remote_udp->remote_port,
             stream->remote_udp->remote_ip);
     silc_mutex_lock(stream->sc->engine->lock);
     silc_hash_table_del(stream->sc->engine->udp_remote, tuple);
index 7e7c234e72681cd6355c0e6b69aec9e51cf37215..cb9ef4229f3c695674728d7b91fcc3d14df41a2c 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
@@ -1529,7 +1529,8 @@ SilcBool silc_pkcs_silc_encrypt(void *public_key,
                                SilcUInt32 src_len,
                                unsigned char *dst,
                                SilcUInt32 dst_size,
-                               SilcUInt32 *ret_dst_len)
+                               SilcUInt32 *ret_dst_len,
+                               SilcRng rng)
 {
   SilcSILCPublicKey silc_pubkey = public_key;
 
@@ -1538,7 +1539,7 @@ SilcBool silc_pkcs_silc_encrypt(void *public_key,
 
   return silc_pubkey->pkcs->encrypt(silc_pubkey->public_key,
                                    src, src_len,
-                                   dst, dst_size, ret_dst_len);
+                                   dst, dst_size, ret_dst_len, rng);
 }
 
 /* Decrypts as specified in SILC protocol specification */
index 38029658e5409d4fe8dc0e58c9ee0fd7275169b6..06fe473a582cddae6b8f7ef750afa5575fa5a4be 100644 (file)
@@ -4,7 +4,7 @@
 
   Author: Pekka Riikonen <priikone@silcnet.org>
 
-  Copyright (C) 2005 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
@@ -69,7 +69,8 @@ SilcBool silc_pkcs_silc_encrypt(void *public_key,
                                SilcUInt32 src_len,
                                unsigned char *dst,
                                SilcUInt32 dst_size,
-                               SilcUInt32 *ret_dst_len);
+                               SilcUInt32 *ret_dst_len,
+                               SilcRng rng);
 SilcBool silc_pkcs_silc_decrypt(void *private_key,
                                unsigned char *src,
                                SilcUInt32 src_len,
index 4665c160d77545340f0edf49b2955ba950738d2e..457deb806cdcfca81a6f9c9818ee756844882e61 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
@@ -571,10 +571,10 @@ void silc_pkcs_private_key_free(SilcPrivateKey private_key)
 SilcBool silc_pkcs_encrypt(SilcPublicKey public_key,
                           unsigned char *src, SilcUInt32 src_len,
                           unsigned char *dst, SilcUInt32 dst_size,
-                          SilcUInt32 *dst_len)
+                          SilcUInt32 *dst_len, SilcRng rng)
 {
   return public_key->pkcs->encrypt(public_key->public_key, src, src_len,
-                                  dst, dst_size, dst_len);
+                                  dst, dst_size, dst_len, rng);
 }
 
 /* Decrypts */
index f0dfca17a306080053fddd768c506b06a1f742b3..78812b0f870bd3fcbbb1571fd7be6659d1f28932 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
@@ -155,7 +155,8 @@ typedef struct {
                      SilcUInt32 src_len,
                      unsigned char *dst,
                      SilcUInt32 dst_size,
-                     SilcUInt32 *ret_dst_len);
+                     SilcUInt32 *ret_dst_len,
+                     SilcRng rng);
   SilcBool (*decrypt)(void *private_key,
                      unsigned char *src,
                      SilcUInt32 src_len,
@@ -260,7 +261,8 @@ struct SilcPKCSObjectStruct {
                      SilcUInt32 src_len,
                      unsigned char *dst,
                      SilcUInt32 dst_size,
-                     SilcUInt32 *ret_dst_len);
+                     SilcUInt32 *ret_dst_len,
+                     SilcRng rng);
   SilcBool (*decrypt)(void *private_key,
                      unsigned char *src,
                      SilcUInt32 src_len,
@@ -656,7 +658,7 @@ void silc_pkcs_private_key_free(SilcPrivateKey private_key);
 SilcBool silc_pkcs_encrypt(SilcPublicKey public_key,
                           unsigned char *src, SilcUInt32 src_len,
                           unsigned char *dst, SilcUInt32 dst_size,
-                          SilcUInt32 *dst_len);
+                          SilcUInt32 *dst_len, SilcRng rng);
 
 /****f* silccrypt/SilcPKCSAPI/silc_pkcs_decrypt
  *
index 0094e13089bf348da224efe520ac4d600be0ad84..e3c6b68f38f75e305728f57c0d0fed4f7c1dd494 100644 (file)
@@ -4,7 +4,7 @@
 
   Author: Pekka Riikonen <priikone@silcnet.org>
 
-  Copyright (C) 2003 - 2006 Pekka Riikonen
+  Copyright (C) 2003 - 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
@@ -74,14 +74,15 @@ SilcBool silc_pkcs1_encode(SilcPkcs1BlockType bt,
 
   case SILC_PKCS1_BT_PUB:
     /* Encryption */
+    if (!rng) {
+      SILC_LOG_ERROR(("Cannot encrypt: random number generator not provided"));
+      return FALSE;
+    }
 
     /* It is guaranteed this routine does not return zero byte. */
-    if (rng)
-      for (i = 2; i < padlen; i++)
-       dest_data[i] = silc_rng_get_byte_fast(rng);
-    else
-      for (i = 2; i < padlen; i++)
-       dest_data[i] = silc_rng_global_get_byte_fast();
+    for (i = 2; i < padlen; i++)
+      dest_data[i] = silc_rng_get_byte_fast(rng);
+
     break;
   }
 
@@ -473,7 +474,8 @@ SilcBool silc_pkcs1_encrypt(void *public_key,
                            SilcUInt32 src_len,
                            unsigned char *dst,
                            SilcUInt32 dst_size,
-                           SilcUInt32 *ret_dst_len)
+                           SilcUInt32 *ret_dst_len,
+                           SilcRng rng)
 {
   RsaPublicKey *key = public_key;
   SilcMPInt mp_tmp;
@@ -488,7 +490,7 @@ SilcBool silc_pkcs1_encrypt(void *public_key,
 
   /* Pad data */
   if (!silc_pkcs1_encode(SILC_PKCS1_BT_PUB, src, src_len,
-                        padded, len, NULL))
+                        padded, len, rng))
     return FALSE;
 
   silc_mp_init(&mp_tmp);
index f70b2acd9baa0a23ffa9b480c1e80343b2ac7312..6b699d94d87c0dc95c9e642fe779417c0609f28f 100644 (file)
@@ -34,7 +34,7 @@ SilcBuffer silc_http_php(char *php_data)
     return NULL;
 #else
   memset(tmp, 0, sizeof(tmp));
-  snprintf(tmp, sizeof(tmp) - 1, "/tmp/silchttpphpXXXXXX");
+  silc_snprintf(tmp, sizeof(tmp) - 1, "/tmp/silchttpphpXXXXXX");
   if (mkstemp(tmp) == -1)
     return NULL;
   name = tmp;
@@ -66,7 +66,7 @@ SilcBuffer silc_http_php_file(const char *filename)
   SILC_LOG_DEBUG(("Executing PHP"));
 
   memset(tmp, 0, sizeof(tmp));
-  snprintf(tmp, sizeof(tmp) - 1, "php -f %s", filename);
+  silc_snprintf(tmp, sizeof(tmp) - 1, "php -f %s", filename);
 
 #ifdef SILC_WIN32
   fd = _popen(tmp, "r");
index d2700ff20749dfb42d1fd2730ff2f7f20d489111..ed01beaed1d546a91c74eba09090f9b7d8de91b5 100644 (file)
@@ -547,11 +547,11 @@ SilcBool silc_http_server_send(SilcHttpServer httpd,
 
   silc_mime_add_field(conn->headers, "Last-Modified",
                      silc_time_string(conn->touched));
-  snprintf(tmp, sizeof(tmp), "%d", (int)silc_buffer_len(data));
+  silc_snprintf(tmp, sizeof(tmp), "%d", (int)silc_buffer_len(data));
   silc_mime_add_field(conn->headers, "Content-Length", tmp);
   if (conn->keepalive) {
     silc_mime_add_field(conn->headers, "Connection", "keep-alive");
-    snprintf(tmp, sizeof(tmp), "%d", (int)SILC_HTTP_SERVER_TIMEOUT);
+    silc_snprintf(tmp, sizeof(tmp), "%d", (int)SILC_HTTP_SERVER_TIMEOUT);
     silc_mime_add_field(conn->headers, "Keep-alive", tmp);
   }
 
index 5f9a61abe0673b807c6d3995b6aa2a81a44ef954..4b585e0eb86c9a95ce1130c688a22731fcbb87ae 100644 (file)
@@ -47,7 +47,7 @@ SilcBool silc_server_send_error(SilcPacketStream stream, const char *fmt, ...)
 
   memset(buf, 0, sizeof(buf));
   va_start(ap, fmt);
-  vsnprintf(buf, sizeof(buf) - 1, fmt, ap);
+  vsilc_snprintf(buf, sizeof(buf) - 1, fmt, ap);
   va_end(ap);
 
   return silc_packet_send(stream, SILC_PACKET_ERROR, 0, buf, strlen(buf));
index cad6f55fb5b106b8814563bad2a374bfbaa7baed..7ad789a9554dd2e4a71a31190edc254d5b4b743c 100644 (file)
@@ -555,8 +555,8 @@ SILC_FSM_STATE(silc_server_st_accept_client)
   ret = silc_parse_userfqdn(username, u, 128, h, sizeof(h));
   if (ret < 2) {
     /* Hostname not present, add it */
-    snprintf(n, sizeof(n), "%s", u);
-    snprintf(u, sizeof(u) - 1, "%s@%s", n, ac->hostname);
+    silc_snprintf(n, sizeof(n), "%s", u);
+    silc_snprintf(u, sizeof(u) - 1, "%s@%s", n, ac->hostname);
   } else {
     /* Verify that hostname is same than resolved hostname */
     if (strcmp(ac->hostname, h)) {
@@ -568,8 +568,8 @@ SILC_FSM_STATE(silc_server_st_accept_client)
       silc_fsm_next(fsm, silc_server_st_accept_error);
       SILC_FSM_CONTINUE;
     }
-    snprintf(n, sizeof(n), "%s", u);
-    snprintf(u, sizeof(u) - 1, "%s@%s", n, h);
+    silc_snprintf(n, sizeof(n), "%s", u);
+    silc_snprintf(u, sizeof(u) - 1, "%s@%s", n, h);
   }
 
   /* If configured as anonymous, scramble the username and hostname */
index dc0557612845f5381a79cb66eed4053095a0b417..66d393ace550649aa2ce95b3d685320db593b928 100644 (file)
@@ -788,7 +788,7 @@ void mem_readdir(void *context, SilcSFTP sftp,
     /* Long name format is:
        drwx------   1   324210 Apr  8 08:40 mail/
        1234567890 123 12345678 123456789012 */
-    snprintf(long_name, sizeof(long_name) - 1,
+    silc_snprintf(long_name, sizeof(long_name) - 1,
             "%c%c%c%c------ %3d %8llu %12s %s%s",
             (entry->directory ? 'd' : '-'),
             ((entry->perm & SILC_SFTP_FS_PERM_READ) ? 'r' : '-'),
index f2317c9e13d34db64ed88f0d95be13b05763b8e9..1ed22beb005b340c51cf271c4855d95b9b856e0a 100644 (file)
@@ -20,6 +20,8 @@
 #include "silc.h"
 #include "silcskr.h"
 
+/* XXX Locking, when removing keys */
+
 /************************** Types and definitions ***************************/
 
 /* Search constraints */
@@ -77,16 +79,16 @@ static void silc_skr_type_string(SilcSKRFindType type, void *data,
   switch (type) {
   case SILC_SKR_FIND_PKCS_TYPE:
   case SILC_SKR_FIND_USAGE:
-    snprintf(retbuf, retbuf_size, "[%s] [%d]", find_name[type],
+    silc_snprintf(retbuf, retbuf_size, "[%s] [%d]", find_name[type],
             (int)SILC_PTR_TO_32(data));
     break;
 
   case SILC_SKR_FIND_PUBLIC_KEY:
-    snprintf(retbuf, retbuf_size, "[%s] [%p]", find_name[type], data);
+    silc_snprintf(retbuf, retbuf_size, "[%s] [%p]", find_name[type], data);
     break;
 
   default:
-    snprintf(retbuf, retbuf_size, "[%s] [%s]", find_name[type],
+    silc_snprintf(retbuf, retbuf_size, "[%s] [%s]", find_name[type],
             (char *)data);
   }
 }
index 76c73df80dafbe7b174dd7168866ff13ad87c8b1..cb837bd31d619ebe5438c535b4bbf4f28516967a 100644 (file)
@@ -3,7 +3,7 @@
 #
 #  Author: Pekka Riikonen <priikone@silcnet.org>
 #
-#  Copyright (C) 2000 - 2005 Pekka Riikonen
+#  Copyright (C) 2000 - 2006 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
@@ -20,22 +20,14 @@ AUTOMAKE_OPTIONS = 1.0 no-dependencies foreign
 if SILC_WIN32
 SUBDIRS=win32
 else
-if SILC_EPOC
-SUBDIRS=epoc
-else
-if SILC_BEOS
-SUBDIRS=beos
-else
-if SILC_OS2
-SUBDIRS=os2
+if SILC_SYMBIAN
+SUBDIRS=symbian
 else
 SUBDIRS=unix
 endif
 endif
-endif
-endif
 
-DIST_SUBDIRS=win32 epoc beos os2 unix
+DIST_SUBDIRS=win32 symbian unix
 
 #ifdef SILC_DIST_TOOLKIT
 SILC_DIST_SOURCE = stacktrace.c
index 1c0116f22ce67016fec0d678edae9907bafeedfb..9deff33a48fecad72710977349a000d2519bdf97 100644 (file)
@@ -112,7 +112,7 @@ static void silc_log_checksize(SilcLog log)
   fclose(log->fp);
 
   memset(newname, 0, sizeof(newname));
-  snprintf(newname, sizeof(newname) - 1, "%s.old", log->filename);
+  silc_silc_snprintf(newname, sizeof(newname) - 1, "%s.old", log->filename);
   unlink(newname);
   rename(log->filename, newname);
 
index aa138a5100188e0216e4b02f7eac1bc8c45138f9..14fde956f14e7b2379ca973d535294ca5e1acc24 100644 (file)
@@ -229,10 +229,10 @@ SilcMime silc_mime_decode(SilcMime mime, const unsigned char *data,
       line = strdup(value);
       if (strrchr(line, '"')) {
        *strrchr(line, '"') = '\0';
-       snprintf(b, sizeof(b) - 1, "--%s", line + 1);
+       silc_silc_snprintf(b, sizeof(b) - 1, "--%s", line + 1);
        mime->boundary = strdup(line + 1);
       } else {
-       snprintf(b, sizeof(b) - 1, "--%s", line);
+       silc_silc_snprintf(b, sizeof(b) - 1, "--%s", line);
        mime->boundary = strdup(line);
       }
       silc_free(line);
@@ -325,7 +325,7 @@ unsigned char *silc_mime_encode(SilcMime mime, SilcUInt32 *encoded_len)
   while (silc_hash_table_get(&htl, (void **)&field, (void **)&value)) {
     memset(tmp, 0, sizeof(tmp));
     SILC_LOG_DEBUG(("Header %s: %s", field, value));
-    snprintf(tmp, sizeof(tmp) - 1, "%s: %s\r\n", field, value);
+    silc_silc_snprintf(tmp, sizeof(tmp) - 1, "%s: %s\r\n", field, value);
     silc_buffer_strformat(&buf, tmp, SILC_STRFMT_END);
     i++;
   }
@@ -370,8 +370,8 @@ unsigned char *silc_mime_encode(SilcMime mime, SilcUInt32 *encoded_len)
 
       /* If fields are not present, add extra CRLF */
       if (!silc_hash_table_count(part->fields))
-       snprintf(tmp2, sizeof(tmp2) - 1, "\r\n");
-      snprintf(tmp, sizeof(tmp) - 1, "%s--%s\r\n%s",
+       silc_silc_snprintf(tmp2, sizeof(tmp2) - 1, "\r\n");
+      silc_silc_snprintf(tmp, sizeof(tmp) - 1, "%s--%s\r\n%s",
               i != 0 ? "\r\n" : "", mime->boundary, tmp2);
       i = 1;
 
@@ -387,7 +387,7 @@ unsigned char *silc_mime_encode(SilcMime mime, SilcUInt32 *encoded_len)
     }
 
     memset(tmp, 0, sizeof(tmp));
-    snprintf(tmp, sizeof(tmp) - 1, "\r\n--%s--\r\n", mime->boundary);
+    silc_silc_snprintf(tmp, sizeof(tmp) - 1, "\r\n--%s--\r\n", mime->boundary);
     buffer = silc_buffer_realloc(buffer, silc_buffer_truelen(buffer) +
                                 strlen(tmp));
     if (!buffer)
@@ -578,7 +578,7 @@ SilcDList silc_mime_encode_partial(SilcMime mime, int max_size)
     memset(type, 0, sizeof(type));
     gethostname(type, sizeof(type) - 1);
     srand((time(NULL) + buf_len) ^ rand());
-    snprintf(id, sizeof(id) - 1, "%X%X%X%s",
+    silc_silc_snprintf(id, sizeof(id) - 1, "%X%X%X%s",
             (unsigned int)rand(), (unsigned int)time(NULL),
             (unsigned int)buf_len, type);
 
@@ -590,7 +590,7 @@ SilcDList silc_mime_encode_partial(SilcMime mime, int max_size)
 
     silc_mime_add_field(partial, "MIME-Version", "1.0");
     memset(type, 0, sizeof(type));
-    snprintf(type, sizeof(type) - 1,
+    silc_silc_snprintf(type, sizeof(type) - 1,
             "message/partial; id=\"%s\"; number=1", id);
     silc_mime_add_field(partial, "Content-Type", type);
     silc_mime_add_data(partial, buf, max_size);
@@ -620,14 +620,14 @@ SilcDList silc_mime_encode_partial(SilcMime mime, int max_size)
       silc_mime_add_field(partial, "MIME-Version", "1.0");
 
       if (len > max_size) {
-       snprintf(type, sizeof(type) - 1,
+       silc_silc_snprintf(type, sizeof(type) - 1,
                 "message/partial; id=\"%s\"; number=%d",
                 id, num++);
        silc_mime_add_data(partial, buf + off, max_size);
        off += max_size;
        len -= max_size;
       } else {
-       snprintf(type, sizeof(type) - 1,
+       silc_silc_snprintf(type, sizeof(type) - 1,
                 "message/partial; id=\"%s\"; number=%d; total=%d",
                 id, num, num);
        silc_mime_add_data(partial, buf + off, len);
@@ -777,7 +777,7 @@ void silc_mime_set_multipart(SilcMime mime, const char *type,
     return;
 
   memset(tmp, 0, sizeof(tmp));
-  snprintf(tmp, sizeof(tmp) - 1, "multipart/%s; boundary=%s", type, boundary);
+  silc_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);
index 2a868d22ac37f7e0de240a850e13fb34f8fdc98b..a6c0f9271456171013bc36b0aac679bae7a2b03c 100644 (file)
@@ -248,7 +248,8 @@ void silc_net_gethostbyname_async(const char *name,
 
 /* Resolves hostname by IP address. */
 
-SilcBool silc_net_gethostbyaddr(const char *addr, char *name, SilcUInt32 name_len)
+SilcBool silc_net_gethostbyaddr(const char *addr, char *name,
+                               SilcUInt32 name_len)
 {
 #ifdef HAVE_IPV6
   struct addrinfo req, *ai;
@@ -300,10 +301,13 @@ void silc_net_gethostbyaddr_async(const char *addr,
   silc_thread_create(silc_net_gethostbyaddr_thread, r, FALSE);
 }
 
+#ifndef SILC_SYMBIAN
+
 /* Performs lookups for remote name and IP address. This peforms reverse
    lookup as well to verify that the IP has FQDN. */
 
-SilcBool silc_net_check_host_by_sock(int sock, char **hostname, char **ip)
+SilcBool silc_net_check_host_by_sock(SilcSocket sock, char **hostname,
+                                    char **ip)
 {
   char host[1024];
   int rval, len;
@@ -381,7 +385,8 @@ SilcBool silc_net_check_host_by_sock(int sock, char **hostname, char **ip)
 /* Performs lookups for local name and IP address. This peforms reverse
    lookup as well to verify that the IP has FQDN. */
 
-SilcBool silc_net_check_local_by_sock(int sock, char **hostname, char **ip)
+SilcBool silc_net_check_local_by_sock(SilcSocket sock, char **hostname,
+                                     char **ip)
 {
   char host[1024];
   int rval, len;
@@ -458,7 +463,7 @@ SilcBool silc_net_check_local_by_sock(int sock, char **hostname, char **ip)
 
 /* Return remote port by socket. */
 
-SilcUInt16 silc_net_get_remote_port(int sock)
+SilcUInt16 silc_net_get_remote_port(SilcSocket sock)
 {
 #ifdef HAVE_IPV6
   struct sockaddr_storage remote;
@@ -490,7 +495,7 @@ SilcUInt16 silc_net_get_remote_port(int sock)
 
 /* Return local port by socket. */
 
-SilcUInt16 silc_net_get_local_port(int sock)
+SilcUInt16 silc_net_get_local_port(SilcSocket sock)
 {
 #ifdef HAVE_IPV6
   struct sockaddr_storage local;
@@ -519,6 +524,7 @@ SilcUInt16 silc_net_get_local_port(int sock)
   return ntohs(local.sin_port);
 #endif
 }
+#endif /* !SILC_SYMBIAN */
 
 /* Return name of localhost. */
 
index 30edce4e3e0b1572ce47d3ae978ff75cbc07b03e..c4a1f045d4d9e2cda364dd07db0f07cf657851fb 100644 (file)
@@ -313,7 +313,8 @@ int silc_net_udp_send(SilcStream stream,
  *
  * DESCRIPTION
  *
- *    Closes the connection by closing the socket connection.
+ *    Closes the connection by closing the socket connection.  This routine
+ *    can only be used with POSIX compliant systems.
  *
  ***/
 void silc_net_close_connection(int sock);
@@ -326,24 +327,13 @@ void silc_net_close_connection(int sock);
  *
  * DESCRIPTION
  *
- *    Accepts a connection from a particular socket.
+ *    Accepts a connection from a particular socket.  This routine can only
+ *    be used with POSIX compliant systems.  This call is equivalent to
+ *    accept(2).
  *
  ***/
 int silc_net_accept_connection(int sock);
 
-/****f* silcutil/SilcNetAPI/silc_net_set_socket_nonblock
- *
- * SYNOPSIS
- *
- *    int silc_net_set_socket_nonblock(int sock);
- *
- * DESCRIPTION
- *
- *    Sets the socket to non-blocking mode.
- *
- ***/
-int silc_net_set_socket_nonblock(int sock);
-
 /****f* silcutil/SilcNetAPI/silc_net_set_socket_opt
  *
  * SYNOPSIS
@@ -354,7 +344,8 @@ int silc_net_set_socket_nonblock(int sock);
  *
  *    Sets a option for a socket.  This function can be used to set
  *    various options for the socket.  Some of the options might be
- *    system specific.
+ *    system specific.  This routine can only be used with POSIX compliant
+ *    systems.  This call is equivalent to setsockopt(2);
  *
  ***/
 int silc_net_set_socket_opt(int sock, int level, int option, int on);
@@ -368,12 +359,27 @@ int silc_net_set_socket_opt(int sock, int level, int option, int on);
  *
  * DESCRIPTION
  *
- *    Return socket options to the `optval' and `opt_len'.
+ *    Return socket options to the `optval' and `opt_len'.  This routine
+ *    can only be used with POSIX compliant systems.  This call is
+ *    equivalent to getsockopt(2).
  *
  ***/
 int silc_net_get_socket_opt(int sock, int level, int option,
                            void *optval, int *opt_len);
 
+/****f* silcutil/SilcNetAPI/silc_net_set_socket_nonblock
+ *
+ * SYNOPSIS
+ *
+ *    int silc_net_set_socket_nonblock(SilcSocket sock);
+ *
+ * DESCRIPTION
+ *
+ *    Sets the socket `sock' to non-blocking mode.
+ *
+ ***/
+int silc_net_set_socket_nonblock(SilcSocket sock);
+
 /****f* silcutil/SilcNetAPI/silc_net_is_ip4
  *
  * SYNOPSIS
@@ -539,7 +545,7 @@ void silc_net_gethostbyaddr_async(const char *addr,
  *
  * SYNOPSIS
  *
- *    SilcBool silc_net_check_host_by_sock(int sock, char **hostname,
+ *    SilcBool silc_net_check_host_by_sock(SilcSocket sock, char **hostname,
  *                                         char **ip);
  *
  * DESCRIPTION
@@ -548,13 +554,14 @@ void silc_net_gethostbyaddr_async(const char *addr,
  *    lookup as well to verify that the IP has FQDN.
  *
  ***/
-SilcBool silc_net_check_host_by_sock(int sock, char **hostname, char **ip);
+SilcBool silc_net_check_host_by_sock(SilcSocket sock, char **hostname,
+                                    char **ip);
 
 /****f* silcutil/SilcNetAPI/silc_net_check_local_by_sock
  *
  * SYNOPSIS
  *
- *    SilcBool silc_net_check_local_by_sock(int sock, char **hostname,
+ *    SilcBool silc_net_check_local_by_sock(SilcSocket sock, char **hostname,
  *                                          char **ip);
  *
  * DESCRIPTION
@@ -563,33 +570,34 @@ SilcBool silc_net_check_host_by_sock(int sock, char **hostname, char **ip);
  *    lookup as well to verify that the IP has FQDN.
  *
  ***/
-SilcBool silc_net_check_local_by_sock(int sock, char **hostname, char **ip);
+SilcBool silc_net_check_local_by_sock(SilcSocket sock, char **hostname,
+                                     char **ip);
 
 /****f* silcutil/SilcNetAPI/silc_net_get_remote_port
  *
  * SYNOPSIS
  *
- *    SilcUInt16 silc_net_get_remote_port(int sock);
+ *    SilcUInt16 silc_net_get_remote_port(SilcSocket sock);
  *
  * DESCRIPTION
  *
  *    Return remote port by socket.
  *
  ***/
-SilcUInt16 silc_net_get_remote_port(int sock);
+SilcUInt16 silc_net_get_remote_port(SilcSocket sock);
 
 /****f* silcutil/SilcNetAPI/silc_net_get_local_port
  *
  * SYNOPSIS
  *
- *    SilcUInt16 silc_net_get_local_port(int sock);
+ *    SilcUInt16 silc_net_get_local_port(SilcSocket sock);
  *
  * DESCRIPTION
  *
  *    Return local port by socket.
  *
  ***/
-SilcUInt16 silc_net_get_local_port(int sock);
+SilcUInt16 silc_net_get_local_port(SilcSocket sock);
 
 /****f* silcutil/SilcNetAPI/silc_net_localhost
  *
index 7cc356e20e2b450ccda83b846d60915ad51adf8b..a5ec1038ac3354da86d39547f06969132ddc5148 100644 (file)
 #error "Do not include this header directly"
 #endif
 
-/* Net listenrr context */
+/* Net listener context */
 struct SilcNetListenerStruct {
   SilcSchedule schedule;
   SilcNetCallback callback;
   void *context;
-  int *socks;
+  SilcSocket *socks;
   unsigned int socks_count   : 30;
   unsigned int require_fqdn  : 1;
   unsigned int lookup        : 1;
index 1c4e952a232cd1540075f180f1d207d2e95ebb54..c320644737440f01c2991fe79636de0fea0a493e 100644 (file)
 
 /************************** Types and definitions ***************************/
 
-#define SILC_IS_SOCKET_STREAM(s) (s->ops == &silc_socket_stream_ops)
-#define SILC_IS_SOCKET_STREAM_UDP(s) (s->ops == &silc_socket_udp_stream_ops)
-
-const SilcStreamOps silc_socket_stream_ops;
-const SilcStreamOps silc_socket_udp_stream_ops;
-
-/* Platform specific functions */
+/* Stream operation functions (platform specific) */
 int silc_socket_stream_read(SilcStream stream, unsigned char *buf,
                            SilcUInt32 buf_len);
 int silc_socket_stream_write(SilcStream stream, const unsigned char *data,
@@ -38,6 +32,13 @@ int silc_socket_udp_stream_read(SilcStream stream, unsigned char *buf,
                                SilcUInt32 buf_len);
 int silc_socket_udp_stream_write(SilcStream stream, const unsigned char *data,
                                 SilcUInt32 data_len);
+SilcBool silc_socket_stream_close(SilcStream stream);
+void silc_socket_stream_destroy(SilcStream stream);
+void silc_socket_stream_notifier(SilcStream stream,
+                                SilcSchedule schedule,
+                                SilcStreamNotifier callback,
+                                void *context);
+SilcSchedule silc_socket_stream_get_schedule(SilcStream stream);
 
 /* Internal async host lookup context. */
 typedef struct {
@@ -53,30 +54,6 @@ typedef struct {
 
 /************************ Static utility functions **************************/
 
-/* The IO process callback that calls the notifier callback to upper
-   layer. */
-
-SILC_TASK_CALLBACK(silc_socket_stream_io)
-{
-  SilcSocketStream stream = context;
-
-  if (silc_unlikely(!stream->notifier))
-    return;
-
-  switch (type) {
-  case SILC_TASK_READ:
-    stream->notifier(stream, SILC_STREAM_CAN_READ, stream->notifier_context);
-    break;
-
-  case SILC_TASK_WRITE:
-    stream->notifier(stream, SILC_STREAM_CAN_WRITE, stream->notifier_context);
-    break;
-
-  default:
-    break;
-  }
-}
-
 /* Finishing timeout callback that will actually call the user specified
    host lookup callback.  This is executed back in the calling thread and
    not in the lookup thread. */
@@ -88,20 +65,16 @@ SILC_TASK_CALLBACK(silc_socket_host_lookup_finish)
 
   if (lookup->aborted) {
     SILC_LOG_DEBUG(("Socket stream creation was aborted"));
-    silc_net_close_connection(stream->sock);
-    silc_free(stream->ip);
-    silc_free(stream->hostname);
-    silc_free(stream);
+    stream->schedule = NULL;
+    silc_socket_stream_destroy(stream);
     silc_free(lookup);
     return;
   }
 
   if (lookup->status != SILC_SOCKET_OK) {
     SILC_LOG_DEBUG(("Socket stream failed"));
-    silc_net_close_connection(stream->sock);
-    silc_free(stream->ip);
-    silc_free(stream->hostname);
-    silc_free(stream);
+    stream->schedule = NULL;
+    silc_socket_stream_destroy(stream);
     stream = lookup->stream = NULL;
   }
 
@@ -170,7 +143,7 @@ static void silc_socket_host_lookup_abort(SilcAsyncOperation op,
 /* Creates TCP socket stream */
 
 SilcAsyncOperation
-silc_socket_tcp_stream_create(int sock, SilcBool lookup,
+silc_socket_tcp_stream_create(SilcSocket sock, SilcBool lookup,
                              SilcBool require_fqdn,
                              SilcSchedule schedule,
                              SilcSocketStreamCallback callback,
@@ -179,6 +152,12 @@ silc_socket_tcp_stream_create(int sock, SilcBool lookup,
   SilcSocketStream stream;
   SilcSocketHostLookup l;
 
+  if (!sock) {
+    if (callback)
+      callback(SILC_SOCKET_ERROR, NULL, context);
+    return NULL;
+  }
+
   stream = silc_calloc(1, sizeof(*stream));
   if (!stream) {
     if (callback)
@@ -232,7 +211,7 @@ silc_socket_tcp_stream_create(int sock, SilcBool lookup,
 
 /* Creates UDP socket stream */
 
-SilcStream silc_socket_udp_stream_create(int sock, SilcBool ipv6,
+SilcStream silc_socket_udp_stream_create(SilcSocket sock, SilcBool ipv6,
                                         SilcBool connected,
                                         SilcSchedule schedule)
 {
@@ -271,7 +250,7 @@ SilcBool silc_socket_stream_is_udp(SilcStream stream, SilcBool *connected)
 /* Returns socket stream information */
 
 SilcBool silc_socket_stream_get_info(SilcStream stream,
-                                    int *sock, const char **hostname,
+                                    SilcSocket *sock, const char **hostname,
                                     const char **ip, SilcUInt16 *port)
 {
   SilcSocketStream socket_stream = stream;
@@ -396,91 +375,6 @@ SilcBool silc_socket_stream_set_qos(SilcStream stream,
   return TRUE;
 }
 
-/* Closes socket */
-
-SilcBool silc_socket_stream_close(SilcStream stream)
-{
-  SilcSocketStream socket_stream = stream;
-
-  if (!SILC_IS_SOCKET_STREAM(socket_stream) &&
-      !SILC_IS_SOCKET_STREAM_UDP(socket_stream))
-    return FALSE;
-
-  silc_schedule_unset_listen_fd(socket_stream->schedule, socket_stream->sock);
-  silc_net_close_connection(socket_stream->sock);
-
-  return TRUE;
-}
-
-/* Destroys the stream */
-
-void silc_socket_stream_destroy(SilcStream stream)
-{
-  SilcSocketStream socket_stream = stream;
-
-  if (!SILC_IS_SOCKET_STREAM(socket_stream) &&
-      !SILC_IS_SOCKET_STREAM_UDP(socket_stream))
-    return;
-
-  silc_socket_stream_close(socket_stream);
-  silc_free(socket_stream->ip);
-  silc_free(socket_stream->hostname);
-  silc_schedule_task_del_by_fd(socket_stream->schedule, socket_stream->sock);
-
-  if (socket_stream->qos) {
-    silc_schedule_task_del_by_context(socket_stream->schedule,
-                                     socket_stream->qos);
-    if (socket_stream->qos->buffer) {
-      memset(socket_stream->qos->buffer, 0,
-            socket_stream->qos->read_limit_bytes);
-      silc_free(socket_stream->qos->buffer);
-    }
-    silc_free(socket_stream->qos);
-  }
-
-  silc_schedule_wakeup(socket_stream->schedule);
-
-  silc_free(socket_stream);
-}
-
-/* Sets stream notification callback for the stream */
-
-void silc_socket_stream_notifier(SilcStream stream,
-                                SilcSchedule schedule,
-                                SilcStreamNotifier callback,
-                                void *context)
-{
-  SilcSocketStream socket_stream = stream;
-
-  if (!SILC_IS_SOCKET_STREAM(socket_stream) &&
-      !SILC_IS_SOCKET_STREAM_UDP(socket_stream))
-    return;
-
-  SILC_LOG_DEBUG(("Setting stream notifier callback"));
-
-  socket_stream->notifier = callback;
-  socket_stream->notifier_context = context;
-  socket_stream->schedule = schedule;
-
-  if (socket_stream->notifier) {
-    /* Add the socket to scheduler.  Safe to call if already added. */
-    silc_schedule_task_add_fd(socket_stream->schedule, socket_stream->sock,
-                             silc_socket_stream_io, socket_stream);
-
-    /* Initially set socket for reading */
-    silc_schedule_set_listen_fd(socket_stream->schedule, socket_stream->sock,
-                               SILC_TASK_READ, FALSE);
-    silc_schedule_wakeup(socket_stream->schedule);
-  } else {
-    /* Unschedule the socket */
-    silc_schedule_unset_listen_fd(socket_stream->schedule,
-                                 socket_stream->sock);
-    silc_schedule_task_del_by_fd(socket_stream->schedule,
-                                socket_stream->sock);
-    silc_schedule_wakeup(socket_stream->schedule);
-  }
-}
-
 /* Return associated scheduler */
 
 SilcSchedule silc_socket_stream_get_schedule(SilcStream stream)
index e03c3255542fe5979b8d7a8f6941cde3d88afcfd..560e7e0f8faf6b36abab88fa5171e60644c6b01f 100644 (file)
@@ -71,11 +71,12 @@ typedef enum {
  *    Callback function of this type is called after the socket stream
  *    creation is completed.  If the `stream' is NULL the socket stream could
  *    not be created or the socket connection is not otherwise allowed.  The
- *    `status' will indicate the error status.  The `stream' is socket stream
- *    representing the socket connection and silc_socket_stream_* functions
- *    can be used to access the stream.  All other silc_stream_* functions
- *    can also be used to read data, send data, and otherwise handle the
- *    stream.
+ *    `status' will indicate the error status.  In case error ocurrs the
+ *    associated socket has already been destroyed.  The `stream' is socket
+ *    stream representing the socket connection and silc_socket_stream_*
+ *    functions can be used to access the stream.  All other silc_stream_*
+ *    functions can also be used to read data, send data, and otherwise
+ *    handle the stream.
  *
  ***/
 typedef void (*SilcSocketStreamCallback)(SilcSocketStreamStatus status,
@@ -86,7 +87,7 @@ typedef void (*SilcSocketStreamCallback)(SilcSocketStreamStatus status,
  * SYNOPSIS
  *
  *    SilcAsyncOperation
- *    silc_socket_tcp_stream_create(int sock, SilcBool lookup,
+ *    silc_socket_tcp_stream_create(SilcSocket sock, SilcBool lookup,
  *                                  SilcBool require_fqdn,
  *                                  SilcSchedule schedule,
  *                                  SilcSocketStreamCallback callback,
@@ -113,7 +114,7 @@ typedef void (*SilcSocketStreamCallback)(SilcSocketStreamStatus status,
  *
  ***/
 SilcAsyncOperation
-silc_socket_tcp_stream_create(int sock, SilcBool lookup,
+silc_socket_tcp_stream_create(SilcSocket sock, SilcBool lookup,
                              SilcBool require_fqdn,
                              SilcSchedule schedule,
                              SilcSocketStreamCallback callback,
@@ -123,7 +124,8 @@ silc_socket_tcp_stream_create(int sock, SilcBool lookup,
  *
  * SYNOPSIS
  *
- *    SilcStream silc_socket_udp_stream_create(int sock, SilcBool ipv6,
+ *    SilcStream silc_socket_udp_stream_create(SilcSocket sock,
+ *                                             SilcBool ipv6,
  *                                             SilcBool connected,
  *                                             SilcSchedule schedule);
  *
@@ -151,7 +153,8 @@ silc_socket_tcp_stream_create(int sock, SilcBool lookup,
  *    This function returns the created SilcStream or NULL on error.
  *
  ***/
-SilcStream silc_socket_udp_stream_create(int sock, SilcBool ipv6,
+SilcStream silc_socket_udp_stream_create(SilcSocket sock,
+                                        SilcBool ipv6,
                                         SilcBool connected,
                                         SilcSchedule schedule);
 
@@ -179,18 +182,18 @@ SilcBool silc_socket_stream_is_udp(SilcStream stream, SilcBool *connected);
  *
  *    SilcBool
  *    silc_socket_stream_get_info(SilcStream stream,
- *                                int *sock, const char **hostname,
+ *                                SilcSocket *sock, const char **hostname,
  *                                const char **ip, SilcUInt16 *port);
  *
  * DESCRIPTION
  *
- *    Returns socket stream information such as the socket number, hostname,
- *    IP address and the port of the remote socket connection.  Return FALSE
- *    if these informations are not available.
+ *    Returns socket stream information such as the socket, remote hostname,
+ *    remote IP address and the remote port of the remote socket connection.
+ *    Return FALSE if these informations are not available.
  *
  ***/
 SilcBool silc_socket_stream_get_info(SilcStream stream,
-                                    int *sock, const char **hostname,
+                                    SilcSocket *sock, const char **hostname,
                                     const char **ip, SilcUInt16 *port);
 
 /****f* silcutil/SilcSocketStreamAPI/silc_socket_stream_set_info
index 73547ea27d8d766a64b51d962a363e2b63b538bc..50385df3bddd38233031412e16383475bf78998d 100644 (file)
@@ -44,7 +44,7 @@ typedef struct SilcSocketQosStruct {
 struct SilcSocketStreamStruct {
   const SilcStreamOps *ops;
   SilcSchedule schedule;
-  int sock;
+  SilcSocket sock;
   char *hostname;
   char *ip;
   SilcUInt16 port;
@@ -56,4 +56,10 @@ struct SilcSocketStreamStruct {
   unsigned int connected : 1;      /* UDP connected state */
 };
 
+#define SILC_IS_SOCKET_STREAM(s) (s->ops == &silc_socket_stream_ops)
+#define SILC_IS_SOCKET_STREAM_UDP(s) (s->ops == &silc_socket_udp_stream_ops)
+
+extern const SilcStreamOps silc_socket_stream_ops;
+extern const SilcStreamOps silc_socket_udp_stream_ops;
+
 #endif /* SILCSOCKETSTREAM_I_H */
index db912fe3204b99ba3dcff8fedd3871760baf786e..5ba4c02e271d22d1a8d4731e8d67a475d22fc69a 100644 (file)
@@ -4,7 +4,7 @@
 
   Author: Pekka Riikonen <priikone@silcnet.org>
 
-  Copyright (C) 2002 - 2006 Pekka Riikonen
+  Copyright (C) 2002 - 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
@@ -170,6 +170,15 @@ unsigned char *silc_pem_decode(unsigned char *pem, SilcUInt32 pem_len,
   return data;
 }
 
+#ifndef HAVE_SNPRINTF
+/* Outputs string according to the `format'. */
+
+int silc_snprintf(char *str, SilcUInt32 size, const char *format, ...)
+{
+
+}
+#endif /* HAVE_SNPRINTF */
+
 /* Concatenates the `src' into `dest'.  If `src_len' is more than the
    size of the `dest' (minus NULL at the end) the `src' will be
    truncated to fit. */
index 0e20e98f91a17ca4d6b65f9066861e18ff0ea78d..1fdc0fd16b486c89242d7e91c14d8d17324cbb1a 100644 (file)
@@ -4,7 +4,7 @@
 
   Author: Pekka Riikonen <priikone@silcnet.org>
 
-  Copyright (C) 2002 - 2006 Pekka Riikonen
+  Copyright (C) 2002 - 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
@@ -111,6 +111,26 @@ char *silc_pem_encode_file(unsigned char *data, SilcUInt32 data_len);
 unsigned char *silc_pem_decode(unsigned char *pem, SilcUInt32 pem_len,
                               SilcUInt32 *ret_len);
 
+/****f* silcutil/SilcStrStrUtilAPI/silc_snprintf
+ *
+ * SYNOPSIS
+ *
+ *    int silc_snprintf(char *str, SilcUInt32 size, const char *format, ...);
+ *
+ * DESCRIPTION
+ *
+ *    Produces output string according to the `format'.  The formatting
+ *    is equivalent to silc_snprintf(3) and sprintf(3).  Returns the number of
+ *    characters output into `str', at most `size' characters including the
+ *    trailing '\0' character.  Returns negative value on error.
+ *
+ ***/
+#ifndef SILC_SNPRINTF
+int silc_snprintf(char *str, SilcUInt32 size, const char *format, ...);
+#else
+#define silc_snprintf snprintf
+#endif /* SILC_SNPRINTF */
+
 /****f* silcutil/SilcStrStrUtilAPI/silc_strncat
  *
  * SYNOPSIS
index 3f1abe7e871cb1344a09fd48def30383a58eafd6..b2f84c3c6af68afd9ad2fc169e1494f8759cc8db 100644 (file)
@@ -209,7 +209,7 @@ SilcBool silc_time_universal_string(SilcTime time_val, char *ret_string,
 {
   int ret, len = 0;
   memset(ret_string, 0, ret_string_size);
-  ret = snprintf(ret_string, ret_string_size - 1,
+  ret = silc_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);
@@ -218,12 +218,12 @@ SilcBool silc_time_universal_string(SilcTime time_val, char *ret_string,
   len += ret;
 
   if (!time_val->utc_hour && !time_val->utc_minute) {
-    ret = snprintf(ret_string + len, ret_string_size - 1 - len, "Z");
+    ret = silc_silc_snprintf(ret_string + len, ret_string_size - 1 - len, "Z");
     if (ret < 0)
       return FALSE;
     len += ret;
   } else {
-    ret = snprintf(ret_string + len, ret_string_size - 1 - len,
+    ret = silc_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);
     if (ret < 0)
@@ -319,7 +319,7 @@ SilcBool silc_time_generalized_string(SilcTime time_val, char *ret_string,
 {
   int len = 0, ret;
   memset(ret_string, 0, ret_string_size);
-  ret = snprintf(ret_string, ret_string_size - 1,
+  ret = silc_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);
@@ -328,7 +328,7 @@ SilcBool silc_time_generalized_string(SilcTime time_val, char *ret_string,
   len += ret;
 
   if (time_val->msecond) {
-    ret = snprintf(ret_string + len, ret_string_size - 1 - len,
+    ret = silc_silc_snprintf(ret_string + len, ret_string_size - 1 - len,
                   ".%lu", (unsigned long)time_val->msecond);
     if (ret < 0)
       return FALSE;
@@ -336,12 +336,12 @@ SilcBool silc_time_generalized_string(SilcTime time_val, char *ret_string,
   }
 
   if (!time_val->utc_hour && !time_val->utc_minute) {
-    ret = snprintf(ret_string + len, ret_string_size - 1 - len, "Z");
+    ret = silc_silc_snprintf(ret_string + len, ret_string_size - 1 - len, "Z");
     if (ret < 0)
       return FALSE;
     len += ret;
   } else {
-    ret = snprintf(ret_string + len, ret_string_size - 1 - len,
+    ret = silc_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);
     if (ret < 0)
index 851bdd011979f29d6925842344390829235efe8f..7500b1fb22d71a403d09f99267f47ed58d3bfe2e 100644 (file)
@@ -275,6 +275,28 @@ typedef SilcInt32 SilcInt64;
 typedef SilcUInt32 * void *;
 #endif
 
+/****d* silcutil/SILCTypes/SilcSocket
+ *
+ * NAME
+ *
+ *    SilcSocket
+ *
+ * DESCRIPTION
+ *
+ *    Platform specific socket.  On POSIX compliant systems this is simply
+ *    an integer, representing the socket. On other systems it is platform
+ *    specific socket context.  Access it only through routines that can
+ *    handle SilcSocket types, unless you know what you are doing.
+ *
+ * SOURCE
+ */
+#if defined(SILC_UNIX) || defined(SILC_WIN32)
+typedef int SilcSocket;
+#elif defined(SILC_SYMBIAN)
+typedef void * SilcSocket;
+#endif
+/***/
+
 /* Macros */
 
 #define SILC_GET_WORD(cp) ((SilcUInt32)(SilcUInt8)(cp)[0]) << 24       \
index 0ecc999c116b63314630cd681007b8e9d3e44416..29f74dc34dbc04795d19d542c18af30f83e8daf5 100644 (file)
@@ -491,7 +491,7 @@ SilcUInt32 silc_utf8_decode(const unsigned char *utf8, SilcUInt32 utf8_len,
              if (enclen + 3 > bin_size)
                return 0;
              bin[enclen] = '\\';
-             snprintf(bin + enclen + 1, 3, "%02X", cv);
+             silc_silc_snprintf(bin + enclen + 1, 3, "%02X", cv);
            }
            enclen += 3;
            continue;
index c412262452e550c2673c0f49950825bf7f497f7a..04b1036358433e3163c75ef64076f2b412cb5985 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
@@ -236,7 +236,7 @@ char *silc_format(char *fmt, ...)
 
   memset(buf, 0, sizeof(buf));
   va_start(args, fmt);
-  vsnprintf(buf, sizeof(buf) - 1, fmt, args);
+  vsilc_snprintf(buf, sizeof(buf) - 1, fmt, args);
   va_end(args);
 
   return strdup(buf);
@@ -473,14 +473,14 @@ char *silc_fingerprint(const unsigned char *data, SilcUInt32 data_len)
   memset(fingerprint, 0, sizeof(fingerprint));
   cp = fingerprint;
   for (i = 0; i < data_len; i++) {
-    snprintf(cp, sizeof(fingerprint), "%02X", data[i]);
+    silc_silc_snprintf(cp, sizeof(fingerprint), "%02X", data[i]);
     cp += 2;
 
     if ((i + 1) % 2 == 0)
-      snprintf(cp++, sizeof(fingerprint), " ");
+      silc_silc_snprintf(cp++, sizeof(fingerprint), " ");
 
     if ((i + 1) % 10 == 0)
-      snprintf(cp++, sizeof(fingerprint), " ");
+      silc_silc_snprintf(cp++, sizeof(fingerprint), " ");
   }
   i--;
   if ((i + 1) % 2 == 0)
diff --git a/lib/silcutil/symbian/Makefile.am b/lib/silcutil/symbian/Makefile.am
deleted file mode 100644 (file)
index 92e6b3e..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-#
-#  Makefile.am
-#
-#  Author: Pekka Riikonen <priikone@silcnet.org>
-#
-#  Copyright (C) 2002 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; either version 2 of the License, or
-#  (at your option) any later version.
-#
-#  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.
-#
-
-AUTOMAKE_OPTIONS = 1.0 no-dependencies foreign
-
-include $(top_srcdir)/Makefile.defines.in
diff --git a/lib/silcutil/symbian/silcepocsockconn.cpp b/lib/silcutil/symbian/silcepocsockconn.cpp
deleted file mode 100644 (file)
index 7c71207..0000000
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
-
-  silcepocsockconn.cpp 
-
-  Author: Pekka Riikonen <priikone@silcnet.org>
-
-  Copyright (C) 2002 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.
-
-*/
-/* $Id$ */
-
-#include "silcincludes.h"
-
-/* Writes data from encrypted buffer to the socket connection. If the
-   data cannot be written at once, it will be written later with a timeout. 
-   The data is written from the data section of the buffer, not from head
-   or tail section. This automatically pulls the data section towards end
-   after writing the data. */
-
-int silc_socket_write(SilcSocketConnection sock)
-{
-  /* XXX */
-}
-
-/* Reads data from the socket connection into the incoming data buffer.
-   It reads as much as possible from the socket connection. This returns
-   amount of bytes read or -1 on error or -2 on case where all of the
-   data could not be read at once. */
-
-int silc_socket_read(SilcSocketConnection sock)
-{
-  /* XXX */
-}
-
-/* Returns human readable socket error message. These are copied from the
-   PuTTY. */
-
-#define PUT_ERROR(s) 
-do {
-  if (strlen(s) > err_len)
-    return FALSE;
-  memset(error, 0, error_len);
-  memcpy(error, s, strlen(s));
-  return TRUE;
-} while(0)
-
-bool silc_socket_get_error(SilcSocketConnection sock, char *error,
-                          SilcUInt32 error_len)
-{
-  if (sock->sock_error == KErrNone)
-    return FALSE;
-
-  switch (sock->sock_error) {
-  case KErrNotFound:
-    PUT_ERROR("Item not found. (NotFound)");
-  case KErrGeneral:
-    PUT_ERROR("Uncategorized error. (General)");
-  case KErrCancel:
-    PUT_ERROR("Operation cancelled. (Cancel)");
-  case KErrNoMemory:
-    PUT_ERROR("A memory allocation failed. (NoMemory)");
-  case KErrNotSupported:
-    PUT_ERROR("A function is not supported in a given context. "
-             "(NotSupported)");
-  case KErrArgument:
-    PUT_ERROR("An argument is out of range. (Argument)");
-  case KErrBadHandle:
-    PUT_ERROR("Bad handle. (BadHandle)");
-  case KErrOverflow:
-    PUT_ERROR("Overflow. (Overflow)");
-  case KErrUnderflow:
-    PUT_ERROR("Underflow. (Underflow)");
-  case KErrAlreadyExists:
-    PUT_ERROR("The resource already exists. (AlreadyExists)");
-  case KErrPathNotFound:
-    PUT_ERROR("In the context of file operations, the path was "
-             "not found. (PathNotFound)");
-  case KErrDied:
-    PUT_ERROR("A handle refers to a thread which has died (Died)");
-  case KErrInUse:
-    PUT_ERROR("A requested resource is already in use. (InUse)");
-  case KErrServerTerminated:
-    PUT_ERROR("A client/server operation cannot execute, because the "
-             "server has terminated. (ServerTerminated)");
-  case KErrServerBusy:
-    PUT_ERROR("A client/server operation cannot execute, because the server "
-             "is busy. (ServerBusy)");
-  case KErrNotReady:
-    PUT_ERROR("Resource not ready. Not initialized, or has no power. "
-             "(NotReady)");
-  case KErrUnknown:
-    PUT_ERROR("A device is of unknown type. (Unknown)");
-  case KErrCorrupt:
-    PUT_ERROR("Corrupted. (Corrupt)");
-  case KErrAccessDenied:
-    PUT_ERROR("Access denied. (AccessDenied)");
-  case KErrLocked:
-    PUT_ERROR("The operation cannot be performed, because the resource "
-             "is locked. (Locked)");
-  case KErrWrite:
-    PUT_ERROR("During a file write operation, not all the data could "
-             "be written. (Write)");
-  case KErrDisMounted:
-    PUT_ERROR("A volume which was to be used for a file system operation "
-             "has been dismounted. (DisMounted)");
-  case KErrEof:
-    PUT_ERROR("End of file has been reached. (Eof)");
-  case KErrDiskFull:
-    PUT_ERROR("A write operation could not complete, because the disk "
-             "was full. (DiskFull)");
-  case KErrBadDriver:
-    PUT_ERROR("A driver DLL was of the wrong type. (BadDriver)");
-  case KErrBadName:
-    PUT_ERROR("Name did not conform with the required syntax. (BadName)");
-  case KErrCommsLineFail:
-    PUT_ERROR("The communication line failed. (CommsLineFail)");
-  case KErrCommsFrame:
-    PUT_ERROR("A frame error occurred in a communications operation. "
-             "(CommsFrame)");
-  case KErrCommsOverrun:
-    PUT_ERROR("An overrun was detected by a communications driver. "
-             "(CommsOverrun)");
-  case KErrCommsParity:
-    PUT_ERROR("A parity error occurred in communications. (CommsParity)");
-  case KErrTimedOut:
-    PUT_ERROR("An operation timed out. (TimedOut)");
-  case KErrCouldNotConnect:
-    PUT_ERROR("A session could not connect. (CouldNotConnect)");
-  case KErrCouldNotDisconnect:
-    PUT_ERROR("A session could not disconnect. (CouldNotDisconnect)");
-  case KErrDisconnected:
-    PUT_ERROR("The required session was disconnected. (Disconnected)");
-  case KErrBadLibraryEntryPoint:
-    PUT_ERROR("A library entry point was not of the required type. "
-             "(BadLibraryEntryPoint)");
-  case KErrBadDescriptor:
-    PUT_ERROR("A non-descriptor parameter was passed. (BadDescriptor)");
-  case KErrAbort:
-    PUT_ERROR("An operation was aborted (Abort)");
-  case KErrTooBig:
-    PUT_ERROR("A number was too big (TooBig)");
-  case KErrDivideByZero:
-    PUT_ERROR("A divide-by-zero operation was attempted. (DivideByZero)");
-  case KErrBadPower:
-    PUT_ERROR("Insufficient power was available to complete an operation. "
-             "(BadPower)");
-  case KErrWouldBlock:
-    PUT_ERROR("Network error: Resource temporarily unavailable (WouldBlock)");
-  case KErrNetUnreach:
-    PUT_ERROR("Network unreachable. (NetUnreach)");
-  case KErrHostUnreach:
-    PUT_ERROR("Host unreachable. (HostUnreach)");
-  case KErrNoProtocolOpt:
-    PUT_ERROR("No such protocol option. (NoProtocolOpt)");
-  case KErrUrgentData:
-    PUT_ERROR("Urgent data arrived. (UrgentData)");
-  case KInvalSocket:
-    PUT_ERROR("Got NULL sokcet.");
-  }
-
-  return FALSE;
-}
diff --git a/lib/silcutil/symbian/silcepocthread.cpp b/lib/silcutil/symbian/silcepocthread.cpp
deleted file mode 100644 (file)
index 12ad59c..0000000
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
-
-  silcepocthread.cpp
-
-  Author: Pekka Riikonen <priikone@silcnet.org>
-
-  Copyright (C) 2002 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.
-
-*/
-/* $Id$ */
-
-#include "silcincludes.h"
-
-#ifdef SILC_THREADS
-
-/* Thread structure for EPOC */
-typedef struct {
-  RThread *thread;
-  SilcThreadStart start_func;
-  void *context;
-  bool waitable;
-} *SilcEpocThread;
-
-/* The actual thread function */
-
-TInt silc_thread_epoc_start(TAny *context)
-{
-  SilcEpocThread thread = (SilcEpocThread)context;
-
-  thread->start_func(thread->context);
-  silc_thread_exit(NULL);
-
-  return 0;
-}
-
-SilcThread silc_thread_create(SilcThreadStart start_func, void *context,
-                             bool waitable)
-{
-#ifdef SILC_THREADS
-  SilcEpocThread thread;
-  TInt ret;
-
-  SILC_LOG_DEBUG(("Creating new thread"));
-
-  thread = silc_calloc(1, sizeof(*thread));
-  thread->start_func = start_func;
-  thread->context = context;
-  thread->waitable = waitable;
-
-  /* Create the thread */
-  /* XXX Unique name should be given for the thread */
-  thread->thread = new RThread();
-  ret = thread->thread->Create(NULL, silc_thread_epoc_start, 0, 0, 0,
-                              (TAny *)thread, EOwnerProcess);
-  if (ret != KErrNone) {
-    SILC_LOG_ERROR(("Could not create new thread"));
-    delete thread->thread;
-    silc_free(thread);
-    return NULL;
-  }
-
-  return (SilcThread)thread;
-#else
-  /* Call thread callback immediately */
-  (*start_func)(context);
-  return NULL;
-#endif
-}
-
-void silc_thread_exit(void *exit_value)
-{
-#ifdef SILC_THREADS
-  /* XXX */
-#endif
-}
-
-SilcThread silc_thread_self(void)
-{
-#ifdef SILC_THREADS
-  /* XXX */
-  return NULL;
-#else
-  return NULL;
-#endif
-}
-
-bool silc_thread_wait(SilcThread thread, void **exit_value)
-{
-#ifdef SILC_THREADS
-  /* XXX */
-  return TRUE;
-#else
-  return FALSE;
-#endif
-}
diff --git a/lib/silcutil/symbian/silcepocutil.cpp b/lib/silcutil/symbian/silcepocutil.cpp
deleted file mode 100644 (file)
index b43eda9..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
-
-  silcepocutil.cpp
-
-  Author: Pekka Riikonen <priikone@silcnet.org>
-
-  Copyright (C) 2002 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.
-
-*/
-/* $Id$ */
-
-#include "silcincludes.h"
-
-/* XXX TODO or use GNU regex if it compiles */
-char *silc_string_regexify(const char *string)
-{
-  return strdup(string);
-}
-
-char *silc_string_regex_combine(const char *string1, const char *string2)
-{
-  return strdup(string1);
-}
-
-int silc_string_regex_match(const char *regex, const char *string)
-{
-  return TRUE;
-}
-
-int silc_string_match(const char *string1, const char *string2)
-{
-  return TRUE;
-}
-
-/* Return current time to struct timeval. */
-
-int silc_gettimeofday(struct timeval *p)
-{
-  return gettimeofday(p, NULL);
-}
diff --git a/lib/silcutil/symbian/silcsymbiannet.cpp b/lib/silcutil/symbian/silcsymbiannet.cpp
new file mode 100644 (file)
index 0000000..f2ae993
--- /dev/null
@@ -0,0 +1,744 @@
+/*\r
+\r
+  silcsymbiannet.cpp\r
+\r
+  Author: Pekka Riikonen <priikone@silcnet.org>\r
+\r
+  Copyright (C) 2006 Pekka Riikonen\r
+\r
+  This program is free software; you can redistribute it and/or modify\r
+  it under the terms of the GNU General Public License as published by\r
+  the Free Software Foundation; version 2 of the License.\r
+\r
+  This program is distributed in the hope that it will be useful,\r
+  but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+  GNU General Public License for more details.\r
+\r
+*/\r
+\r
+#include "silc.h"\r
+#include "silcsymbiansocketstream.h"\r
+\r
+/****************************** TCP Listener ********************************/\r
+\r
+class SilcSymbianTCPListener;\r
+\r
+/* Deliver new stream to upper layer */\r
+\r
+static void silc_net_accept_stream(SilcSocketStreamStatus status,\r
+                                  SilcStream stream, void *context)\r
+{\r
+  SilcNetListener listener = (SilcNetListener)context;\r
+\r
+  /* In case of error, the socket has been destroyed already */\r
+  if (status != SILC_SOCKET_OK)\r
+    return;\r
+\r
+  listener->callback(SILC_NET_OK, stream, listener->context);\r
+}\r
+\r
+/* TCP Listener class */\r
+\r
+class SilcSymbianTCPListener : public CActive {\r
+public:\r
+  /* Constructor */\r
+  SilcSymbianTCPListener() : CActive(CActive::EPriorityStandard)\r
+  {\r
+    CActiveScheduler::Add(this);\r
+  }\r
+\r
+  /* Destructor */\r
+  ~SilcSymbianTCPListener()\r
+  {\r
+    Cancel();\r
+  }\r
+\r
+  /* Listen for connection */\r
+  void Listen()\r
+  {\r
+    new_conn = new RSocket;\r
+    if (!new_conn)\r
+      return;\r
+    User::LeaveIfError(new_conn->Open(ss));\r
+\r
+    /* Start listenning */\r
+    sock.Accept(*new_conn, iStatus);\r
+    SetActive();\r
+  }\r
+\r
+  /* Listener callback */\r
+  void RunL()\r
+  {\r
+    if (iStatus != KErrNone) {\r
+      if (new_conn)\r
+       delete new_conn;\r
+      new_conn = NULL;\r
+      Listen();\r
+      return;\r
+    }\r
+\r
+    /* Set socket options */\r
+    new_conn->SetOpt(KSoReuseAddr, KSolInetIp, 1);\r
+\r
+    /* Create socket stream */\r
+    silc_socket_tcp_stream_create(\r
+                       (SilcSocket)silc_create_symbian_socket(new_conn, NULL),\r
+                       listener->lookup, listener->require_fqdn,\r
+                       listener->schedule, silc_net_accept_stream,\r
+                       (void *)listener);\r
+\r
+    /* Continue listenning */\r
+    Listen();\r
+  }\r
+\r
+  /* Cancel */\r
+  void DoCancel()\r
+  {\r
+    sock.CancelAll();\r
+    ss.Close();\r
+    if (new_conn)\r
+      delete new_conn;\r
+  }\r
+\r
+  RSocket *new_conn;\r
+  RSocket sock;\r
+  RSocketServ ss;\r
+  SilcNetListener listener;\r
+};\r
+\r
+/* Create TCP listener */\r
+\r
+SilcNetListener\r
+silc_net_tcp_create_listener(const char **local_ip_addr,\r
+                            SilcUInt32 local_ip_count, int port,\r
+                            SilcBool lookup, SilcBool require_fqdn,\r
+                            SilcSchedule schedule,\r
+                            SilcNetCallback callback, void *context)\r
+{\r
+  SilcNetListener listener = NULL;\r
+  SilcSymbianTCPListener *l = NULL;\r
+  TInetAddr server;\r
+  TInt ret;\r
+  TBuf<64> tmp;\r
+  int i;\r
+\r
+  SILC_LOG_DEBUG(("Creating TCP listener"));\r
+\r
+  if (port < 0 || !schedule || !callback)\r
+    goto err;\r
+\r
+  listener = (SilcNetListener)silc_calloc(1, sizeof(*listener));\r
+  if (!listener) {\r
+    callback(SILC_NET_NO_MEMORY, NULL, context);\r
+    return NULL;\r
+  }\r
+  listener->schedule = schedule;\r
+  listener->callback = callback;\r
+  listener->context = context;\r
+  listener->require_fqdn = require_fqdn;\r
+  listener->lookup = lookup;\r
+\r
+  if (local_ip_count > 0) {\r
+    listener->socks = (SilcSocket *)silc_calloc(local_ip_count,\r
+                                             sizeof(*listener->socks));\r
+    if (!listener->socks) {\r
+      callback(SILC_NET_NO_MEMORY, NULL, context);\r
+      return NULL;\r
+    }\r
+  } else {\r
+    listener->socks = (SilcSocket *)silc_calloc(1, sizeof(*listener->socks));\r
+    if (!listener->socks) {\r
+      callback(SILC_NET_NO_MEMORY, NULL, context);\r
+      return NULL;\r
+    }\r
+\r
+    local_ip_count = 1;\r
+  }\r
+\r
+  /* Bind to local addresses */\r
+  for (i = 0; i < local_ip_count; i++) {\r
+    SILC_LOG_DEBUG(("Binding to local address %s",\r
+                   local_ip_addr ? local_ip_addr[i] : "0.0.0.0"));\r
+\r
+    l = new SilcSymbianTCPListener;\r
+    if (!l)\r
+      goto err;\r
+\r
+    /* Connect to socket server */\r
+    ret = l->ss.Connect();\r
+    if (ret != KErrNone)\r
+      goto err;\r
+\r
+    /* Set listener address */\r
+    if (local_ip_addr) {\r
+      server = TInetAddr(port);\r
+         tmp = (TText *)local_ip_addr[i];\r
+      ret = server.Input(tmp);\r
+      if (ret != KErrNone)\r
+       goto err;\r
+    } else {\r
+      server = TInetAddr(KInetAddrAny, port);\r
+    }\r
+\r
+    /* Create the socket */\r
+    ret = l->sock.Open(l->ss, KAfInet, KSockStream, KProtocolInetTcp);\r
+    if (ret != KErrNone) {\r
+      SILC_LOG_ERROR(("Cannot create socket"));\r
+      goto err;\r
+    }\r
+\r
+    /* Set the socket options */\r
+    ret = l->sock.SetOpt(KSoReuseAddr, KSolInetIp, 1);\r
+    if (ret != KErrNone) {\r
+      SILC_LOG_ERROR(("Cannot set socket options"));\r
+      goto err;\r
+    }\r
+\r
+    /* Bind the listener socket */\r
+    ret = l->sock.Bind(server);\r
+    if (ret != KErrNone) {\r
+      SILC_LOG_DEBUG(("Cannot bind socket"));\r
+      goto err;\r
+    }\r
+\r
+    /* Specify that we are listenning */\r
+    ret = l->sock.Listen(5);\r
+    if (ret != KErrNone) {\r
+      SILC_LOG_ERROR(("Cannot set socket listenning"));\r
+      goto err;\r
+    }\r
+    l->Listen();\r
+\r
+    l->listener = listener;\r
+    listener->socks[i] = (SilcSocket)l;\r
+    listener->socks_count++;\r
+  }\r
+\r
+  SILC_LOG_DEBUG(("TCP listener created"));\r
+\r
+  return listener;\r
+\r
+ err:\r
+  if (l)\r
+    delete l;\r
+  if (callback)\r
+    callback(SILC_NET_ERROR, NULL, context);\r
+  if (listener)\r
+    silc_net_close_listener(listener);\r
+  return NULL;\r
+}\r
+\r
+/* Close network listener */\r
+\r
+void silc_net_close_listener(SilcNetListener listener)\r
+{\r
+  int i;\r
+\r
+  SILC_LOG_DEBUG(("Closing network listener"));\r
+\r
+  for (i = 0; i < listener->socks_count; i++) {\r
+    SilcSymbianTCPListener *l = (SilcSymbianTCPListener *)listener->socks[i];\r
+    l->sock.CancelAll();\r
+    l->sock.Close();\r
+    l->ss.Close();\r
+    if (l->new_conn)\r
+      delete l->new_conn;\r
+    delete l;\r
+  }\r
+\r
+  silc_free(listener->socks);\r
+  silc_free(listener);\r
+}\r
+\r
+/**************************** TCP/IP connecting *****************************/\r
+\r
+static void silc_net_connect_stream(SilcSocketStreamStatus status,\r
+                                   SilcStream stream, void *context);\r
+\r
+/* TCP connecting class */\r
+\r
+class SilcSymbianTCPConnect : public CActive {\r
+public:\r
+  /* Constructor */\r
+  SilcSymbianTCPConnect() : CActive(CActive::EPriorityStandard)\r
+  {\r
+    CActiveScheduler::Add(this);\r
+  }\r
+\r
+  /* Destructor */\r
+  ~SilcSymbianTCPConnect()\r
+  {\r
+    silc_free(remote);\r
+    if (op)\r
+      silc_async_free(op);\r
+    Cancel();\r
+  }\r
+\r
+  /* Connect to remote host */\r
+  void Connect(TSockAddr &addr)\r
+  {\r
+    sock->Connect(addr, iStatus);\r
+    SetActive();\r
+  }\r
+\r
+  /* Connection callback */\r
+  void RunL()\r
+  {\r
+    if (iStatus != KErrNone) {\r
+      if (callback)\r
+       callback(SILC_NET_ERROR, NULL, context);\r
+      sock->CancelConnect();\r
+      delete sock;\r
+      ss->Close();\r
+      delete ss;\r
+      delete this;\r
+    }\r
+\r
+    /* Create stream */\r
+    if (callback) {\r
+      silc_socket_tcp_stream_create(\r
+                            (SilcSocket)silc_create_symbian_socket(sock, ss),\r
+                            FALSE, FALSE, schedule, silc_net_connect_stream,\r
+                            (void *)this);\r
+    } else {\r
+      sock->Close();\r
+      delete sock;\r
+      ss->Close();\r
+      delete ss;\r
+    }\r
+\r
+    delete this;\r
+  }\r
+\r
+  /* Cancel */\r
+  void DoCancel()\r
+  {\r
+    sock->CancelConnect();\r
+    ss->Close();\r
+    delete ss;\r
+    delete sock;\r
+    delete this;\r
+  }\r
+\r
+  RSocket *sock;\r
+  RSocketServ *ss;\r
+  char *remote;\r
+  char remote_ip[64];\r
+  int port;\r
+  SilcAsyncOperation op;\r
+  SilcSchedule schedule;\r
+  SilcNetCallback callback;\r
+  void *context;\r
+};\r
+\r
+/* Stream creation callback */\r
+\r
+static void silc_net_connect_stream(SilcSocketStreamStatus status,\r
+                                   SilcStream stream, void *context)\r
+{\r
+  SilcSymbianTCPConnect *conn = (SilcSymbianTCPConnect *)context;\r
+  SilcNetStatus net_status = SILC_NET_OK;\r
+\r
+  if (status != SILC_SOCKET_OK) {\r
+    /* In case of error, the socket has been destroyed already */\r
+    if (status == SILC_SOCKET_UNKNOWN_IP)\r
+      net_status = SILC_NET_UNKNOWN_IP;\r
+    else if (status == SILC_SOCKET_UNKNOWN_HOST)\r
+      net_status = SILC_NET_UNKNOWN_HOST;\r
+    else\r
+      net_status = SILC_NET_ERROR;\r
+  }\r
+\r
+  /* Set stream information */\r
+  if (stream && conn->callback)\r
+    silc_socket_stream_set_info(stream,\r
+                               !silc_net_is_ip(conn->remote) ? conn->remote :\r
+                               conn->remote_ip, conn->remote_ip, conn->port);\r
+\r
+  /* Call connection callback */\r
+  if (conn->callback)\r
+    conn->callback(net_status, stream, conn->context);\r
+  else if (stream)\r
+    silc_stream_destroy(stream);\r
+\r
+  delete conn;\r
+}\r
+\r
+/* Connecting abort callback */\r
+\r
+static void silc_net_connect_abort(SilcAsyncOperation op, void *context)\r
+{\r
+  SilcSymbianTCPConnect *conn = (SilcSymbianTCPConnect *)context;\r
+\r
+  /* Abort */\r
+  conn->callback = NULL;\r
+  conn->op = NULL;\r
+  conn->DoCancel();\r
+}\r
+\r
+/* Create TCP/IP connection */\r
+\r
+SilcAsyncOperation silc_net_tcp_connect(const char *local_ip_addr,\r
+                                       const char *remote_ip_addr,\r
+                                       int remote_port,\r
+                                       SilcSchedule schedule,\r
+                                       SilcNetCallback callback,\r
+                                       void *context)\r
+{\r
+  SilcSymbianTCPConnect *conn;\r
+  TInetAddr local, remote;\r
+  SilcNetStatus status;\r
+  TBuf<64> tmp;\r
+  TInt ret;\r
+\r
+  if (!remote_ip_addr || remote_port < 1 || !schedule || !callback)\r
+    return NULL;\r
+\r
+  SILC_LOG_DEBUG(("Creating connection to host %s port %d",\r
+                 remote_ip_addr, remote_port));\r
+\r
+  conn = new SilcSymbianTCPConnect;\r
+  if (!conn) {\r
+    callback(SILC_NET_NO_MEMORY, NULL, context);\r
+    return NULL;\r
+  }\r
+  conn->schedule = schedule;\r
+  conn->callback = callback;\r
+  conn->context = context;\r
+  conn->port = remote_port;\r
+  conn->remote = strdup(remote_ip_addr);\r
+  if (!conn->remote) {\r
+    status = SILC_NET_NO_MEMORY;\r
+    goto err;\r
+  }\r
+\r
+  /* Allocate socket */\r
+  conn->sock = new RSocket;\r
+  if (!conn->sock) {\r
+    status = SILC_NET_NO_MEMORY;\r
+    goto err;\r
+  }\r
+\r
+  /* Allocate socket server */\r
+  conn->ss = new RSocketServ;\r
+  if (!conn->ss) {\r
+    status = SILC_NET_NO_MEMORY;\r
+    goto err;\r
+  }\r
+\r
+  /* Connect to socket server */\r
+  ret = conn->ss->Connect();\r
+  if (ret != KErrNone) {\r
+    status = SILC_NET_ERROR;\r
+    goto err;\r
+  }\r
+\r
+  /* Start async operation */\r
+  conn->op = silc_async_alloc(silc_net_connect_abort, NULL, (void *)conn);\r
+  if (!conn->op) {\r
+    status = SILC_NET_NO_MEMORY;\r
+    goto err;\r
+  }\r
+\r
+  /* Do host lookup */\r
+  if (!silc_net_is_ip(remote_ip_addr)) {\r
+    if (!silc_net_gethostbyname(remote_ip_addr, FALSE, conn->remote_ip,\r
+                               sizeof(conn->remote_ip))) {\r
+      SILC_LOG_ERROR(("Network (%s) unreachable: could not resolve the "\r
+                     "host", conn->remote));\r
+      status = SILC_NET_HOST_UNREACHABLE;\r
+      goto err;\r
+    }\r
+  } else {\r
+    strcpy(conn->remote_ip, remote_ip_addr);\r
+  }\r
+\r
+  /* Create the connection socket */\r
+  ret = conn->sock->Open(*conn->ss, KAfInet, KSockStream, KProtocolInetTcp);\r
+  if (ret != KErrNone) {\r
+    SILC_LOG_ERROR(("Cannot create socket"));\r
+    status = SILC_NET_ERROR;\r
+    goto err;\r
+  }\r
+\r
+  /* Set appropriate options */\r
+  conn->sock->SetOpt(KSoTcpNoDelay, KSolInetTcp, 1);\r
+  conn->sock->SetOpt(KSoTcpKeepAlive, KSolInetTcp, 1);\r
+\r
+  /* Bind to the local address if provided */\r
+  if (local_ip_addr) {\r
+    local = TInetAddr(0);\r
+       tmp = (TText *)local_ip_addr;\r
+    ret = local.Input(tmp);\r
+    if (ret == KErrNone)\r
+      ret = conn->sock->Bind(local);\r
+  }\r
+\r
+  /* Connect to the host */\r
+  remote = TInetAddr(remote_port);\r
+  tmp = (TText *)conn->remote_ip;\r
+  ret = remote.Input(tmp);\r
+  if (ret != KErrNone) {\r
+    SILC_LOG_ERROR(("Cannot connect (cannot set address)"));\r
+    status = SILC_NET_ERROR;\r
+    goto err;\r
+  }\r
+  conn->Connect(remote);\r
+\r
+  SILC_LOG_DEBUG(("Connection operation in progress"));\r
+\r
+  return conn->op;\r
+\r
+ err:\r
+  if (conn->ss) {\r
+    conn->ss->Close();\r
+    delete conn->ss;\r
+  }\r
+  if (conn->sock)\r
+    delete conn->sock;\r
+  if (conn->remote)\r
+    silc_free(conn->remote);\r
+  if (conn->op)\r
+    silc_async_free(conn->op);\r
+  callback(status, NULL, context);\r
+  delete conn;\r
+  return NULL;\r
+}\r
+\r
+/****************************** UDP routines ********************************/\r
+\r
+/* Create UDP/IP connection */\r
+\r
+SilcStream silc_net_udp_connect(const char *local_ip_addr, int local_port,\r
+                               const char *remote_ip_addr, int remote_port,\r
+                               SilcSchedule schedule)\r
+{\r
+  SilcSymbianSocket *s;\r
+  SilcStream stream;\r
+  TInetAddr local, remote;\r
+  TRequestStatus status;\r
+  RSocket *sock = NULL;\r
+  RSocketServ *ss = NULL;\r
+  TBuf<64> tmp;\r
+  TInt ret;\r
+\r
+  SILC_LOG_DEBUG(("Creating UDP stream"));\r
+\r
+  if (!schedule)\r
+    goto err;\r
+\r
+  SILC_LOG_DEBUG(("Binding to local address %s",\r
+                 local_ip_addr ? local_ip_addr : "0.0.0.0"));\r
+\r
+  sock = new RSocket;\r
+  if (!sock)\r
+    goto err;\r
+\r
+  ss = new RSocketServ;\r
+  if (!ss)\r
+    goto err;\r
+\r
+  /* Open socket server */\r
+  ret = ss->Connect();\r
+  if (ret != KErrNone)\r
+    goto err;\r
+\r
+  /* Get local bind address */\r
+  if (local_ip_addr) {\r
+    local = TInetAddr(local_port);\r
+       tmp = (TText *)local_ip_addr;\r
+    ret = local.Input(tmp);\r
+    if (ret != KErrNone)\r
+      goto err;\r
+  } else {\r
+    local = TInetAddr(KInetAddrAny, local_port);\r
+  }\r
+\r
+  /* Create the socket */\r
+  ret = sock->Open(*ss, KAfInet, KSockDatagram, KProtocolInetUdp);\r
+  if (ret != KErrNone) {\r
+    SILC_LOG_ERROR(("Cannot create socket"));\r
+    goto err;\r
+  }\r
+\r
+  /* Set the socket options */\r
+  sock->SetOpt(KSoReuseAddr, KSolInetIp, 1);\r
+\r
+  /* Bind the listener socket */\r
+  ret = sock->Bind(local);\r
+  if (ret != KErrNone) {\r
+    SILC_LOG_DEBUG(("Cannot bind socket"));\r
+    goto err;\r
+  }\r
+\r
+  /* Set to connected state if remote address is provided. */\r
+  if (remote_ip_addr && remote_port) {\r
+    remote = TInetAddr(remote_port);\r
+       tmp = (TText *)remote_ip_addr;\r
+    ret = remote.Input(tmp);\r
+    if (ret != KErrNone)\r
+      goto err;\r
+\r
+    sock->Connect(remote, status);\r
+    if (status != KErrNone) {\r
+      SILC_LOG_DEBUG(("Cannot connect UDP stream"));\r
+      goto err;\r
+    }\r
+  }\r
+\r
+  /* Encapsulate into socket stream */\r
+  s = silc_create_symbian_socket(sock, ss);\r
+  if (!s)\r
+    goto err;\r
+  stream =\r
+    silc_socket_udp_stream_create((SilcSocket)s, local_ip_addr ?\r
+                                 silc_net_is_ip6(local_ip_addr) : FALSE,\r
+                                 remote_ip_addr ? TRUE : FALSE, schedule);\r
+  if (!stream)\r
+    goto err;\r
+\r
+  SILC_LOG_DEBUG(("UDP stream created, fd=%d", sock));\r
+  return stream;\r
+\r
+ err:\r
+  if (sock)\r
+    delete sock;\r
+  if (ss) {\r
+    ss->Close();\r
+    delete ss;\r
+  }\r
+  return NULL;\r
+}\r
+\r
+/* Sets socket to non-blocking mode */\r
+\r
+int silc_net_set_socket_nonblock(SilcSocket sock)\r
+{\r
+  /* Nothing to do in Symbian where blocking socket mode is asynchronous\r
+     already (ie. non-blocking). */\r
+  return 0;\r
+}\r
+\r
+/* Converts the IP number string from numbers-and-dots notation to\r
+   binary form. */\r
+\r
+SilcBool silc_net_addr2bin(const char *addr, void *bin, SilcUInt32 bin_len)\r
+{\r
+  int ret = 0;\r
+\r
+  struct in_addr tmp;\r
+  ret = inet_aton(addr, &tmp);\r
+  if (bin_len < 4)\r
+    return FALSE;\r
+\r
+  memcpy(bin, (unsigned char *)&tmp.s_addr, 4);\r
+\r
+  return ret != 0;\r
+}\r
+\r
+/* Get remote host and IP from socket */\r
+\r
+SilcBool silc_net_check_host_by_sock(SilcSocket sock, char **hostname,\r
+                                    char **ip)\r
+{\r
+  SilcSymbianSocket *s = (SilcSymbianSocket *)sock;\r
+  TInetAddr addr;\r
+  char host[256];\r
+  TBuf<64> tmp;\r
+\r
+  if (hostname)\r
+    *hostname = NULL;\r
+  *ip = NULL;\r
+\r
+  s->sock->RemoteName(addr);\r
+  addr.Output(tmp);\r
+\r
+  *ip = (char *)silc_memdup(tmp.Ptr(), tmp.Length());\r
+  if (*ip == NULL)\r
+    return FALSE;\r
+\r
+  /* Do reverse lookup if we want hostname too. */\r
+  if (hostname) {\r
+    /* Get host by address */\r
+    if (!silc_net_gethostbyaddr(*ip, host, sizeof(host)))\r
+      return FALSE;\r
+\r
+    *hostname = (char *)silc_memdup(host, strlen(host));\r
+    SILC_LOG_DEBUG(("Resolved hostname `%s'", *hostname));\r
+\r
+    /* Reverse */\r
+    if (!silc_net_gethostbyname(*hostname, TRUE, host, sizeof(host)))\r
+      return FALSE;\r
+\r
+    if (strcmp(*ip, host))\r
+      return FALSE;\r
+  }\r
+\r
+  SILC_LOG_DEBUG(("Resolved IP address `%s'", *ip));\r
+  return TRUE;\r
+}\r
+\r
+/* Get local host and IP from socket */\r
+\r
+SilcBool silc_net_check_local_by_sock(SilcSocket sock, char **hostname,\r
+                                     char **ip)\r
+{\r
+  SilcSymbianSocket *s = (SilcSymbianSocket *)sock;\r
+  TInetAddr addr;\r
+  char host[256];\r
+  TBuf<64> tmp;\r
+\r
+  if (hostname)\r
+    *hostname = NULL;\r
+  *ip = NULL;\r
+\r
+  s->sock->LocalName(addr);\r
+  addr.Output(tmp);\r
+\r
+  *ip = (char *)silc_memdup(tmp.Ptr(), tmp.Length());\r
+  if (*ip == NULL)\r
+    return FALSE;\r
+\r
+  /* Do reverse lookup if we want hostname too. */\r
+  if (hostname) {\r
+    /* Get host by address */\r
+    if (!silc_net_gethostbyaddr(*ip, host, sizeof(host)))\r
+      return FALSE;\r
+\r
+    *hostname = (char *)silc_memdup(host, strlen(host));\r
+    SILC_LOG_DEBUG(("Resolved hostname `%s'", *hostname));\r
+\r
+    /* Reverse */\r
+    if (!silc_net_gethostbyname(*hostname, TRUE, host, sizeof(host)))\r
+      return FALSE;\r
+\r
+    if (strcmp(*ip, host))\r
+      return FALSE;\r
+  }\r
+\r
+  SILC_LOG_DEBUG(("Resolved IP address `%s'", *ip));\r
+  return TRUE;\r
+}\r
+\r
+/* Get remote port from socket */\r
+\r
+SilcUInt16 silc_net_get_remote_port(SilcSocket sock)\r
+{\r
+  SilcSymbianSocket *s = (SilcSymbianSocket *)sock;\r
+  TInetAddr addr;\r
+\r
+  s->sock->RemoteName(addr);\r
+  return (SilcUInt16)addr.Port();\r
+}\r
+\r
+/* Get local port from socket */\r
+\r
+SilcUInt16 silc_net_get_local_port(SilcSocket sock)\r
+{\r
+  SilcSymbianSocket *s = (SilcSymbianSocket *)sock;\r
+  TInetAddr addr;\r
+\r
+  s->sock->LocalName(addr);\r
+  return (SilcUInt16)addr.Port();\r
+}\r
diff --git a/lib/silcutil/symbian/silcsymbianscheduler.cpp b/lib/silcutil/symbian/silcsymbianscheduler.cpp
new file mode 100644 (file)
index 0000000..bf3ee23
--- /dev/null
@@ -0,0 +1,109 @@
+/*\r
+\r
+  silcsymbianschduler.cpp\r
+\r
+  Author: Pekka Riikonen <priikone@silcnet.org>\r
+\r
+  Copyright (C) 1998 - 2006 Pekka Riikonen\r
+\r
+  This program is free software; you can redistribute it and/or modify\r
+  it under the terms of the GNU General Public License as published by\r
+  the Free Software Foundation; version 2 of the License.\r
+\r
+  This program is distributed in the hope that it will be useful,\r
+  but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+  GNU General Public License for more details.\r
+\r
+*/\r
+\r
+/* On symbian the SILC Scheduler doesn't do anything.  All timeout tasks\r
+   are dispatched by the generic scheduler implementation.  Sockets and\r
+   file descriptors are dispatched automatically in their class\r
+   implementation, so adding FD Tasks on Symbian doesn't do anything.\r
+\r
+   This also means that on Symbian the SILC Scheduler always returns\r
+   immediately.  Because FD tasks use the Symbian scheduler the performance\r
+   is as good as it can be.  For timeout tasks the performance is not an\r
+   issue. */\r
+\r
+#include "silc.h"\r
+\r
+int silc_poll(SilcSchedule schedule, void *context)\r
+{\r
+  /* Return immediately, timeout. */\r
+  return 0;\r
+}\r
+\r
+SilcBool silc_schedule_internal_schedule_fd(SilcSchedule schedule,\r
+                                           void *context,\r
+                                           SilcTaskFd task,\r
+                                           SilcTaskEvent event_mask)\r
+{\r
+  /* Nothing to do */\r
+  return TRUE;\r
+}\r
+\r
+void *silc_schedule_internal_init(SilcSchedule schedule,\r
+                                 void *app_context)\r
+{\r
+  /* Nothing to do */\r
+  return NULL;\r
+}\r
+\r
+\r
+void silc_schedule_internal_uninit(SilcSchedule schedule, void *context)\r
+{\r
+  /* Nothing to do */\r
+}\r
+\r
+void silc_schedule_internal_wakeup(SilcSchedule schedule, void *context)\r
+{\r
+  /* Nothing to do */\r
+}\r
+\r
+void silc_schedule_internal_signal_register(SilcSchedule schedule,\r
+                                           void *context,\r
+                                           SilcUInt32 sig,\r
+                                            SilcTaskCallback callback,\r
+                                            void *callback_context)\r
+{\r
+  /* Nothing to do */\r
+}\r
+\r
+void silc_schedule_internal_signal_unregister(SilcSchedule schedule,\r
+                                             void *context,\r
+                                             SilcUInt32 sig)\r
+{\r
+  /* Nothing to do */\r
+}\r
+\r
+void silc_schedule_internal_signals_call(SilcSchedule schedule, void *context)\r
+{\r
+  /* Nothing to do */\r
+}\r
+\r
+void silc_schedule_internal_signals_block(SilcSchedule schedule, void *context)\r
+{\r
+  /* Nothing to do */\r
+}\r
+\r
+void silc_schedule_internal_signals_unblock(SilcSchedule schedule,\r
+                                           void *context)\r
+{\r
+  /* Nothing to do */\r
+}\r
+\r
+const SilcScheduleOps schedule_ops =\r
+{\r
+  silc_schedule_internal_init,\r
+  silc_schedule_internal_uninit,\r
+  silc_poll,\r
+  silc_schedule_internal_schedule_fd,\r
+  silc_schedule_internal_wakeup,\r
+  silc_schedule_internal_signal_register,\r
+  silc_schedule_internal_signal_unregister,\r
+  silc_schedule_internal_signals_call,\r
+  silc_schedule_internal_signals_block,\r
+  silc_schedule_internal_signals_unblock,\r
+};\r
diff --git a/lib/silcutil/symbian/silcsymbiansocketstream.cpp b/lib/silcutil/symbian/silcsymbiansocketstream.cpp
new file mode 100644 (file)
index 0000000..fe9d57d
--- /dev/null
@@ -0,0 +1,421 @@
+\r
+/*\r
+\r
+  silcsymbiansocketstream.cpp\r
+\r
+  Author: Pekka Riikonen <priikone@silcnet.org>\r
+\r
+  Copyright (C) 2006 Pekka Riikonen\r
+\r
+  This program is free software; you can redistribute it and/or modify\r
+  it under the terms of the GNU General Public License as published by\r
+  the Free Software Foundation; version 2 of the License.\r
+\r
+  This program is distributed in the hope that it will be useful,\r
+  but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+  GNU General Public License for more details.\r
+\r
+*/\r
+\r
+/* In this implementation the sockets are in blocking mode, except that\r
+   on Symbian the blocking mode is actually asynchronous, which semantically\r
+   translates into non-blocking mode.  The non-blocking mode just is not\r
+   explicitly set because it would require us also to explicitly poll for the\r
+   socket, which is done automatically by the Active Scheduler in blocking\r
+   mode. */\r
+\r
+#include "silc.h"\r
+#include "silcsymbiansocketstream.h"\r
+\r
+/***************************** Socket Classes *******************************/\r
+\r
+/* Socket stream sender */\r
+\r
+class SilcSymbianSocketSend : public CActive {\r
+public:\r
+  /* Constructor */\r
+  SilcSymbianSocketSend() : CActive(CActive::EPriorityStandard)\r
+  {\r
+    CActiveScheduler::Add(this);\r
+  }\r
+\r
+  /* Destructor */\r
+  ~SilcSymbianSocketSend()\r
+  {\r
+    Cancel();\r
+  }\r
+\r
+  /* Send data */\r
+  void Send(const TDesC8& buf, TSockXfrLength& ret_len)\r
+  {\r
+    s->sock->Send(buf, 0, iStatus, ret_len);\r
+    SetActive();\r
+  }\r
+\r
+  /* Send data */\r
+  void Send(const TDesC8& buf, TSockXfrLength& ret_len,\r
+           const char *remote_ip, int remote_port)\r
+  {\r
+    TInetAddr remote;\r
+    TBuf<64> tmp;\r
+\r
+    remote = TInetAddr(remote_port);\r
+    tmp = (TText *)remote_ip;\r
+    if (remote.Input(tmp) == KErrNone) {\r
+      s->sock->SendTo(buf, remote, 0, iStatus, ret_len);\r
+      SetActive();\r
+    }\r
+  }\r
+\r
+  /* Sending callback */\r
+  void RunL()\r
+  {\r
+    if (iStatus != KErrNone) {\r
+      if (iStatus == KErrEof)\r
+       s->eof = 1;\r
+      else\r
+       s->error = 1;\r
+      return;\r
+    }\r
+\r
+    /* Call stream callback */\r
+    if (s->stream && s->stream->notifier)\r
+      s->stream->notifier(s->stream, SILC_STREAM_CAN_WRITE,\r
+                         s->stream->notifier_context);\r
+  }\r
+\r
+  /* Cancel */\r
+  void DoCancel()\r
+  {\r
+    s->sock->CancelWrite();\r
+  }\r
+\r
+  SilcSymbianSocket *s;\r
+};\r
+\r
+/* Socket stream receiver */\r
+\r
+class SilcSymbianSocketReceive : public CActive {\r
+public:\r
+  /* Constructor */\r
+  SilcSymbianSocketReceive() : CActive(CActive::EPriorityStandard)\r
+  {\r
+    CActiveScheduler::Add(this);\r
+  }\r
+\r
+  /* Destructor */\r
+  ~SilcSymbianSocketReceive()\r
+  {\r
+    Cancel();\r
+  }\r
+\r
+  /* Read data */\r
+  void Read()\r
+  {\r
+    if (!s->stream || s->stream->connected)\r
+      s->sock->RecvOneOrMore(inbuf, 0, iStatus, inbuf_len);\r
+    else\r
+      s->sock->RecvFrom(inbuf, remote, 0, iStatus);\r
+    SetActive();\r
+  }\r
+\r
+  /* Reading callback */\r
+  void RunL()\r
+  {\r
+    if (iStatus != KErrNone) {\r
+      if (iStatus == KErrEof)\r
+       s->eof = 1;\r
+      else\r
+       s->error = 1;\r
+      return;\r
+    }\r
+\r
+    if (!inbuf_ptr)\r
+      inbuf_ptr = inbuf.Ptr();\r
+    inbuf_len = inbuf.Length();\r
+\r
+    /* Call stream callback */\r
+    if (s->stream && s->stream->notifier)\r
+      s->stream->notifier(s->stream, SILC_STREAM_CAN_READ,\r
+                         s->stream->notifier_context);\r
+\r
+    /* Read more */\r
+    Read();\r
+  }\r
+\r
+  /* Cancel */\r
+  void DoCancel()\r
+  {\r
+    s->sock->CancelRecv();\r
+  }\r
+\r
+  TBuf8<8192> inbuf;\r
+  const unsigned char *inbuf_ptr;\r
+  TSockXfrLength inbuf_len;\r
+  SilcSymbianSocket *s;\r
+  TInetAddr remote;\r
+};\r
+\r
+/* Creates symbian socket stream context */\r
+\r
+SilcSymbianSocket *silc_create_symbian_socket(RSocket *sock,\r
+                                             RSocketServ *ss)\r
+{\r
+  SilcSymbianSocket *stream;\r
+\r
+  stream = (SilcSymbianSocket *)silc_calloc(1, sizeof(*stream));\r
+  if (!stream)\r
+    return NULL;\r
+  stream->sock = sock;\r
+  stream->ss = ss;\r
+\r
+  stream->send = new SilcSymbianSocketSend;\r
+  if (!stream->send) {\r
+    silc_free(stream);\r
+    return NULL;\r
+  }\r
+\r
+  stream->receive = new SilcSymbianSocketReceive;\r
+  if (!stream->receive) {\r
+    delete stream->send;\r
+    silc_free(stream);\r
+    return NULL;\r
+  }\r
+\r
+  return stream;\r
+}\r
+\r
+/***************************** SILC Stream API ******************************/\r
+\r
+/* Stream read operation */\r
+\r
+int silc_socket_stream_read(SilcStream stream, unsigned char *buf,\r
+                           SilcUInt32 buf_len)\r
+{\r
+  SilcSocketStream socket_stream = (SilcSocketStream)stream;\r
+  SilcSymbianSocket *s = (SilcSymbianSocket *)socket_stream->sock;\r
+  SilcSymbianSocketReceive *recv = s->receive;\r
+  int len;\r
+\r
+  if (s->error || !s->stream)\r
+    return -2;\r
+  if (s->eof)\r
+    return 0;\r
+  if (!recv->inbuf_len() || !recv->inbuf_ptr)\r
+    return -1;\r
+\r
+  len = recv->inbuf_len();\r
+  if (buf_len < len)\r
+    len = buf_len;\r
+\r
+  /* Copy the read data */\r
+  memcpy(buf, recv->inbuf_ptr, len);\r
+\r
+  recv->inbuf_ptr = NULL;\r
+  if (len < recv->inbuf_len())\r
+    recv->inbuf_ptr += len;\r
+\r
+  return len;\r
+}\r
+\r
+/* Stream write operation */\r
+\r
+int silc_socket_stream_write(SilcStream stream, const unsigned char *data,\r
+                            SilcUInt32 data_len)\r
+{\r
+  SilcSocketStream socket_stream = (SilcSocketStream)stream;\r
+  SilcSymbianSocket *s = (SilcSymbianSocket *)socket_stream->sock;\r
+  SilcSymbianSocketSend *send = s->send;\r
+  TSockXfrLength ret_len;\r
+  TPtrC8 write_buf(data, data_len);\r
+\r
+  if (s->would_block)\r
+    return -1;\r
+  if (s->error || !s->stream)\r
+    return -2;\r
+  if (s->eof)\r
+    return 0;\r
+\r
+  /* Send data */\r
+  send->Send(write_buf, ret_len);\r
+  if (send->iStatus.Int() != KErrNone) {\r
+    if (send->iStatus.Int() == KErrEof)\r
+      return 0;\r
+    return -2;\r
+  }\r
+\r
+  if (!ret_len())\r
+    return -1;\r
+\r
+  s->would_block = 0;\r
+  if (ret_len() < data_len)\r
+    s->would_block = 1;\r
+\r
+  return ret_len();\r
+}\r
+\r
+/* Receive UDP packet, connected socket. */\r
+\r
+int silc_socket_udp_stream_read(SilcStream stream, unsigned char *buf,\r
+                               SilcUInt32 buf_len)\r
+{\r
+  return silc_net_udp_receive(stream, NULL, 0, NULL, buf, buf_len);\r
+}\r
+\r
+/* Send UDP packet, connected socket. */\r
+\r
+int silc_socket_udp_stream_write(SilcStream stream, const unsigned char *data,\r
+                                SilcUInt32 data_len)\r
+{\r
+  SilcSocketStream sock = (SilcSocketStream)stream;\r
+\r
+  /* In connectionless state check if remote IP and port is provided */\r
+  if (!sock->connected && sock->ip && sock->port)\r
+    return silc_net_udp_send(stream, sock->ip, sock->port, data, data_len);\r
+\r
+  /* In connected state use normal writing to socket. */\r
+  return silc_socket_stream_write(stream, data, data_len);\r
+}\r
+\r
+/* Receive UDP packet, connectionless socket */\r
+\r
+int silc_net_udp_receive(SilcStream stream, char *remote_ip_addr,\r
+                        SilcUInt32 remote_ip_addr_size, int *remote_port,\r
+                        unsigned char *buf, SilcUInt32 buf_len)\r
+{\r
+  SilcSocketStream socket_stream = (SilcSocketStream)stream;\r
+  SilcSymbianSocket *s = (SilcSymbianSocket *)socket_stream->sock;\r
+  SilcSymbianSocketReceive *recv = s->receive;\r
+  int len;\r
+\r
+  if (s->eof)\r
+    return 0;\r
+  if (!recv->inbuf_len() || !recv->inbuf_ptr)\r
+    return -1;\r
+\r
+  len = recv->inbuf_len();\r
+  if (buf_len < len)\r
+    len = buf_len;\r
+\r
+  /* Copy the read data */\r
+  memcpy(buf, recv->inbuf_ptr, len);\r
+\r
+  recv->inbuf_ptr = NULL;\r
+  if (len < recv->inbuf_len())\r
+    recv->inbuf_ptr += len;\r
+\r
+  if (remote_ip_addr && remote_ip_addr_size && remote_port) {\r
+    TBuf<64> ip;\r
+    recv->remote.Output(ip);\r
+    silc_strncat(remote_ip_addr, remote_ip_addr_size, (const char *)ip.Ptr(),\r
+                ip.Length());\r
+    *remote_port = recv->remote.Port();\r
+  }\r
+\r
+  return len;\r
+}\r
+\r
+/* Send UDP packet, connectionless socket  */\r
+\r
+int silc_net_udp_send(SilcStream stream,\r
+                     const char *remote_ip_addr, int remote_port,\r
+                     const unsigned char *data, SilcUInt32 data_len)\r
+{\r
+  SilcSocketStream socket_stream = (SilcSocketStream)stream;\r
+  SilcSymbianSocket *s = (SilcSymbianSocket *)socket_stream->sock;\r
+  SilcSymbianSocketSend *send = s->send;\r
+  TSockXfrLength ret_len;\r
+  TPtrC8 write_buf(data, data_len);\r
+\r
+  if (s->would_block)\r
+    return -1;\r
+  if (s->eof)\r
+    return 0;\r
+\r
+  /* Send data */\r
+  send->Send(write_buf, ret_len, remote_ip_addr, remote_port);\r
+  if (send->iStatus.Int() != KErrNone) {\r
+    if (send->iStatus.Int() == KErrEof)\r
+      return 0;\r
+    return -2;\r
+  }\r
+\r
+  if (!ret_len())\r
+    return -1;\r
+\r
+  s->would_block = 0;\r
+  if (ret_len() < data_len)\r
+    s->would_block = 1;\r
+\r
+  return ret_len();\r
+}\r
+\r
+/* Closes socket */\r
+\r
+SilcBool silc_socket_stream_close(SilcStream stream)\r
+{\r
+  SilcSocketStream socket_stream = (SilcSocketStream)stream;\r
+  SilcSymbianSocket *s;\r
+\r
+  if (!SILC_IS_SOCKET_STREAM(socket_stream) &&\r
+      !SILC_IS_SOCKET_STREAM_UDP(socket_stream))\r
+    return FALSE;\r
+\r
+  s = (SilcSymbianSocket *)socket_stream->sock;\r
+  s->sock->Close();\r
+\r
+  return TRUE;\r
+}\r
+\r
+/* Destroys the stream */\r
+\r
+void silc_socket_stream_destroy(SilcStream stream)\r
+{\r
+  SilcSocketStream socket_stream = (SilcSocketStream)stream;\r
+  SilcSymbianSocket *s;\r
+\r
+  if (!SILC_IS_SOCKET_STREAM(socket_stream) &&\r
+      !SILC_IS_SOCKET_STREAM_UDP(socket_stream))\r
+    return;\r
+\r
+  s = (SilcSymbianSocket *)socket_stream->sock;\r
+\r
+  silc_socket_stream_close(stream);\r
+  silc_free(socket_stream->ip);\r
+  silc_free(socket_stream->hostname);\r
+  silc_free(socket_stream);\r
+  delete s->send;\r
+  delete s->receive;\r
+  delete s->sock;\r
+  if (s->ss) {\r
+    s->ss->Close();\r
+    delete s->ss;\r
+  }\r
+  delete s;\r
+}\r
+\r
+/* Sets stream notification callback for the stream */\r
+\r
+void silc_socket_stream_notifier(SilcStream stream,\r
+                                SilcSchedule schedule,\r
+                                SilcStreamNotifier callback,\r
+                                void *context)\r
+{\r
+  SilcSocketStream socket_stream = (SilcSocketStream)stream;\r
+  SilcSymbianSocket *s;\r
+\r
+  if (!SILC_IS_SOCKET_STREAM(socket_stream) &&\r
+      !SILC_IS_SOCKET_STREAM_UDP(socket_stream))\r
+    return;\r
+\r
+  s = (SilcSymbianSocket *)socket_stream->sock;\r
+  if (callback)\r
+    s->stream = socket_stream;\r
+  else\r
+    s->stream = NULL;\r
+\r
+  socket_stream->notifier = callback;\r
+  socket_stream->notifier_context = context;\r
+  socket_stream->schedule = schedule;\r
+}\r
diff --git a/lib/silcutil/symbian/silcsymbiansocketstream.h b/lib/silcutil/symbian/silcsymbiansocketstream.h
new file mode 100644 (file)
index 0000000..c0ff2a4
--- /dev/null
@@ -0,0 +1,46 @@
+/*\r
+\r
+  silcsymbiansocketstream.h\r
+\r
+  Author: Pekka Riikonen <priikone@silcnet.org>\r
+\r
+  Copyright (C) 2006 Pekka Riikonen\r
+\r
+  This program is free software; you can redistribute it and/or modify\r
+  it under the terms of the GNU General Public License as published by\r
+  the Free Software Foundation; version 2 of the License.\r
+\r
+  This program is distributed in the hope that it will be useful,\r
+  but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+  GNU General Public License for more details.\r
+\r
+*/\r
+\r
+#ifndef SILCSYMBIANSOCKETSTREAM_H\r
+#define SILCSYMBIANSOCKETSTREAM_H\r
+\r
+#include <e32std.h>\r
+#include <es_sock.h>\r
+#include <in_sock.h>\r
+\r
+class SilcSymbianSocketSend;\r
+class SilcSymbianSocketReceive;\r
+\r
+/* Symbian Socket context */\r
+typedef struct {\r
+  SilcSymbianSocketSend *send;\r
+  SilcSymbianSocketReceive *receive;\r
+  RSocket *sock;\r
+  RSocketServ *ss;\r
+  SilcSocketStream stream;\r
+  unsigned int eof          : 1;\r
+  unsigned int error        : 1;\r
+  unsigned int would_block  : 1;\r
+} SilcSymbianSocket;\r
+\r
+/* Creates symbian socket context.  This will steal the `sock' and `ss'. */\r
+SilcSymbianSocket *silc_create_symbian_socket(RSocket *sock,\r
+                                             RSocketServ *ss);\r
+\r
+#endif /* SILCSYMBIANSOCKETSTREAM_H */\r
diff --git a/lib/silcutil/symbian/silcsymbianthread.cpp b/lib/silcutil/symbian/silcsymbianthread.cpp
new file mode 100644 (file)
index 0000000..5d637b4
--- /dev/null
@@ -0,0 +1,270 @@
+/*\r
+\r
+  silcsymbianthread.cpp\r
+\r
+  Author: Pekka Riikonen <priikone@silcnet.org>\r
+\r
+  Copyright (C) 2006 Pekka Riikonen\r
+\r
+  This program is free software; you can redistribute it and/or modify\r
+  it under the terms of the GNU General Public License as published by\r
+  the Free Software Foundation; version 2 of the License.\r
+\r
+  This program is distributed in the hope that it will be useful,\r
+  but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+  GNU General Public License for more details.\r
+\r
+*/\r
+\r
+#include "silc.h"\r
+#include <e32std.h>\r
+\r
+/**************************** SILC Thread API *******************************/\r
+\r
+/* Thread structure for Symbian */\r
+typedef struct {\r
+#ifdef SILC_THREADS\r
+  RThread *thread;\r
+  SilcThreadStart start_func;\r
+  void *context;\r
+  bool waitable;\r
+#else\r
+  void *tmp;\r
+#endif\r
+} *SilcSymbianThread;\r
+\r
+/* The actual thread function */\r
+\r
+TInt silc_thread_epoc_start(TAny *context)\r
+{\r
+#ifdef SILC_THREADS\r
+  SilcSymbianThread thread = (SilcSymbianThread)context;\r
+  void *ret;\r
+\r
+  ret = thread->start_func(thread->context);\r
+  silc_thread_exit(ret);\r
+\r
+#endif\r
+  return 0;\r
+}\r
+\r
+SilcThread silc_thread_create(SilcThreadStart start_func, void *context,\r
+                             bool waitable)\r
+{\r
+#ifdef SILC_THREADS\r
+  SilcSymbianThread thread;\r
+  TInt ret;\r
+  TBuf<32> name;\r
+\r
+  SILC_LOG_DEBUG(("Creating new thread"));\r
+\r
+  thread = (SilcSymbianThread)silc_calloc(1, sizeof(*thread));\r
+  if (!thread)\r
+    return NULL;\r
+  thread->start_func = start_func;\r
+  thread->context = context;\r
+  thread->waitable = waitable;\r
+\r
+  /* Create the thread */\r
+  /* XXX Unique name should be given for the thread */\r
+  thread->thread = new RThread();\r
+  if (!thread->thread) {\r
+    silc_free(thread);\r
+    return NULL;\r
+  }\r
+\r
+  name = (TText *)"silc" + time(NULL);\r
+  ret = thread->thread->Create(name, silc_thread_epoc_start,\r
+                              8192, 4096, 1024 * 1024, (TAny *)thread);\r
+  if (ret != KErrNone) {\r
+    SILC_LOG_ERROR(("Could not create new thread"));\r
+    delete thread->thread;\r
+    silc_free(thread);\r
+    return NULL;\r
+  }\r
+  thread->thread->Resume();\r
+\r
+  return (SilcThread)thread;\r
+#else\r
+  /* Call thread callback immediately */\r
+  (*start_func)(context);\r
+  return NULL;\r
+#endif\r
+}\r
+\r
+void silc_thread_exit(void *exit_value)\r
+{\r
+#ifdef SILC_THREADS\r
+  /* XXX */\r
+#endif\r
+}\r
+\r
+SilcThread silc_thread_self(void)\r
+{\r
+#ifdef SILC_THREADS\r
+  /* XXX */\r
+  return NULL;\r
+#else\r
+  return NULL;\r
+#endif\r
+}\r
+\r
+SilcBool silc_thread_wait(SilcThread thread, void **exit_value)\r
+{\r
+#ifdef SILC_THREADS\r
+  /* XXX */\r
+  return TRUE;\r
+#else\r
+  return FALSE;\r
+#endif\r
+}\r
+\r
+/***************************** SILC Mutex API *******************************/\r
+\r
+/* SILC Mutex structure */\r
+struct SilcMutexStruct {\r
+#ifdef SILC_THREADS\r
+  RMutex *mutex;\r
+#endif /* SILC_THREADS */\r
+  unsigned int locked : 1;\r
+};\r
+\r
+SilcBool silc_mutex_alloc(SilcMutex *mutex)\r
+{\r
+#ifdef SILC_THREADS\r
+  *mutex = (SilcMutex)silc_calloc(1, sizeof(**mutex));\r
+  if (*mutex == NULL)\r
+    return FALSE;\r
+  (*mutex)->mutex = new RMutex();\r
+  if (!(*mutex)->mutex) {\r
+    silc_free(*mutex);\r
+    return FALSE;\r
+  }\r
+  if ((*mutex)->mutex->CreateLocal() != KErrNone) {\r
+    delete (*mutex)->mutex;\r
+    silc_free(*mutex);\r
+    return FALSE;\r
+  }\r
+  (*mutex)->locked = FALSE;\r
+  return TRUE;\r
+#else\r
+  return FALSE;\r
+#endif /* SILC_THREADS */\r
+}\r
+\r
+void silc_mutex_free(SilcMutex mutex)\r
+{\r
+#ifdef SILC_THREADS\r
+  if (mutex) {\r
+    mutex->mutex->Close();\r
+    delete mutex->mutex;\r
+    silc_free(mutex);\r
+  }\r
+#endif /* SILC_THREADS */\r
+}\r
+\r
+void silc_mutex_lock(SilcMutex mutex)\r
+{\r
+#ifdef SILC_THREADS\r
+  if (mutex) {\r
+    mutex->mutex->Wait();\r
+    mutex->locked = TRUE;\r
+  }\r
+#endif /* SILC_THREADS */\r
+}\r
+\r
+void silc_mutex_unlock(SilcMutex mutex)\r
+{\r
+#ifdef SILC_THREADS\r
+  if (mutex) {\r
+    mutex->mutex->Signal();\r
+    mutex->locked = FALSE;\r
+  }\r
+#endif /* SILC_THREADS */\r
+}\r
+\r
+void silc_mutex_assert_locked(SilcMutex mutex)\r
+{\r
+#ifdef SILC_THREADS\r
+  if (mutex)\r
+    SILC_ASSERT(mutex->locked);\r
+#endif /* SILC_THREADS */\r
+}\r
+\r
+\r
+/****************************** SILC Cond API *******************************/\r
+\r
+/* SILC Conditional Variable context */\r
+struct SilcCondStruct {\r
+#ifdef SILC_THREADS\r
+  RCondVar *cond;\r
+#else\r
+  void *tmp;\r
+#endif /* SILC_THREADS*/\r
+};\r
+\r
+SilcBool silc_cond_alloc(SilcCond *cond)\r
+{\r
+#ifdef SILC_THREADS\r
+  *cond = (SilcCond)silc_calloc(1, sizeof(**cond));\r
+  if (*cond == NULL)\r
+    return FALSE;\r
+  (*cond)->cond = new RCondVar();\r
+  if (!(*cond)->cond) {\r
+    silc_free(*cond);\r
+    return FALSE;\r
+  }\r
+  if ((*cond)->cond->CreateLocal() != KErrNone) {\r
+    delete (*cond)->cond;\r
+    silc_free(*cond);\r
+    return FALSE;\r
+  }\r
+  return TRUE;\r
+#else\r
+  return FALSE;\r
+#endif /* SILC_THREADS*/\r
+}\r
+\r
+void silc_cond_free(SilcCond cond)\r
+{\r
+#ifdef SILC_THREADS\r
+  cond->cond->Close();\r
+  delete cond->cond;\r
+  silc_free(cond);\r
+#endif /* SILC_THREADS*/\r
+}\r
+\r
+void silc_cond_signal(SilcCond cond)\r
+{\r
+#ifdef SILC_THREADS\r
+  cond->cond->Signal();\r
+#endif /* SILC_THREADS*/\r
+}\r
+\r
+void silc_cond_broadcast(SilcCond cond)\r
+{\r
+#ifdef SILC_THREADS\r
+  cond->cond->Broadcast();\r
+#endif /* SILC_THREADS*/\r
+}\r
+\r
+void silc_cond_wait(SilcCond cond, SilcMutex mutex)\r
+{\r
+#ifdef SILC_THREADS\r
+  cond->cond->Wait(*mutex->mutex);\r
+#endif /* SILC_THREADS*/\r
+}\r
+\r
+SilcBool silc_cond_timedwait(SilcCond cond, SilcMutex mutex,\r
+                            int timeout)\r
+{\r
+#ifdef SILC_THREADS\r
+  if (timeout)\r
+    return (cond->cond->TimedWait(*mutex->mutex, (TInt)timeout * 1000) ==\r
+           KErrNone);\r
+  return (cond->cond->Wait(*mutex->mutex) == KErrNone);\r
+#else\r
+  return FALSE;\r
+#endif /* SILC_THREADS*/\r
+}\r
diff --git a/lib/silcutil/symbian/silcsymbianutil.cpp b/lib/silcutil/symbian/silcsymbianutil.cpp
new file mode 100644 (file)
index 0000000..93ae79a
--- /dev/null
@@ -0,0 +1,74 @@
+/*\r
+\r
+  silcsymbianutil.cpp\r
+\r
+  Author: Pekka Riikonen <priikone@silcnet.org>\r
+\r
+  Copyright (C) 2006 Pekka Riikonen\r
+\r
+  This program is free software; you can redistribute it and/or modify\r
+  it under the terms of the GNU General Public License as published by\r
+  the Free Software Foundation; version 2 of the License.\r
+\r
+  This program is distributed in the hope that it will be useful,\r
+  but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+  GNU General Public License for more details.\r
+\r
+*/\r
+\r
+#include "silc.h"\r
+\r
+/* Returns the username of the user. */\r
+\r
+char *silc_get_username()\r
+{\r
+  char *logname = NULL;\r
+\r
+  logname = getlogin();\r
+  if (!logname) {\r
+    struct passwd *pw;\r
+\r
+    pw = getpwuid(getuid());\r
+    if (!pw)\r
+      return strdup("User");\r
+\r
+    logname = pw->pw_name;\r
+  }\r
+\r
+  return strdup(logname);\r
+}\r
+\r
+/* Returns the real name of ther user. */\r
+\r
+char *silc_get_real_name()\r
+{\r
+  char *realname = NULL;\r
+  struct passwd *pw;\r
+\r
+  pw = getpwuid(getuid());\r
+  if (!pw)\r
+    return strdup("No Name");\r
+\r
+  if (strchr(pw->pw_gecos, ','))\r
+    *strchr(pw->pw_gecos, ',') = 0;\r
+\r
+  if (!strlen(pw->pw_gecos))\r
+    return strdup("No Name");\r
+\r
+  realname = strdup(pw->pw_gecos);\r
+\r
+  return realname;\r
+}\r
+\r
+/* Return current time to struct timeval. */\r
+\r
+int silc_gettimeofday(struct timeval *p)\r
+{\r
+  return gettimeofday(p, NULL);\r
+}\r
+\r
+int silc_file_set_nonblock(int fd)\r
+{\r
+  return 0;\r
+}\r
index 21b3fca3364c2da61ea6b337d02c9de1b8e57045..622fc4536647868c726adb791e0799f938224734 100644 (file)
@@ -49,7 +49,7 @@ SilcBool add_entries()
     e = silc_calloc(1, sizeof(*e));
     if (!e)
       return FALSE;
-    snprintf(e->name, sizeof(e->name), "%d", i);
+    silc_snprintf(e->name, sizeof(e->name), "%d", i);
     e->val = i;
 
     silc_hash_table_add(t, (void *)e, (void *)e->name);
@@ -99,7 +99,7 @@ SilcBool del_n_entries_foreach()
 
   for (i = 0; i < count; i++) {
     memset(&f, 0, sizeof(f));
-    snprintf(f.name, sizeof(f.name), "%d", i);
+    silc_snprintf(f.name, sizeof(f.name), "%d", i);
     f.val = i;
 
     silc_hash_table_find_foreach(t, &f, del_foreach, NULL);
@@ -169,7 +169,7 @@ SilcBool find_entries()
 
   for (i = 0; i < count; i++) {
     memset(&f, 0, sizeof(f));
-    snprintf(f.name, sizeof(f.name), "%d", i);
+    silc_snprintf(f.name, sizeof(f.name), "%d", i);
     f.val = i;
 
     /* Find */
index bc138cd943bd27a42060c6b8d71638c476f0d71f..1ce203811c0c249b5a8baa33915391abac663d8a 100644 (file)
@@ -196,7 +196,7 @@ silc_net_tcp_create_listener(const char **local_ip_addr,
     }
 
     /* Specify that we are listenning */
-    rval = listen(sock, 5);
+    rval = listen(sock, 64);
     if (rval < 0) {
       SILC_LOG_ERROR(("Cannot set socket listenning: %s", strerror(errno)));
       goto err;
@@ -453,7 +453,7 @@ typedef struct {
   SilcSocketStreamStatus stream_status;
   SilcStream stream;
   SilcFSMStruct fsm;
-  SilcFSMEventStruct sema;
+  SilcFSMEventStruct event;
   SilcAsyncOperation op;
   SilcAsyncOperation sop;
   char *local_ip;
@@ -475,7 +475,7 @@ SILC_FSM_STATE(silc_net_connect_st_finish);
 SILC_TASK_CALLBACK(silc_net_connect_wait)
 {
   SilcNetConnect conn = context;
-  SILC_FSM_EVENT_SIGNAL(&conn->sema);
+  SILC_FSM_EVENT_SIGNAL(&conn->event);
   silc_schedule_task_del_by_fd(schedule, conn->sock);
 }
 
@@ -575,12 +575,12 @@ SILC_FSM_STATE(silc_net_connect_st_start)
 
   /** Wait for connection */
   silc_fsm_next(fsm, silc_net_connect_st_connected);
-  silc_fsm_event_init(&conn->sema, fsm);
+  silc_fsm_event_init(&conn->event, fsm);
   silc_schedule_task_add_fd(silc_fsm_get_schedule(fsm), sock,
                            silc_net_connect_wait, conn);
   silc_schedule_set_listen_fd(silc_fsm_get_schedule(fsm), sock,
                              SILC_TASK_WRITE, FALSE);
-  SILC_FSM_EVENT_WAIT(&conn->sema);
+  SILC_FSM_EVENT_WAIT(&conn->event);
   SILC_FSM_CONTINUE;
 }
 
@@ -743,6 +743,7 @@ SilcAsyncOperation silc_net_tcp_connect(const char *local_ip_addr,
   /* Start async operation */
   conn->op = silc_async_alloc(silc_net_connect_abort, NULL, conn);
   if (!conn->op) {
+    silc_free(conn);
     callback(SILC_NET_NO_MEMORY, NULL, context);
     return NULL;
   }
@@ -751,6 +752,9 @@ SilcAsyncOperation silc_net_tcp_connect(const char *local_ip_addr,
     conn->local_ip = strdup(local_ip_addr);
   conn->remote = 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);
     return NULL;
   }
@@ -775,9 +779,9 @@ void silc_net_close_connection(int sock)
 
 /* Set's the socket to non-blocking mode. */
 
-int silc_net_set_socket_nonblock(int sock)
+int silc_net_set_socket_nonblock(SilcSocket sock)
 {
-  return fcntl(sock, F_SETFL, fcntl(sock, F_GETFL, 0) | O_NONBLOCK);
+  return fcntl((int)sock, F_SETFL, fcntl(sock, F_GETFL, 0) | O_NONBLOCK);
 }
 
 /* Converts the IP number string from numbers-and-dots notation to
index e171369b693a52fa3b00b5631eb7e63c27d4ff98..1b9d66295036a22721ed963d1e44d262aed27bd4 100644 (file)
 
 #include "silc.h"
 
+/************************ Static utility functions **************************/
+
+/* The IO process callback that calls the notifier callback to upper layer. */
+
+SILC_TASK_CALLBACK(silc_socket_stream_io)
+{
+  SilcSocketStream stream = context;
+
+  if (silc_unlikely(!stream->notifier))
+    return;
+
+  switch (type) {
+  case SILC_TASK_READ:
+    stream->notifier(stream, SILC_STREAM_CAN_READ, stream->notifier_context);
+    break;
+
+  case SILC_TASK_WRITE:
+    stream->notifier(stream, SILC_STREAM_CAN_WRITE, stream->notifier_context);
+    break;
+
+  default:
+    break;
+  }
+}
+
+/**************************** Stream Operations *****************************/
+
 /* QoS read handler, this will call the read and write events to indicate
    that data is available again after a timeout. */
 
@@ -219,3 +246,90 @@ SilcBool silc_socket_get_error(SilcStream sock, char *error,
   return TRUE;
 }
 #endif /* 0 */
+
+/* Closes socket */
+
+SilcBool silc_socket_stream_close(SilcStream stream)
+{
+  SilcSocketStream socket_stream = stream;
+
+  if (!SILC_IS_SOCKET_STREAM(socket_stream) &&
+      !SILC_IS_SOCKET_STREAM_UDP(socket_stream))
+    return FALSE;
+
+  silc_schedule_unset_listen_fd(socket_stream->schedule, socket_stream->sock);
+  silc_net_close_connection(socket_stream->sock);
+
+  return TRUE;
+}
+
+/* Destroys the stream */
+
+void silc_socket_stream_destroy(SilcStream stream)
+{
+  SilcSocketStream socket_stream = stream;
+
+  if (!SILC_IS_SOCKET_STREAM(socket_stream) &&
+      !SILC_IS_SOCKET_STREAM_UDP(socket_stream))
+    return;
+
+  silc_socket_stream_close(socket_stream);
+  silc_free(socket_stream->ip);
+  silc_free(socket_stream->hostname);
+  if (socket_stream->schedule)
+    silc_schedule_task_del_by_fd(socket_stream->schedule, socket_stream->sock);
+
+  if (socket_stream->qos) {
+    silc_schedule_task_del_by_context(socket_stream->schedule,
+                                     socket_stream->qos);
+    if (socket_stream->qos->buffer) {
+      memset(socket_stream->qos->buffer, 0,
+            socket_stream->qos->read_limit_bytes);
+      silc_free(socket_stream->qos->buffer);
+    }
+    silc_free(socket_stream->qos);
+  }
+
+  if (socket_stream->schedule)
+    silc_schedule_wakeup(socket_stream->schedule);
+
+  silc_free(socket_stream);
+}
+
+/* Sets stream notification callback for the stream */
+
+void silc_socket_stream_notifier(SilcStream stream,
+                                SilcSchedule schedule,
+                                SilcStreamNotifier callback,
+                                void *context)
+{
+  SilcSocketStream socket_stream = stream;
+
+  if (!SILC_IS_SOCKET_STREAM(socket_stream) &&
+      !SILC_IS_SOCKET_STREAM_UDP(socket_stream))
+    return;
+
+  SILC_LOG_DEBUG(("Setting stream notifier callback"));
+
+  socket_stream->notifier = callback;
+  socket_stream->notifier_context = context;
+  socket_stream->schedule = schedule;
+
+  if (socket_stream->notifier) {
+    /* Add the socket to scheduler.  Safe to call if already added. */
+    silc_schedule_task_add_fd(socket_stream->schedule, socket_stream->sock,
+                             silc_socket_stream_io, socket_stream);
+
+    /* Initially set socket for reading */
+    silc_schedule_set_listen_fd(socket_stream->schedule, socket_stream->sock,
+                               SILC_TASK_READ, FALSE);
+    silc_schedule_wakeup(socket_stream->schedule);
+  } else {
+    /* Unschedule the socket */
+    silc_schedule_unset_listen_fd(socket_stream->schedule,
+                                 socket_stream->sock);
+    silc_schedule_task_del_by_fd(socket_stream->schedule,
+                                socket_stream->sock);
+    silc_schedule_wakeup(socket_stream->schedule);
+  }
+}
index 3985a6174fe26f5fd37397d45705a2f7a52b35c5..7f52de901daca7baafd9d1c1bca4aaf949e52ad3 100644 (file)
@@ -163,7 +163,7 @@ void silc_mutex_assert_locked(SilcMutex mutex)
 }
 
 
-/**************************** SILC Cond API ******************************/
+/****************************** SILC Cond API *******************************/
 
 /* SILC Conditional Variable context */
 struct SilcCondStruct {
diff --git a/symbian/silcdefs.h b/symbian/silcdefs.h
new file mode 100644 (file)
index 0000000..30d40b0
--- /dev/null
@@ -0,0 +1,289 @@
+/* silcdefs.h.  Generated from silcdefs.h.in by configure.  */
+/* silcdefs.h.in.  Generated from configure.ac by autoheader.  */
+
+/* Define to 1 if you have the <arpa/inet.h> header file. */
+#define HAVE_ARPA_INET_H 1
+
+/* Define to 1 if you have the <assert.h> header file. */
+#define HAVE_ASSERT_H 1
+
+/* Define to 1 if you have the `bind' function. */
+#define HAVE_BIND 1
+
+/* Define to 1 if you have the `chmod' function. */
+#define HAVE_CHMOD 1
+
+/* Define to 1 if you have the `close' function. */
+#define HAVE_CLOSE 1
+
+/* Define to 1 if you have the `connect' function. */
+#define HAVE_CONNECT 1
+
+/* Define to 1 if you have the `ctime' function. */
+#define HAVE_CTIME 1
+
+/* Define to 1 if you have the <ctype.h> header file. */
+#define HAVE_CTYPE_H 1
+
+/* Define to 1 if you have the <errno.h> header file. */
+#define HAVE_ERRNO_H 1
+
+/* Define to 1 if you have the `fcntl' function. */
+#define HAVE_FCNTL 1
+
+/* Define to 1 if you have the <fcntl.h> header file. */
+#define HAVE_FCNTL_H 1
+
+/* Define to 1 if you have the `fstat' function. */
+#define HAVE_FSTAT 1
+
+/* Define to 1 if you have the `getenv' function. */
+#define HAVE_GETENV 1
+
+/* Define to 1 if you have the `getgid' function. */
+#define HAVE_GETGID 1
+
+/* Define to 1 if you have the `gethostbyaddr' function. */
+#define HAVE_GETHOSTBYADDR 1
+
+/* Define to 1 if you have the `gethostname' function. */
+#define HAVE_GETHOSTNAME 1
+
+/* Define to 1 if you have the `getpgid' function. */
+#define HAVE_GETPGID 1
+
+/* Define to 1 if you have the `getpgrp' function. */
+#define HAVE_GETPGRP 1
+
+/* Define to 1 if you have the `getpid' function. */
+#define HAVE_GETPID 1
+
+/* Define to 1 if you have the `getservbyname' function. */
+#define HAVE_GETSERVBYNAME 1
+
+/* Define to 1 if you have the `getservbyport' function. */
+#define HAVE_GETSERVBYPORT 1
+
+/* Define to 1 if you have the `getsid' function. */
+#define HAVE_GETSID 1
+
+/* Define to 1 if you have the `gettimeofday' function. */
+#define HAVE_GETTIMEOFDAY 1
+
+/* Define to 1 if you have the `getuid' function. */
+#define HAVE_GETUID 1
+
+/* Define to 1 if you have the `initgroups' function. */
+#define HAVE_INITGROUPS 1
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#define HAVE_INTTYPES_H 1
+
+/* Define to 1 if you have the <limits.h> header file. */
+#define HAVE_LIMITS_H 1
+
+/* Define to 1 if you have the `listen' function. */
+#define HAVE_LISTEN 1
+
+/* Define to 1 if you have the <locale.h> header file. */
+#define HAVE_LOCALE_H 1
+
+/* Define to 1 if you have the `memcpy' function. */
+#define HAVE_MEMCPY 1
+
+/* Define to 1 if you have the `memmove' function. */
+#define HAVE_MEMMOVE 1
+
+/* Define to 1 if you have the `memset' function. */
+#define HAVE_MEMSET 1
+
+/* Define to 1 if you have the <netdb.h> header file. */
+#define HAVE_NETDB_H 1
+
+/* Define to 1 if you have the <netinet/in.h> header file. */
+#define HAVE_NETINET_IN_H 1
+
+/* Define to 1 if you have the `nl_langinfo' function. */
+#define HAVE_NL_LANGINFO 1
+
+/* Define to 1 if you have the <paths.h> header file. */
+#define HAVE_PATHS_H 1
+
+/* Define to 1 if you have the `poll' function. */
+#define HAVE_POLL 1
+
+/* Define to 1 if you have the `putenv' function. */
+#define HAVE_PUTENV 1
+
+/* Define to 1 if you have the <pwd.h> header file. */
+#define HAVE_PWD_H 1
+
+/* Define to 1 if you have the `select' function. */
+#define HAVE_SELECT 1
+
+/* Define to 1 if you have the `setgroups' function. */
+#define HAVE_SETGROUPS 1
+
+/* Define to 1 if you have the `setrlimit' function. */
+#define HAVE_SETRLIMIT 1
+
+/* Define to 1 if you have the `setsockopt' function. */
+#define HAVE_SETSOCKOPT 1
+
+/* Define to 1 if you have the <signal.h> header file. */
+#define HAVE_SIGNAL_H 1
+
+/* Define to 1 if you have the `stat' function. */
+#define HAVE_STAT 1
+
+/* Define to 1 if you have the <stddef.h> header file. */
+#define HAVE_STDDEF_H 1
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#define HAVE_STDINT_H 1
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#define HAVE_STDLIB_H 1
+
+/* Define to 1 if you have the `strchr' function. */
+#define HAVE_STRCHR 1
+
+/* Define to 1 if you have the `strcpy' function. */
+#define HAVE_STRCPY 1
+
+/* Define to 1 if you have the `strerror' function. */
+#define HAVE_STRERROR 1
+
+/* Define to 1 if you have the <strings.h> header file. */
+#define HAVE_STRINGS_H 1
+
+/* Define to 1 if you have the <string.h> header file. */
+#define HAVE_STRING_H 1
+
+/* Define to 1 if you have the `strncpy' function. */
+#define HAVE_STRNCPY 1
+
+/* Define to 1 if you have the `strstr' function. */
+#define HAVE_STRSTR 1
+
+/* Define to 1 if you have the <sys/resource.h> header file. */
+#define HAVE_SYS_RESOURCE_H 1
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#define HAVE_SYS_STAT_H 1
+
+/* Define to 1 if you have the <sys/time.h> header file. */
+#define HAVE_SYS_TIME_H 1
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#define HAVE_SYS_TYPES_H 1
+
+/* Define to 1 if you have the `time' function. */
+#define HAVE_TIME 1
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#define HAVE_UNISTD_H 1
+
+/* HAVE_VA_COPY */
+//#define HAVE_VA_COPY
+#define HAVE_VA_COPY_AARRAY
+
+/* Name of package */
+#define PACKAGE "silc-toolkit"
+
+/* Define to the address where bug reports for this package should be sent. */
+#define PACKAGE_BUGREPORT ""
+
+/* Define to the full name of this package. */
+#define PACKAGE_NAME "Toolkit"
+
+/* Define to the full name and version of this package. */
+#define PACKAGE_STRING "Toolkit 1.1"
+
+/* Define to the one symbol short name of this package. */
+#define PACKAGE_TARNAME "toolkit"
+
+/* Define to the version of this package. */
+#define PACKAGE_VERSION "1.1"
+
+/* Define as the return type of signal handlers (`int' or `void'). */
+#define RETSIGTYPE void
+
+/* SILC_DOCDIR */
+#define SILC_DOCDIR "/usr/local/silc/doc"
+
+/* SILC_ETCDIR */
+#define SILC_ETCDIR "/usr/local/silc/etc"
+
+/* SILC_HELPDIR */
+#define SILC_HELPDIR "/usr/local/silc/help"
+
+/* SILC_I386 */
+/* #undef SILC_I386 */
+
+/* SILC_I486 */
+/* #undef SILC_I486 */
+
+/* SILC_IA64 */
+/* #undef SILC_IA64 */
+
+/* SILC_MODULESDIR */
+#define SILC_MODULESDIR "/usr/local/silc/modules"
+
+/* GMP */
+/* #undef SILC_MP_GMP */
+
+/* SILCMATH */
+#define SILC_MP_SILCMATH
+
+/* SILC_NO_ASM */
+/* #undef SILC_NO_ASM */
+
+/* SILC_POWERPC */
+/* #undef SILC_POWERPC */
+
+/* SILC_STACKTRACE */
+/* #undef SILC_STACKTRACE */
+
+/* HAVE_THREAD */
+#define SILC_THREADS
+
+/* SILC_VA_COPY_ARRAY */
+/* #undef SILC_VA_COPY_ARRAY */
+
+/* SILC_WIN32 */
+/* #undef SILC_WIN32 */
+
+/* SILC_X86_64 */
+/* #undef SILC_X86_64 */
+
+/* The size of `char', as computed by sizeof. */
+#define SIZEOF_CHAR 1
+
+/* The size of `int', as computed by sizeof. */
+#define SIZEOF_INT 4
+
+/* The size of `long', as computed by sizeof. */
+#define SIZEOF_LONG 4
+
+/* The size of `long long', as computed by sizeof. */
+#define SIZEOF_LONG_LONG 8
+
+/* The size of `short', as computed by sizeof. */
+#define SIZEOF_SHORT 2
+
+/* The size of `void *', as computed by sizeof. */
+#define SIZEOF_VOID_P 4
+
+/* Define to 1 if you have the ANSI C header files. */
+#define STDC_HEADERS 1
+
+/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
+#define TIME_WITH_SYS_TIME 1
+
+/* Version number of package */
+#define VERSION "1.1"
+
+/* Define to 1 if your processor stores words with the most significant byte
+   first (like Motorola and SPARC, unlike Intel and VAX). */
+/* #undef WORDS_BIGENDIAN */
diff --git a/symbian/silcdistdefs.h b/symbian/silcdistdefs.h
new file mode 100644 (file)
index 0000000..fd186f2
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+  Automatically generated by Autodist 1.3.  Do not edit.
+
+  Generated: Fri Dec 22 21:56:55 EET 2006 by priikone
+  Distribution: default
+  License:
+*/
+
+#ifndef _SILC_DISTDEFS_H
+#define _SILC_DISTDEFS_H
+
+#define SILC_DIST_TOOLKIT 1
+#define SILC_DIST_ASN1 1
+#define SILC_DIST_COMPILER 1
+#define SILC_DIST_DOC 1
+#define SILC_DIST_IDCACHE 1
+#define SILC_DIST_INCLUDES 1
+#define SILC_DIST_LIB 1
+#define SILC_DIST_MATH 1
+#define SILC_DIST_SILC 1
+#define SILC_DIST_SKR 1
+#define SILC_DIST_TMA 1
+#define SILC_DIST_VCARD 1
+
+#endif /* _SILC_DISTDEFS_H */
index f4ced5f18c9aead30b9117b1d37bbfa0be9421bc..6e689d061cb106239301ed1a5f60d76a15abfcef 100644 (file)
@@ -39,7 +39,7 @@
 
 */
 
-#include "silcincludes.h"      /* Mandatory include for SILC applications */
+#include "silc.h"              /* Mandatory include for SILC applications */
 #include "silcclient.h"                /* SILC Client Library API */
 
 SilcClientOperations ops;