Added silc_snprintf.
Added SilcRng argument to silc_pkcs_encrypt API.
+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
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
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
#
# 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
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
])
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)
#
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.
~ Hostname ~
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-| Port |
+| Protocol | Port |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
.in 3
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
.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
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
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
#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
#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 */
#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
#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
/* Include generic SILC type definitions */
#include "silctypes.h"
+#include "silcmutex.h"
#include "silcatomic.h"
#include "silcversion.h"
/* More SILC util library includes */
#include "silctime.h"
-#include "silcmutex.h"
#include "silccond.h"
#include "silcthread.h"
#include "silcschedule.h"
+++ /dev/null
-/*
-
- 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
--- /dev/null
+/*
+
+ 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 */
#
# 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
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
*/
+#include "silc.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <assert.h>
-//#include "silc.h"
#include "regexpr.h"
#define MACRO_BEGIN do {
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);
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): ");
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)
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)
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);
}
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);
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);
}
}
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;
}
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);
}
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;
/* 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);
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;
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"));
/* 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:
}
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;
/* 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) {
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);
}
}
/* 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)) {
} 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);
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
SilcUInt32 src_len,
unsigned char *dst,
SilcUInt32 dst_size,
- SilcUInt32 *ret_dst_len)
+ SilcUInt32 *ret_dst_len,
+ SilcRng rng)
{
SilcSILCPublicKey silc_pubkey = 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 */
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
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,
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
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 */
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
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,
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,
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
*
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
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;
}
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;
/* 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);
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;
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");
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);
}
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));
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)) {
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 */
/* 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' : '-'),
#include "silc.h"
#include "silcskr.h"
+/* XXX Locking, when removing keys */
+
/************************** Types and definitions ***************************/
/* Search constraints */
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);
}
}
#
# 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
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
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);
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);
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++;
}
/* 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;
}
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)
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);
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);
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);
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);
/* 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;
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;
/* 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;
/* 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;
/* 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;
return ntohs(local.sin_port);
#endif
}
+#endif /* !SILC_SYMBIAN */
/* Return name of localhost. */
*
* 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);
*
* 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
*
* 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);
*
* 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
*
* 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
* 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
* 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
*
#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;
/************************** 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,
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 {
/************************ 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. */
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;
}
/* 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,
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)
/* 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)
{
/* 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;
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)
* 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,
* 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,
*
***/
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,
*
* 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);
*
* 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);
*
* 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
struct SilcSocketStreamStruct {
const SilcStreamOps *ops;
SilcSchedule schedule;
- int sock;
+ SilcSocket sock;
char *hostname;
char *ip;
SilcUInt16 port;
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 */
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
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. */
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
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
{
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);
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)
{
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);
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;
}
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)
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 \
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;
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
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);
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)
+++ /dev/null
-#
-# 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
+++ /dev/null
-/*
-
- 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;
-}
+++ /dev/null
-/*
-
- 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
-}
+++ /dev/null
-/*
-
- 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);
-}
--- /dev/null
+/*\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
--- /dev/null
+/*\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
--- /dev/null
+\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
--- /dev/null
+/*\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
--- /dev/null
+/*\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
--- /dev/null
+/*\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
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);
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);
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 */
}
/* 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;
SilcSocketStreamStatus stream_status;
SilcStream stream;
SilcFSMStruct fsm;
- SilcFSMEventStruct sema;
+ SilcFSMEventStruct event;
SilcAsyncOperation op;
SilcAsyncOperation sop;
char *local_ip;
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);
}
/** 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;
}
/* 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;
}
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;
}
/* 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
#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. */
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);
+ }
+}
}
-/**************************** SILC Cond API ******************************/
+/****************************** SILC Cond API *******************************/
/* SILC Conditional Variable context */
struct SilcCondStruct {
--- /dev/null
+/* 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 */
--- /dev/null
+/*
+ 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 */
*/
-#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;