silc_snprintf name fixes.
authorPekka Riikonen <priikone@silcnet.org>
Tue, 2 Jan 2007 10:10:00 +0000 (10:10 +0000)
committerPekka Riikonen <priikone@silcnet.org>
Tue, 2 Jan 2007 10:10:00 +0000 (10:10 +0000)
14 files changed:
README.SYMBIAN
lib/silccrypt/silcpkcs1_i.h
lib/silcutil/silcfsm.c
lib/silcutil/silcfsm.h
lib/silcutil/silclog.c
lib/silcutil/silcmime.c
lib/silcutil/silctime.c
lib/silcutil/silctime.h
lib/silcutil/silcutf8.c
lib/silcutil/silcutil.c
lib/silcutil/symbian/silcsymbiannet.cpp
lib/silcutil/symbian/silcsymbiansocketstream.cpp
lib/silcutil/symbian/silcsymbianthread.cpp
symbian/silcdistdefs.h [deleted file]

index 664730dbc3bfc600311b9ad06444bf976eb9d646..6093a905ed0b7c2818786cd4029dd567ee4be609 100644 (file)
@@ -2,9 +2,9 @@ Compiling SILC Toolkit for Symbian OS
 =====================================
 
 The SILC Toolkit works on Symbian OS.  This document is intended for those
-that want to compile the SILC Toolkit by itself for Symbian OS, or for
+that want to compile the SILC Toolkit by themselves for Symbian OS, or for
 Symbian OS emulator.  The building environment expects Carbide.c++ and
-WINCW compiler for emulator target and GCCE (variant of GCC) for device
+WINSCW compiler for emulator target and GCCE (variant of GCC) for device
 target.  The SILC Toolkit has not been tested with other compilers or
 build systems.  The build environment expects MS Windows.
 
index 6c0504911cfbcd456add3da8af1bd1d05b156e79..40899e0627371c08dba61996772cce7ce5ebf1ae 100644 (file)
@@ -45,7 +45,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);
 SilcBool silc_pkcs1_decrypt(void *private_key,
                            unsigned char *src,
                            SilcUInt32 src_len,
index 9ba6466f3f5577db8d7f90fa8f8a55a687c89638..2219ed54e664561d8c19a30d9074e1cf59c8ecc9 100644 (file)
@@ -407,9 +407,9 @@ SILC_TASK_CALLBACK(silc_fsm_run)
   SILC_LOG_DEBUG(("Running %s %p", fsm->thread ? "thread" : "FSM", fsm));
 
   /* Run the states */
-//  do
+  do
     status = fsm->next_state(fsm, fsm->fsm_context, fsm->state_context);
-//  while (status == SILC_FSM_CONTINUE);
+  while (status == SILC_FSM_ST_CONTINUE);
 
   switch (status) {
   case SILC_FSM_ST_YIELD:
index 8a28360b5d3c1cfe8ff4a4322a33875bac22af04..29ec90163febf4092ba267b639fcb263713d7f04 100644 (file)
@@ -133,8 +133,12 @@ typedef struct SilcFSMObject SilcFSMThreadStruct;
  *    }
  *
  ***/
+#ifndef SILC_FSM_SMALL_STACK
 #define SILC_FSM_CONTINUE \
   return fsm->next_state(fsm, fsm->fsm_context, fsm->state_context);
+#else
+#define SILC_FSM_CONTINUE return SILC_FSM_ST_CONTINUE;
+#endif /* SILC_FSM_SMALL_STACK */
 
 /****d* silcutil/SilcFSMAPI/SILC_FSM_YIELD
  *
index 9deff33a48fecad72710977349a000d2519bdf97..4369830b6376c6690dc0e463d90e53beedc9ceba 100644 (file)
@@ -112,7 +112,7 @@ static void silc_log_checksize(SilcLog log)
   fclose(log->fp);
 
   memset(newname, 0, sizeof(newname));
-  silc_silc_snprintf(newname, sizeof(newname) - 1, "%s.old", log->filename);
+  silc_snprintf(newname, sizeof(newname) - 1, "%s.old", log->filename);
   unlink(newname);
   rename(log->filename, newname);
 
index 14fde956f14e7b2379ca973d535294ca5e1acc24..e424d5d3839840021f52ee6b85b4d941e4b6194f 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';
-       silc_silc_snprintf(b, sizeof(b) - 1, "--%s", line + 1);
+       silc_snprintf(b, sizeof(b) - 1, "--%s", line + 1);
        mime->boundary = strdup(line + 1);
       } else {
-       silc_silc_snprintf(b, sizeof(b) - 1, "--%s", line);
+       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));
-    silc_silc_snprintf(tmp, sizeof(tmp) - 1, "%s: %s\r\n", field, value);
+    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))
-       silc_silc_snprintf(tmp2, sizeof(tmp2) - 1, "\r\n");
-      silc_silc_snprintf(tmp, sizeof(tmp) - 1, "%s--%s\r\n%s",
+       silc_snprintf(tmp2, sizeof(tmp2) - 1, "\r\n");
+      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));
-    silc_silc_snprintf(tmp, sizeof(tmp) - 1, "\r\n--%s--\r\n", mime->boundary);
+    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());
-    silc_silc_snprintf(id, sizeof(id) - 1, "%X%X%X%s",
+    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));
-    silc_silc_snprintf(type, sizeof(type) - 1,
+    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) {
-       silc_silc_snprintf(type, sizeof(type) - 1,
+       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 {
-       silc_silc_snprintf(type, sizeof(type) - 1,
+       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));
-  silc_silc_snprintf(tmp, sizeof(tmp) - 1, "multipart/%s; boundary=%s", type, boundary);
+  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 b2f84c3c6af68afd9ad2fc169e1494f8759cc8db..52c356fd8e656efaa11a22bfdab88d612b43d8bf 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 = silc_silc_snprintf(ret_string, ret_string_size - 1,
+  ret = silc_snprintf(ret_string, ret_string_size - 1,
                 "%02u%02u%02u%02u%02u%02u",
                 time_val->year % 100, time_val->month, time_val->day,
                 time_val->hour, time_val->minute, time_val->second);
@@ -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 = silc_silc_snprintf(ret_string + len, ret_string_size - 1 - len, "Z");
+    ret = silc_snprintf(ret_string + len, ret_string_size - 1 - len, "Z");
     if (ret < 0)
       return FALSE;
     len += ret;
   } else {
-    ret = silc_silc_snprintf(ret_string + len, ret_string_size - 1 - len,
+    ret = silc_snprintf(ret_string + len, ret_string_size - 1 - len,
                   "%c%02u%02u", time_val->utc_east ? '+' : '-',
                   time_val->utc_hour, time_val->utc_minute);
     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 = silc_silc_snprintf(ret_string, ret_string_size - 1,
+  ret = silc_snprintf(ret_string, ret_string_size - 1,
                 "%04u%02u%02u%02u%02u%02u",
                 time_val->year, time_val->month, time_val->day, time_val->hour,
                 time_val->minute, time_val->second);
@@ -328,7 +328,7 @@ SilcBool silc_time_generalized_string(SilcTime time_val, char *ret_string,
   len += ret;
 
   if (time_val->msecond) {
-    ret = silc_silc_snprintf(ret_string + len, ret_string_size - 1 - len,
+    ret = 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 = silc_silc_snprintf(ret_string + len, ret_string_size - 1 - len, "Z");
+    ret = silc_snprintf(ret_string + len, ret_string_size - 1 - len, "Z");
     if (ret < 0)
       return FALSE;
     len += ret;
   } else {
-    ret = silc_silc_snprintf(ret_string + len, ret_string_size - 1 - len,
+    ret = silc_snprintf(ret_string + len, ret_string_size - 1 - len,
                   "%c%02u%02u", time_val->utc_east ? '+' : '-',
                   time_val->utc_hour, time_val->utc_minute);
     if (ret < 0)
index c7494bafa9dc98d9cd124ee73f5d28941059dc3d..a57830f6444a90006491b6866f5e30fa9f1b6097 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
@@ -105,34 +105,34 @@ SilcInt64 silc_time_usec(void);
  *
  * SYNOPSIS
  *
- *    const char *silc_time_string(SilcInt64 time_val);
+ *    const char *silc_time_string(SilcInt64 time_val_sec);
  *
  * DESCRIPTION
  *
  *    Returns time and date as string.  The caller must not free the string
  *    and next call to this function will delete the old string.  If the
- *    `time_val' is zero (0) returns current time as string, otherwise the
- *    `time_val' as string.  The `time_val' is in seconds since Epoch.
+ *    `time_val_sec' is zero (0) returns current time as string, otherwise the
+ *    `time_val_sec' as string.  The `time_val_sec' is in seconds since Epoch.
  *    Returns NULL on error.
  *
  ***/
-const char *silc_time_string(SilcInt64 time_val);
+const char *silc_time_string(SilcInt64 time_val_sec);
 
 /****f* silcutil/SilcTimeAPI/silc_time_value
  *
  * SYNOPSIS
  *
- *   SilcBool silc_time_value(SilcInt64 time_val, SilcTime ret_time);
+ *   SilcBool silc_time_value(SilcInt64 time_val_msec, SilcTime ret_time);
  *
  * DESCRIPTION
  *
- *    Returns time and date as SilcTime.  If the `time_val' is zero (0)
- *    returns current time as SilcTime, otherwise the `time_val' as SilcTime.
- *    The `time_val' is in milliseconds since Epoch.  Returns FALSE on error,
- *    TRUE otherwise.
+ *    Returns time and date as SilcTime.  If the `time_val_msec' is zero (0)
+ *    returns current time as SilcTime, otherwise the `time_val_msec' as
+ *    SilcTime.  The `time_val_msec' is in milliseconds since Epoch.  Returns
+ *    FALSE on error, TRUE otherwise.
  *
  ***/
-SilcBool silc_time_value(SilcInt64 time_val, SilcTime ret_time);
+SilcBool silc_time_value(SilcInt64 time_val_msec, SilcTime ret_time);
 
 /****f* silcutil/SilcTimeAPI/silc_time_universal
  *
index 29f74dc34dbc04795d19d542c18af30f83e8daf5..65254eb5fab82196e6ec76b6e18e3c071c0bea0f 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] = '\\';
-             silc_silc_snprintf(bin + enclen + 1, 3, "%02X", cv);
+             silc_snprintf(bin + enclen + 1, 3, "%02X", cv);
            }
            enclen += 3;
            continue;
index 04b1036358433e3163c75ef64076f2b412cb5985..5fd5de84b3a241e936d3735b956a91d083f23524 100644 (file)
@@ -236,7 +236,7 @@ char *silc_format(char *fmt, ...)
 
   memset(buf, 0, sizeof(buf));
   va_start(args, fmt);
-  vsilc_snprintf(buf, sizeof(buf) - 1, fmt, args);
+  vsnprintf(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++) {
-    silc_silc_snprintf(cp, sizeof(fingerprint), "%02X", data[i]);
+    silc_snprintf(cp, sizeof(fingerprint), "%02X", data[i]);
     cp += 2;
 
     if ((i + 1) % 2 == 0)
-      silc_silc_snprintf(cp++, sizeof(fingerprint), " ");
+      silc_snprintf(cp++, sizeof(fingerprint), " ");
 
     if ((i + 1) % 10 == 0)
-      silc_silc_snprintf(cp++, sizeof(fingerprint), " ");
+      silc_snprintf(cp++, sizeof(fingerprint), " ");
   }
   i--;
   if ((i + 1) % 2 == 0)
index f2ae993dc9118dce786773e914109d2196f70d92..6cc8d736e839deb236d3ae948289fa21b8ca9130 100644 (file)
-/*\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
+/*
+
+  silcsymbiannet.cpp
+
+  Author: Pekka Riikonen <priikone@silcnet.org>
+
+  Copyright (C) 2006 - 2007 Pekka Riikonen
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; version 2 of the License.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+*/
+
+#include "silc.h"
+#include "silcsymbiansocketstream.h"
+
+/****************************** TCP Listener ********************************/
+
+class SilcSymbianTCPListener;
+
+/* Deliver new stream to upper layer */
+
+static void silc_net_accept_stream(SilcSocketStreamStatus status,
+                                  SilcStream stream, void *context)
+{
+  SilcNetListener listener = (SilcNetListener)context;
+
+  /* In case of error, the socket has been destroyed already */
+  if (status != SILC_SOCKET_OK)
+    return;
+
+  listener->callback(SILC_NET_OK, stream, listener->context);
+}
+
+/* TCP Listener class */
+
+class SilcSymbianTCPListener : public CActive {
+public:
+  /* Constructor */
+  SilcSymbianTCPListener() : CActive(CActive::EPriorityStandard)
+  {
+    CActiveScheduler::Add(this);
+  }
+
+  /* Destructor */
+  ~SilcSymbianTCPListener()
+  {
+    Cancel();
+  }
+
+  /* Listen for connection */
+  void Listen()
+  {
+    new_conn = new RSocket;
+    if (!new_conn)
+      return;
+    if (new_conn->Open(ss) != KErrNone) {
+      Listen();
+      return;
+    }
+
+    /* Start listenning */
+    sock.Accept(*new_conn, iStatus);
+    SetActive();
+  }
+
+  /* Listener callback */
+  virtual void RunL()
+  {
+    if (iStatus != KErrNone) {
+      if (new_conn)
+       delete new_conn;
+      new_conn = NULL;
+      Listen();
+      return;
+    }
+
+    /* Set socket options */
+    new_conn->SetOpt(KSoReuseAddr, KSolInetIp, 1);
+
+    /* Create socket stream */
+    silc_socket_tcp_stream_create(
+                       (SilcSocket)silc_create_symbian_socket(new_conn, NULL),
+                       listener->lookup, listener->require_fqdn,
+                       listener->schedule, silc_net_accept_stream,
+                       (void *)listener);
+    new_conn = NULL;
+
+    /* Continue listenning */
+    Listen();
+  }
+
+  /* Cancel */
+  virtual void DoCancel()
+  {
+    sock.CancelAll();
+    ss.Close();
+    if (new_conn)
+      delete new_conn;
+  }
+
+  RSocket *new_conn;
+  RSocket sock;
+  RSocketServ ss;
+  SilcNetListener listener;
+};
+
+/* Create TCP listener */
+
+SilcNetListener
+silc_net_tcp_create_listener(const char **local_ip_addr,
+                            SilcUInt32 local_ip_count, int port,
+                            SilcBool lookup, SilcBool require_fqdn,
+                            SilcSchedule schedule,
+                            SilcNetCallback callback, void *context)
+{
+  SilcNetListener listener = NULL;
+  SilcSymbianTCPListener *l = NULL;
+  TInetAddr server;
+  TInt ret;
+  TBuf<64> tmp;
+  int i;
+
+  SILC_LOG_DEBUG(("Creating TCP listener"));
+
+  if (port < 0 || !schedule || !callback)
+    goto err;
+
+  listener = (SilcNetListener)silc_calloc(1, sizeof(*listener));
+  if (!listener) {
+    callback(SILC_NET_NO_MEMORY, NULL, context);
+    return NULL;
+  }
+  listener->schedule = schedule;
+  listener->callback = callback;
+  listener->context = context;
+  listener->require_fqdn = require_fqdn;
+  listener->lookup = lookup;
+
+  if (local_ip_count > 0) {
+    listener->socks = (SilcSocket *)silc_calloc(local_ip_count,
+                                             sizeof(*listener->socks));
+    if (!listener->socks) {
+      callback(SILC_NET_NO_MEMORY, NULL, context);
+      return NULL;
+    }
+  } else {
+    listener->socks = (SilcSocket *)silc_calloc(1, sizeof(*listener->socks));
+    if (!listener->socks) {
+      callback(SILC_NET_NO_MEMORY, NULL, context);
+      return NULL;
+    }
+
+    local_ip_count = 1;
+  }
+
+  /* Bind to local addresses */
+  for (i = 0; i < local_ip_count; i++) {
+    SILC_LOG_DEBUG(("Binding to local address %s",
+                   local_ip_addr ? local_ip_addr[i] : "0.0.0.0"));
+
+    l = new SilcSymbianTCPListener;
+    if (!l)
+      goto err;
+
+    /* Connect to socket server */
+    ret = l->ss.Connect();
+    if (ret != KErrNone)
+      goto err;
+
+    /* Set listener address */
+    if (local_ip_addr) {
+      server = TInetAddr(port);
+      tmp = (TText *)local_ip_addr[i];
+      ret = server.Input(tmp);
+      if (ret != KErrNone)
+       goto err;
+    } else {
+      server = TInetAddr(KInetAddrAny, port);
+    }
+
+    /* Create the socket */
+    ret = l->sock.Open(l->ss, KAfInet, KSockStream, KProtocolInetTcp);
+    if (ret != KErrNone) {
+      SILC_LOG_ERROR(("Cannot create socket"));
+      goto err;
+    }
+
+    /* Set the socket options */
+    ret = l->sock.SetOpt(KSoReuseAddr, KSolInetIp, 1);
+    if (ret != KErrNone) {
+      SILC_LOG_ERROR(("Cannot set socket options"));
+      goto err;
+    }
+
+    /* Bind the listener socket */
+    ret = l->sock.Bind(server);
+    if (ret != KErrNone) {
+      SILC_LOG_DEBUG(("Cannot bind socket"));
+      goto err;
+    }
+
+    /* Specify that we are listenning */
+    ret = l->sock.Listen(5);
+    if (ret != KErrNone) {
+      SILC_LOG_ERROR(("Cannot set socket listenning"));
+      goto err;
+    }
+    l->Listen();
+
+    l->listener = listener;
+    listener->socks[i] = (SilcSocket)l;
+    listener->socks_count++;
+  }
+
+  SILC_LOG_DEBUG(("TCP listener created"));
+
+  return listener;
+
+ err:
+  if (l)
+    delete l;
+  if (callback)
+    callback(SILC_NET_ERROR, NULL, context);
+  if (listener)
+    silc_net_close_listener(listener);
+  return NULL;
+}
+
+/* Close network listener */
+
+void silc_net_close_listener(SilcNetListener listener)
+{
+  int i;
+
+  SILC_LOG_DEBUG(("Closing network listener"));
+
+  for (i = 0; i < listener->socks_count; i++) {
+    SilcSymbianTCPListener *l = (SilcSymbianTCPListener *)listener->socks[i];
+    l->sock.CancelAll();
+    l->sock.Close();
+    l->ss.Close();
+    if (l->new_conn)
+      delete l->new_conn;
+    delete l;
+  }
+
+  silc_free(listener->socks);
+  silc_free(listener);
+}
+
+/**************************** TCP/IP connecting *****************************/
+
+static void silc_net_connect_stream(SilcSocketStreamStatus status,
+                                   SilcStream stream, void *context);
+
+/* TCP connecting class */
+
+class SilcSymbianTCPConnect : public CActive {
+public:
+  /* Constructor */
+  SilcSymbianTCPConnect() : CActive(CActive::EPriorityStandard)
+  {
+    CActiveScheduler::Add(this);
+  }
+
+  /* Destructor */
+  ~SilcSymbianTCPConnect()
+  {
+    silc_free(remote);
+    if (op)
+      silc_async_free(op);
+    Cancel();
+  }
+
+  /* Connect to remote host */
+  void Connect(TSockAddr &addr)
+  {
+    sock->Connect(addr, iStatus);
+    SetActive();
+  }
+
+  /* Connection callback */
+  virtual void RunL()
+  {
+    if (iStatus != KErrNone) {
+      if (callback)
+       callback(SILC_NET_ERROR, NULL, context);
+      sock->CancelConnect();
+      delete sock;
+      ss->Close();
+      delete ss;
+      sock = NULL;
+      ss = NULL;
+      delete this;
+      return;
+    }
+
+    /* Create stream */
+    if (callback) {
+      silc_socket_tcp_stream_create(
+                            (SilcSocket)silc_create_symbian_socket(sock, ss),
+                            FALSE, FALSE, schedule, silc_net_connect_stream,
+                            (void *)this);
+    } else {
+      sock->Close();
+      delete sock;
+      ss->Close();
+      delete ss;
+      sock = NULL;
+      ss = NULL;
+    }
+
+    delete this;
+  }
+
+  /* Cancel */
+  virtual void DoCancel()
+  {
+    if (ss) {
+      ss->Close();
+      delete ss;
+    }
+    if (sock) {
+      sock->CancelConnect();
+      delete sock;
+    }
+  }
+
+  RSocket *sock;
+  RSocketServ *ss;
+  char *remote;
+  char remote_ip[64];
+  int port;
+  SilcAsyncOperation op;
+  SilcSchedule schedule;
+  SilcNetCallback callback;
+  void *context;
+};
+
+/* Stream creation callback */
+
+static void silc_net_connect_stream(SilcSocketStreamStatus status,
+                                   SilcStream stream, void *context)
+{
+  SilcSymbianTCPConnect *conn = (SilcSymbianTCPConnect *)context;
+  SilcNetStatus net_status = SILC_NET_OK;
+
+  if (status != SILC_SOCKET_OK) {
+    /* In case of error, the socket has been destroyed already */
+    if (status == SILC_SOCKET_UNKNOWN_IP)
+      net_status = SILC_NET_UNKNOWN_IP;
+    else if (status == SILC_SOCKET_UNKNOWN_HOST)
+      net_status = SILC_NET_UNKNOWN_HOST;
+    else
+      net_status = SILC_NET_ERROR;
+  }
+
+  /* Set stream information */
+  if (stream && conn->callback)
+    silc_socket_stream_set_info(stream,
+                               !silc_net_is_ip(conn->remote) ? conn->remote :
+                               conn->remote_ip, conn->remote_ip, conn->port);
+
+  /* Call connection callback */
+  if (conn->callback)
+    conn->callback(net_status, stream, conn->context);
+  else if (stream)
+    silc_stream_destroy(stream);
+
+  delete conn;
+}
+
+/* Connecting abort callback */
+
+static void silc_net_connect_abort(SilcAsyncOperation op, void *context)
+{
+  SilcSymbianTCPConnect *conn = (SilcSymbianTCPConnect *)context;
+
+  /* Abort */
+  conn->callback = NULL;
+  conn->op = NULL;
+  if (conn->sock)
+    sock->CancelConnect();
+}
+
+/* Create TCP/IP connection */
+
+SilcAsyncOperation silc_net_tcp_connect(const char *local_ip_addr,
+                                       const char *remote_ip_addr,
+                                       int remote_port,
+                                       SilcSchedule schedule,
+                                       SilcNetCallback callback,
+                                       void *context)
+{
+  SilcSymbianTCPConnect *conn;
+  TInetAddr local, remote;
+  SilcNetStatus status;
+  TBuf<64> tmp;
+  TInt ret;
+
+  if (!remote_ip_addr || remote_port < 1 || !schedule || !callback)
+    return NULL;
+
+  SILC_LOG_DEBUG(("Creating connection to host %s port %d",
+                 remote_ip_addr, remote_port));
+
+  conn = new SilcSymbianTCPConnect;
+  if (!conn) {
+    callback(SILC_NET_NO_MEMORY, NULL, context);
+    return NULL;
+  }
+  conn->schedule = schedule;
+  conn->callback = callback;
+  conn->context = context;
+  conn->port = remote_port;
+  conn->remote = strdup(remote_ip_addr);
+  if (!conn->remote) {
+    status = SILC_NET_NO_MEMORY;
+    goto err;
+  }
+
+  /* Allocate socket */
+  conn->sock = new RSocket;
+  if (!conn->sock) {
+    status = SILC_NET_NO_MEMORY;
+    goto err;
+  }
+
+  /* Allocate socket server */
+  conn->ss = new RSocketServ;
+  if (!conn->ss) {
+    status = SILC_NET_NO_MEMORY;
+    goto err;
+  }
+
+  /* Connect to socket server */
+  ret = conn->ss->Connect();
+  if (ret != KErrNone) {
+    status = SILC_NET_ERROR;
+    goto err;
+  }
+
+  /* Start async operation */
+  conn->op = silc_async_alloc(silc_net_connect_abort, NULL, (void *)conn);
+  if (!conn->op) {
+    status = SILC_NET_NO_MEMORY;
+    goto err;
+  }
+
+  /* Do host lookup */
+  if (!silc_net_is_ip(remote_ip_addr)) {
+    if (!silc_net_gethostbyname(remote_ip_addr, FALSE, conn->remote_ip,
+                               sizeof(conn->remote_ip))) {
+      SILC_LOG_ERROR(("Network (%s) unreachable: could not resolve the "
+                     "host", conn->remote));
+      status = SILC_NET_HOST_UNREACHABLE;
+      goto err;
+    }
+  } else {
+    strcpy(conn->remote_ip, remote_ip_addr);
+  }
+
+  /* Create the connection socket */
+  ret = conn->sock->Open(*conn->ss, KAfInet, KSockStream, KProtocolInetTcp);
+  if (ret != KErrNone) {
+    SILC_LOG_ERROR(("Cannot create socket"));
+    status = SILC_NET_ERROR;
+    goto err;
+  }
+
+  /* Set appropriate options */
+  conn->sock->SetOpt(KSoTcpNoDelay, KSolInetTcp, 1);
+  conn->sock->SetOpt(KSoTcpKeepAlive, KSolInetTcp, 1);
+
+  /* Bind to the local address if provided */
+  if (local_ip_addr) {
+    local = TInetAddr(0);
+    tmp = (TText *)local_ip_addr;
+    ret = local.Input(tmp);
+    if (ret == KErrNone)
+      ret = conn->sock->Bind(local);
+  }
+
+  /* Connect to the host */
+  remote = TInetAddr(remote_port);
+  tmp = (TText *)conn->remote_ip;
+  ret = remote.Input(tmp);
+  if (ret != KErrNone) {
+    SILC_LOG_ERROR(("Cannot connect (cannot set address)"));
+    status = SILC_NET_ERROR;
+    goto err;
+  }
+  conn->Connect(remote);
+
+  SILC_LOG_DEBUG(("Connection operation in progress"));
+
+  return conn->op;
+
+ err:
+  if (conn->ss) {
+    conn->ss->Close();
+    delete conn->ss;
+  }
+  if (conn->sock)
+    delete conn->sock;
+  if (conn->remote)
+    silc_free(conn->remote);
+  if (conn->op)
+    silc_async_free(conn->op);
+  callback(status, NULL, context);
+  delete conn;
+  return NULL;
+}
+
+/****************************** UDP routines ********************************/
+
+/* Create UDP/IP connection */
+
+SilcStream silc_net_udp_connect(const char *local_ip_addr, int local_port,
+                               const char *remote_ip_addr, int remote_port,
+                               SilcSchedule schedule)
+{
+  SilcSymbianSocket *s;
+  SilcStream stream;
+  TInetAddr local, remote;
+  TRequestStatus status;
+  RSocket *sock = NULL;
+  RSocketServ *ss = NULL;
+  TBuf<64> tmp;
+  TInt ret;
+
+  SILC_LOG_DEBUG(("Creating UDP stream"));
+
+  if (!schedule)
+    goto err;
+
+  SILC_LOG_DEBUG(("Binding to local address %s",
+                 local_ip_addr ? local_ip_addr : "0.0.0.0"));
+
+  sock = new RSocket;
+  if (!sock)
+    goto err;
+
+  ss = new RSocketServ;
+  if (!ss)
+    goto err;
+
+  /* Open socket server */
+  ret = ss->Connect();
+  if (ret != KErrNone)
+    goto err;
+
+  /* Get local bind address */
+  if (local_ip_addr) {
+    local = TInetAddr(local_port);
+    tmp = (TText *)local_ip_addr;
+    ret = local.Input(tmp);
+    if (ret != KErrNone)
+      goto err;
+  } else {
+    local = TInetAddr(KInetAddrAny, local_port);
+  }
+
+  /* Create the socket */
+  ret = sock->Open(*ss, KAfInet, KSockDatagram, KProtocolInetUdp);
+  if (ret != KErrNone) {
+    SILC_LOG_ERROR(("Cannot create socket"));
+    goto err;
+  }
+
+  /* Set the socket options */
+  sock->SetOpt(KSoReuseAddr, KSolInetIp, 1);
+
+  /* Bind the listener socket */
+  ret = sock->Bind(local);
+  if (ret != KErrNone) {
+    SILC_LOG_DEBUG(("Cannot bind socket"));
+    goto err;
+  }
+
+  /* Set to connected state if remote address is provided. */
+  if (remote_ip_addr && remote_port) {
+    remote = TInetAddr(remote_port);
+    tmp = (TText *)remote_ip_addr;
+    ret = remote.Input(tmp);
+    if (ret != KErrNone)
+      goto err;
+
+    sock->Connect(remote, status);
+    if (status != KErrNone) {
+      SILC_LOG_DEBUG(("Cannot connect UDP stream"));
+      goto err;
+    }
+  }
+
+  /* Encapsulate into socket stream */
+  s = silc_create_symbian_socket(sock, ss);
+  if (!s)
+    goto err;
+  stream =
+    silc_socket_udp_stream_create((SilcSocket)s, local_ip_addr ?
+                                 silc_net_is_ip6(local_ip_addr) : FALSE,
+                                 remote_ip_addr ? TRUE : FALSE, schedule);
+  if (!stream)
+    goto err;
+
+  SILC_LOG_DEBUG(("UDP stream created, fd=%d", sock));
+  return stream;
+
+ err:
+  if (sock)
+    delete sock;
+  if (ss) {
+    ss->Close();
+    delete ss;
+  }
+  return NULL;
+}
+
+/* Sets socket to non-blocking mode */
+
+int silc_net_set_socket_nonblock(SilcSocket sock)
+{
+  /* Nothing to do in Symbian where blocking socket mode is asynchronous
+     already (ie. non-blocking). */
+  return 0;
+}
+
+/* Converts the IP number string from numbers-and-dots notation to
+   binary form. */
+
+SilcBool silc_net_addr2bin(const char *addr, void *bin, SilcUInt32 bin_len)
+{
+  int ret = 0;
+
+  struct in_addr tmp;
+  ret = inet_aton(addr, &tmp);
+  if (bin_len < 4)
+    return FALSE;
+
+  memcpy(bin, (unsigned char *)&tmp.s_addr, 4);
+
+  return ret != 0;
+}
+
+/* Get remote host and IP from socket */
+
+SilcBool silc_net_check_host_by_sock(SilcSocket sock, char **hostname,
+                                    char **ip)
+{
+  SilcSymbianSocket *s = (SilcSymbianSocket *)sock;
+  TInetAddr addr;
+  char host[256];
+  TBuf<64> tmp;
+
+  if (hostname)
+    *hostname = NULL;
+  *ip = NULL;
+
+  s->sock->RemoteName(addr);
+  addr.Output(tmp);
+
+  *ip = (char *)silc_memdup(tmp.Ptr(), tmp.Length());
+  if (*ip == NULL)
+    return FALSE;
+
+  /* Do reverse lookup if we want hostname too. */
+  if (hostname) {
+    /* Get host by address */
+    if (!silc_net_gethostbyaddr(*ip, host, sizeof(host)))
+      return FALSE;
+
+    *hostname = (char *)silc_memdup(host, strlen(host));
+    SILC_LOG_DEBUG(("Resolved hostname `%s'", *hostname));
+
+    /* Reverse */
+    if (!silc_net_gethostbyname(*hostname, TRUE, host, sizeof(host)))
+      return FALSE;
+
+    if (strcmp(*ip, host))
+      return FALSE;
+  }
+
+  SILC_LOG_DEBUG(("Resolved IP address `%s'", *ip));
+  return TRUE;
+}
+
+/* Get local host and IP from socket */
+
+SilcBool silc_net_check_local_by_sock(SilcSocket sock, char **hostname,
+                                     char **ip)
+{
+  SilcSymbianSocket *s = (SilcSymbianSocket *)sock;
+  TInetAddr addr;
+  char host[256];
+  TBuf<64> tmp;
+
+  if (hostname)
+    *hostname = NULL;
+  *ip = NULL;
+
+  s->sock->LocalName(addr);
+  addr.Output(tmp);
+
+  *ip = (char *)silc_memdup(tmp.Ptr(), tmp.Length());
+  if (*ip == NULL)
+    return FALSE;
+
+  /* Do reverse lookup if we want hostname too. */
+  if (hostname) {
+    /* Get host by address */
+    if (!silc_net_gethostbyaddr(*ip, host, sizeof(host)))
+      return FALSE;
+
+    *hostname = (char *)silc_memdup(host, strlen(host));
+    SILC_LOG_DEBUG(("Resolved hostname `%s'", *hostname));
+
+    /* Reverse */
+    if (!silc_net_gethostbyname(*hostname, TRUE, host, sizeof(host)))
+      return FALSE;
+
+    if (strcmp(*ip, host))
+      return FALSE;
+  }
+
+  SILC_LOG_DEBUG(("Resolved IP address `%s'", *ip));
+  return TRUE;
+}
+
+/* Get remote port from socket */
+
+SilcUInt16 silc_net_get_remote_port(SilcSocket sock)
+{
+  SilcSymbianSocket *s = (SilcSymbianSocket *)sock;
+  TInetAddr addr;
+
+  s->sock->RemoteName(addr);
+  return (SilcUInt16)addr.Port();
+}
+
+/* Get local port from socket */
+
+SilcUInt16 silc_net_get_local_port(SilcSocket sock)
+{
+  SilcSymbianSocket *s = (SilcSymbianSocket *)sock;
+  TInetAddr addr;
+
+  s->sock->LocalName(addr);
+  return (SilcUInt16)addr.Port();
+}
index fe9d57d64d38f570c3573643a4fc647904447ff8..2d90808b66fe9fb61bf0b7b15aee629a6e09dbef 100644 (file)
@@ -1,11 +1,10 @@
-\r
 /*\r
 \r
   silcsymbiansocketstream.cpp\r
 \r
   Author: Pekka Riikonen <priikone@silcnet.org>\r
 \r
-  Copyright (C) 2006 Pekka Riikonen\r
+  Copyright (C) 2006 - 2007 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
@@ -69,7 +68,7 @@ public:
   }\r
 \r
   /* Sending callback */\r
-  void RunL()\r
+  virtual void RunL()\r
   {\r
     if (iStatus != KErrNone) {\r
       if (iStatus == KErrEof)\r
@@ -86,7 +85,7 @@ public:
   }\r
 \r
   /* Cancel */\r
-  void DoCancel()\r
+  virtual void DoCancel()\r
   {\r
     s->sock->CancelWrite();\r
   }\r
@@ -121,7 +120,7 @@ public:
   }\r
 \r
   /* Reading callback */\r
-  void RunL()\r
+  virtual void RunL()\r
   {\r
     if (iStatus != KErrNone) {\r
       if (iStatus == KErrEof)\r
@@ -145,7 +144,7 @@ public:
   }\r
 \r
   /* Cancel */\r
-  void DoCancel()\r
+  virtual void DoCancel()\r
   {\r
     s->sock->CancelRecv();\r
   }\r
@@ -392,7 +391,7 @@ void silc_socket_stream_destroy(SilcStream stream)
     s->ss->Close();\r
     delete s->ss;\r
   }\r
-  delete s;\r
+  silc_free(s);\r
 }\r
 \r
 /* Sets stream notification callback for the stream */\r
index 5d637b423ed6af34307232fdf9d3a18aab63546d..7e134e527d13281ec9880ca8fd69b7595f36e9be 100644 (file)
-/*\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
+/*
+
+  silcsymbianthread.cpp
+
+  Author: Pekka Riikonen <priikone@silcnet.org>
+
+  Copyright (C) 2006 - 2007 Pekka Riikonen
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; version 2 of the License.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+*/
+
+#include "silc.h"
+#include <e32std.h>
+
+/**************************** SILC Thread API *******************************/
+
+/* Thread structure for Symbian */
+typedef struct {
+#ifdef SILC_THREADS
+  SilcThreadStart start_func;
+  void *context;
+  SilcBool waitable;
+#else
+  void *tmp;
+#endif
+} *SilcSymbianThread;
+
+/* The actual thread function */
+
+static TInt silc_thread_start(TAny *context)
+{
+#ifdef SILC_THREADS
+  SilcSymbianThread tc = (SilcSymbianThread)context;
+  SilcThreadStart start_func = tc->start_func;
+  void *context = tc->context;
+  SilcBool waitable = tc->waitable;
+
+  silc_free(tc);
+
+  /* Call the thread function */
+  if (waitable)
+    silc_thread_exit(start_func(context));
+  else
+    start_func(context);
+
+#endif
+  return KErrNone;
+}
+
+/* Executed new thread */
+
+SilcThread silc_thread_create(SilcThreadStart start_func, void *context,
+                             bool waitable)
+{
+#ifdef SILC_THREADS
+  SilcSymbianThread tc;
+  RThread *thread;
+  TInt ret;
+  TBuf<32> name;
+
+  SILC_LOG_DEBUG(("Creating new thread"));
+
+  tc = (SilcSymbianThread)silc_calloc(1, sizeof(*thread));
+  if (!tc)
+    return NULL;
+  tc->start_func = start_func;
+  tc->context = context;
+  tc->waitable = waitable;
+
+  /* Allocate thread */
+  thread = new RThread();
+  if (!thread) {
+    silc_free(tc);
+    return NULL;
+  }
+
+  /* Create the thread */
+  name = (TText *)silc_time_string(0);
+  ret = thread->Create(name, silc_thread_start, 8192, 4096, 1024 * 1024,
+                      (TAny *)tc);
+  if (ret != KErrNone) {
+    SILC_LOG_ERROR(("Could not create new thread"));
+    delete thread;
+    silc_free(tc);
+    return NULL;
+  }
+
+  /* Start the thread */
+  thread->Resume();
+
+  /* Close our instance to the thread */
+  thread->Close();
+
+  return (SilcThread)thread;
+#else
+  /* Call thread callback immediately */
+  (*start_func)(context);
+  return NULL;
+#endif
+}
+
+/* Exits current thread */
+
+void silc_thread_exit(void *exit_value)
+{
+#ifdef SILC_THREADS
+  RThread().Kill((Tint)exit_value);
+#endif
+}
+
+/* Returns current thread context */
+
+SilcThread silc_thread_self(void)
+{
+#ifdef SILC_THREADS
+  return (SilcThread)&RThread();
+#else
+  return NULL;
+#endif
+}
+
+/* Blocks calling thread to wait for `thread' to finish. */
+
+SilcBool silc_thread_wait(SilcThread thread, void **exit_value)
+{
+#ifdef SILC_THREADS
+  TRequestStatus req;
+  RThread *t = (RThread *)thread;
+  t->Logon(req);
+  User::WaitForAnyRequest();
+  return TRUE;
+#else
+  return FALSE;
+#endif
+}
+
+/***************************** SILC Mutex API *******************************/
+
+/* SILC Mutex structure */
+struct SilcMutexStruct {
+#ifdef SILC_THREADS
+  RMutex *mutex;
+#endif /* SILC_THREADS */
+  unsigned int locked : 1;
+};
+
+SilcBool silc_mutex_alloc(SilcMutex *mutex)
+{
+#ifdef SILC_THREADS
+  *mutex = (SilcMutex)silc_calloc(1, sizeof(**mutex));
+  if (*mutex == NULL)
+    return FALSE;
+  (*mutex)->mutex = new RMutex();
+  if (!(*mutex)->mutex) {
+    silc_free(*mutex);
+    return FALSE;
+  }
+  if ((*mutex)->mutex->CreateLocal() != KErrNone) {
+    delete (*mutex)->mutex;
+    silc_free(*mutex);
+    return FALSE;
+  }
+  (*mutex)->locked = FALSE;
+  return TRUE;
+#else
+  return FALSE;
+#endif /* SILC_THREADS */
+}
+
+void silc_mutex_free(SilcMutex mutex)
+{
+#ifdef SILC_THREADS
+  if (mutex) {
+    mutex->mutex->Close();
+    delete mutex->mutex;
+    silc_free(mutex);
+  }
+#endif /* SILC_THREADS */
+}
+
+void silc_mutex_lock(SilcMutex mutex)
+{
+#ifdef SILC_THREADS
+  if (mutex) {
+    mutex->mutex->Wait();
+    mutex->locked = TRUE;
+  }
+#endif /* SILC_THREADS */
+}
+
+void silc_mutex_unlock(SilcMutex mutex)
+{
+#ifdef SILC_THREADS
+  if (mutex) {
+    mutex->mutex->Signal();
+    mutex->locked = FALSE;
+  }
+#endif /* SILC_THREADS */
+}
+
+void silc_mutex_assert_locked(SilcMutex mutex)
+{
+#ifdef SILC_THREADS
+  if (mutex)
+    SILC_ASSERT(mutex->locked);
+#endif /* SILC_THREADS */
+}
+
+
+/****************************** SILC Cond API *******************************/
+
+/* SILC Conditional Variable context */
+struct SilcCondStruct {
+#ifdef SILC_THREADS
+  RCondVar *cond;
+#else
+  void *tmp;
+#endif /* SILC_THREADS*/
+};
+
+SilcBool silc_cond_alloc(SilcCond *cond)
+{
+#ifdef SILC_THREADS
+  *cond = (SilcCond)silc_calloc(1, sizeof(**cond));
+  if (*cond == NULL)
+    return FALSE;
+  (*cond)->cond = new RCondVar();
+  if (!(*cond)->cond) {
+    silc_free(*cond);
+    return FALSE;
+  }
+  if ((*cond)->cond->CreateLocal() != KErrNone) {
+    delete (*cond)->cond;
+    silc_free(*cond);
+    return FALSE;
+  }
+  return TRUE;
+#else
+  return FALSE;
+#endif /* SILC_THREADS*/
+}
+
+void silc_cond_free(SilcCond cond)
+{
+#ifdef SILC_THREADS
+  cond->cond->Close();
+  delete cond->cond;
+  silc_free(cond);
+#endif /* SILC_THREADS*/
+}
+
+void silc_cond_signal(SilcCond cond)
+{
+#ifdef SILC_THREADS
+  cond->cond->Signal();
+#endif /* SILC_THREADS*/
+}
+
+void silc_cond_broadcast(SilcCond cond)
+{
+#ifdef SILC_THREADS
+  cond->cond->Broadcast();
+#endif /* SILC_THREADS*/
+}
+
+void silc_cond_wait(SilcCond cond, SilcMutex mutex)
+{
+#ifdef SILC_THREADS
+  cond->cond->Wait(*mutex->mutex);
+#endif /* SILC_THREADS*/
+}
+
+SilcBool silc_cond_timedwait(SilcCond cond, SilcMutex mutex,
+                            int timeout)
+{
+#ifdef SILC_THREADS
+  if (timeout)
+    return (cond->cond->TimedWait(*mutex->mutex, (TInt)timeout * 1000) ==
+           KErrNone);
+  return (cond->cond->Wait(*mutex->mutex) == KErrNone);
+#else
+  return FALSE;
+#endif /* SILC_THREADS*/
+}
diff --git a/symbian/silcdistdefs.h b/symbian/silcdistdefs.h
deleted file mode 100644 (file)
index fd186f2..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
-  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 */