From: Pekka Riikonen Date: Tue, 2 Jan 2007 10:10:00 +0000 (+0000) Subject: silc_snprintf name fixes. X-Git-Tag: silc.client.1.1.beta1~76 X-Git-Url: http://git.silcnet.org/gitweb/?p=silc.git;a=commitdiff_plain;h=89e862e5385cdd697feaec6c008e30b599890e4d silc_snprintf name fixes. --- diff --git a/README.SYMBIAN b/README.SYMBIAN index 664730db..6093a905 100644 --- a/README.SYMBIAN +++ b/README.SYMBIAN @@ -2,9 +2,9 @@ Compiling SILC Toolkit for Symbian OS ===================================== The SILC Toolkit works on Symbian OS. This document is intended for those -that want to compile the SILC Toolkit by itself for Symbian OS, or for +that want to compile the SILC Toolkit by themselves for Symbian OS, or for Symbian OS emulator. The building environment expects Carbide.c++ and -WINCW compiler for emulator target and GCCE (variant of GCC) for device +WINSCW compiler for emulator target and GCCE (variant of GCC) for device target. The SILC Toolkit has not been tested with other compilers or build systems. The build environment expects MS Windows. diff --git a/lib/silccrypt/silcpkcs1_i.h b/lib/silccrypt/silcpkcs1_i.h index 6c050491..40899e06 100644 --- a/lib/silccrypt/silcpkcs1_i.h +++ b/lib/silccrypt/silcpkcs1_i.h @@ -45,7 +45,8 @@ SilcBool silc_pkcs1_encrypt(void *public_key, SilcUInt32 src_len, unsigned char *dst, SilcUInt32 dst_size, - SilcUInt32 *ret_dst_len); + SilcUInt32 *ret_dst_len, + SilcRng rng); SilcBool silc_pkcs1_decrypt(void *private_key, unsigned char *src, SilcUInt32 src_len, diff --git a/lib/silcutil/silcfsm.c b/lib/silcutil/silcfsm.c index 9ba6466f..2219ed54 100644 --- a/lib/silcutil/silcfsm.c +++ b/lib/silcutil/silcfsm.c @@ -407,9 +407,9 @@ SILC_TASK_CALLBACK(silc_fsm_run) SILC_LOG_DEBUG(("Running %s %p", fsm->thread ? "thread" : "FSM", fsm)); /* Run the states */ -// do + do status = fsm->next_state(fsm, fsm->fsm_context, fsm->state_context); -// while (status == SILC_FSM_CONTINUE); + while (status == SILC_FSM_ST_CONTINUE); switch (status) { case SILC_FSM_ST_YIELD: diff --git a/lib/silcutil/silcfsm.h b/lib/silcutil/silcfsm.h index 8a28360b..29ec9016 100644 --- a/lib/silcutil/silcfsm.h +++ b/lib/silcutil/silcfsm.h @@ -133,8 +133,12 @@ typedef struct SilcFSMObject SilcFSMThreadStruct; * } * ***/ +#ifndef SILC_FSM_SMALL_STACK #define SILC_FSM_CONTINUE \ return fsm->next_state(fsm, fsm->fsm_context, fsm->state_context); +#else +#define SILC_FSM_CONTINUE return SILC_FSM_ST_CONTINUE; +#endif /* SILC_FSM_SMALL_STACK */ /****d* silcutil/SilcFSMAPI/SILC_FSM_YIELD * diff --git a/lib/silcutil/silclog.c b/lib/silcutil/silclog.c index 9deff33a..4369830b 100644 --- a/lib/silcutil/silclog.c +++ b/lib/silcutil/silclog.c @@ -112,7 +112,7 @@ static void silc_log_checksize(SilcLog log) fclose(log->fp); memset(newname, 0, sizeof(newname)); - silc_silc_snprintf(newname, sizeof(newname) - 1, "%s.old", log->filename); + silc_snprintf(newname, sizeof(newname) - 1, "%s.old", log->filename); unlink(newname); rename(log->filename, newname); diff --git a/lib/silcutil/silcmime.c b/lib/silcutil/silcmime.c index 14fde956..e424d5d3 100644 --- a/lib/silcutil/silcmime.c +++ b/lib/silcutil/silcmime.c @@ -229,10 +229,10 @@ SilcMime silc_mime_decode(SilcMime mime, const unsigned char *data, line = strdup(value); if (strrchr(line, '"')) { *strrchr(line, '"') = '\0'; - silc_silc_snprintf(b, sizeof(b) - 1, "--%s", line + 1); + silc_snprintf(b, sizeof(b) - 1, "--%s", line + 1); mime->boundary = strdup(line + 1); } else { - silc_silc_snprintf(b, sizeof(b) - 1, "--%s", line); + silc_snprintf(b, sizeof(b) - 1, "--%s", line); mime->boundary = strdup(line); } silc_free(line); @@ -325,7 +325,7 @@ unsigned char *silc_mime_encode(SilcMime mime, SilcUInt32 *encoded_len) while (silc_hash_table_get(&htl, (void **)&field, (void **)&value)) { memset(tmp, 0, sizeof(tmp)); SILC_LOG_DEBUG(("Header %s: %s", field, value)); - silc_silc_snprintf(tmp, sizeof(tmp) - 1, "%s: %s\r\n", field, value); + silc_snprintf(tmp, sizeof(tmp) - 1, "%s: %s\r\n", field, value); silc_buffer_strformat(&buf, tmp, SILC_STRFMT_END); i++; } @@ -370,8 +370,8 @@ unsigned char *silc_mime_encode(SilcMime mime, SilcUInt32 *encoded_len) /* If fields are not present, add extra CRLF */ if (!silc_hash_table_count(part->fields)) - silc_silc_snprintf(tmp2, sizeof(tmp2) - 1, "\r\n"); - silc_silc_snprintf(tmp, sizeof(tmp) - 1, "%s--%s\r\n%s", + silc_snprintf(tmp2, sizeof(tmp2) - 1, "\r\n"); + silc_snprintf(tmp, sizeof(tmp) - 1, "%s--%s\r\n%s", i != 0 ? "\r\n" : "", mime->boundary, tmp2); i = 1; @@ -387,7 +387,7 @@ unsigned char *silc_mime_encode(SilcMime mime, SilcUInt32 *encoded_len) } memset(tmp, 0, sizeof(tmp)); - silc_silc_snprintf(tmp, sizeof(tmp) - 1, "\r\n--%s--\r\n", mime->boundary); + silc_snprintf(tmp, sizeof(tmp) - 1, "\r\n--%s--\r\n", mime->boundary); buffer = silc_buffer_realloc(buffer, silc_buffer_truelen(buffer) + strlen(tmp)); if (!buffer) @@ -578,7 +578,7 @@ SilcDList silc_mime_encode_partial(SilcMime mime, int max_size) memset(type, 0, sizeof(type)); gethostname(type, sizeof(type) - 1); srand((time(NULL) + buf_len) ^ rand()); - silc_silc_snprintf(id, sizeof(id) - 1, "%X%X%X%s", + silc_snprintf(id, sizeof(id) - 1, "%X%X%X%s", (unsigned int)rand(), (unsigned int)time(NULL), (unsigned int)buf_len, type); @@ -590,7 +590,7 @@ SilcDList silc_mime_encode_partial(SilcMime mime, int max_size) silc_mime_add_field(partial, "MIME-Version", "1.0"); memset(type, 0, sizeof(type)); - silc_silc_snprintf(type, sizeof(type) - 1, + silc_snprintf(type, sizeof(type) - 1, "message/partial; id=\"%s\"; number=1", id); silc_mime_add_field(partial, "Content-Type", type); silc_mime_add_data(partial, buf, max_size); @@ -620,14 +620,14 @@ SilcDList silc_mime_encode_partial(SilcMime mime, int max_size) silc_mime_add_field(partial, "MIME-Version", "1.0"); if (len > max_size) { - silc_silc_snprintf(type, sizeof(type) - 1, + silc_snprintf(type, sizeof(type) - 1, "message/partial; id=\"%s\"; number=%d", id, num++); silc_mime_add_data(partial, buf + off, max_size); off += max_size; len -= max_size; } else { - silc_silc_snprintf(type, sizeof(type) - 1, + silc_snprintf(type, sizeof(type) - 1, "message/partial; id=\"%s\"; number=%d; total=%d", id, num, num); silc_mime_add_data(partial, buf + off, len); @@ -777,7 +777,7 @@ void silc_mime_set_multipart(SilcMime mime, const char *type, return; memset(tmp, 0, sizeof(tmp)); - silc_silc_snprintf(tmp, sizeof(tmp) - 1, "multipart/%s; boundary=%s", type, boundary); + silc_snprintf(tmp, sizeof(tmp) - 1, "multipart/%s; boundary=%s", type, boundary); silc_mime_add_field(mime, "Content-Type", tmp); silc_free(mime->boundary); mime->boundary = strdup(boundary); diff --git a/lib/silcutil/silctime.c b/lib/silcutil/silctime.c index b2f84c3c..52c356fd 100644 --- a/lib/silcutil/silctime.c +++ b/lib/silcutil/silctime.c @@ -209,7 +209,7 @@ SilcBool silc_time_universal_string(SilcTime time_val, char *ret_string, { int ret, len = 0; memset(ret_string, 0, ret_string_size); - ret = silc_silc_snprintf(ret_string, ret_string_size - 1, + ret = silc_snprintf(ret_string, ret_string_size - 1, "%02u%02u%02u%02u%02u%02u", time_val->year % 100, time_val->month, time_val->day, time_val->hour, time_val->minute, time_val->second); @@ -218,12 +218,12 @@ SilcBool silc_time_universal_string(SilcTime time_val, char *ret_string, len += ret; if (!time_val->utc_hour && !time_val->utc_minute) { - ret = silc_silc_snprintf(ret_string + len, ret_string_size - 1 - len, "Z"); + ret = silc_snprintf(ret_string + len, ret_string_size - 1 - len, "Z"); if (ret < 0) return FALSE; len += ret; } else { - ret = silc_silc_snprintf(ret_string + len, ret_string_size - 1 - len, + ret = silc_snprintf(ret_string + len, ret_string_size - 1 - len, "%c%02u%02u", time_val->utc_east ? '+' : '-', time_val->utc_hour, time_val->utc_minute); if (ret < 0) @@ -319,7 +319,7 @@ SilcBool silc_time_generalized_string(SilcTime time_val, char *ret_string, { int len = 0, ret; memset(ret_string, 0, ret_string_size); - ret = silc_silc_snprintf(ret_string, ret_string_size - 1, + ret = silc_snprintf(ret_string, ret_string_size - 1, "%04u%02u%02u%02u%02u%02u", time_val->year, time_val->month, time_val->day, time_val->hour, time_val->minute, time_val->second); @@ -328,7 +328,7 @@ SilcBool silc_time_generalized_string(SilcTime time_val, char *ret_string, len += ret; if (time_val->msecond) { - ret = silc_silc_snprintf(ret_string + len, ret_string_size - 1 - len, + ret = silc_snprintf(ret_string + len, ret_string_size - 1 - len, ".%lu", (unsigned long)time_val->msecond); if (ret < 0) return FALSE; @@ -336,12 +336,12 @@ SilcBool silc_time_generalized_string(SilcTime time_val, char *ret_string, } if (!time_val->utc_hour && !time_val->utc_minute) { - ret = silc_silc_snprintf(ret_string + len, ret_string_size - 1 - len, "Z"); + ret = silc_snprintf(ret_string + len, ret_string_size - 1 - len, "Z"); if (ret < 0) return FALSE; len += ret; } else { - ret = silc_silc_snprintf(ret_string + len, ret_string_size - 1 - len, + ret = silc_snprintf(ret_string + len, ret_string_size - 1 - len, "%c%02u%02u", time_val->utc_east ? '+' : '-', time_val->utc_hour, time_val->utc_minute); if (ret < 0) diff --git a/lib/silcutil/silctime.h b/lib/silcutil/silctime.h index c7494baf..a57830f6 100644 --- a/lib/silcutil/silctime.h +++ b/lib/silcutil/silctime.h @@ -4,7 +4,7 @@ Author: Pekka Riikonen - Copyright (C) 2003 - 2006 Pekka Riikonen + Copyright (C) 2003 - 2007 Pekka Riikonen This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -105,34 +105,34 @@ SilcInt64 silc_time_usec(void); * * SYNOPSIS * - * const char *silc_time_string(SilcInt64 time_val); + * const char *silc_time_string(SilcInt64 time_val_sec); * * DESCRIPTION * * Returns time and date as string. The caller must not free the string * and next call to this function will delete the old string. If the - * `time_val' is zero (0) returns current time as string, otherwise the - * `time_val' as string. The `time_val' is in seconds since Epoch. + * `time_val_sec' is zero (0) returns current time as string, otherwise the + * `time_val_sec' as string. The `time_val_sec' is in seconds since Epoch. * Returns NULL on error. * ***/ -const char *silc_time_string(SilcInt64 time_val); +const char *silc_time_string(SilcInt64 time_val_sec); /****f* silcutil/SilcTimeAPI/silc_time_value * * SYNOPSIS * - * SilcBool silc_time_value(SilcInt64 time_val, SilcTime ret_time); + * SilcBool silc_time_value(SilcInt64 time_val_msec, SilcTime ret_time); * * DESCRIPTION * - * Returns time and date as SilcTime. If the `time_val' is zero (0) - * returns current time as SilcTime, otherwise the `time_val' as SilcTime. - * The `time_val' is in milliseconds since Epoch. Returns FALSE on error, - * TRUE otherwise. + * Returns time and date as SilcTime. If the `time_val_msec' is zero (0) + * returns current time as SilcTime, otherwise the `time_val_msec' as + * SilcTime. The `time_val_msec' is in milliseconds since Epoch. Returns + * FALSE on error, TRUE otherwise. * ***/ -SilcBool silc_time_value(SilcInt64 time_val, SilcTime ret_time); +SilcBool silc_time_value(SilcInt64 time_val_msec, SilcTime ret_time); /****f* silcutil/SilcTimeAPI/silc_time_universal * diff --git a/lib/silcutil/silcutf8.c b/lib/silcutil/silcutf8.c index 29f74dc3..65254eb5 100644 --- a/lib/silcutil/silcutf8.c +++ b/lib/silcutil/silcutf8.c @@ -491,7 +491,7 @@ SilcUInt32 silc_utf8_decode(const unsigned char *utf8, SilcUInt32 utf8_len, if (enclen + 3 > bin_size) return 0; bin[enclen] = '\\'; - silc_silc_snprintf(bin + enclen + 1, 3, "%02X", cv); + silc_snprintf(bin + enclen + 1, 3, "%02X", cv); } enclen += 3; continue; diff --git a/lib/silcutil/silcutil.c b/lib/silcutil/silcutil.c index 04b10363..5fd5de84 100644 --- a/lib/silcutil/silcutil.c +++ b/lib/silcutil/silcutil.c @@ -236,7 +236,7 @@ char *silc_format(char *fmt, ...) memset(buf, 0, sizeof(buf)); va_start(args, fmt); - vsilc_snprintf(buf, sizeof(buf) - 1, fmt, args); + vsnprintf(buf, sizeof(buf) - 1, fmt, args); va_end(args); return strdup(buf); @@ -473,14 +473,14 @@ char *silc_fingerprint(const unsigned char *data, SilcUInt32 data_len) memset(fingerprint, 0, sizeof(fingerprint)); cp = fingerprint; for (i = 0; i < data_len; i++) { - silc_silc_snprintf(cp, sizeof(fingerprint), "%02X", data[i]); + silc_snprintf(cp, sizeof(fingerprint), "%02X", data[i]); cp += 2; if ((i + 1) % 2 == 0) - silc_silc_snprintf(cp++, sizeof(fingerprint), " "); + silc_snprintf(cp++, sizeof(fingerprint), " "); if ((i + 1) % 10 == 0) - silc_silc_snprintf(cp++, sizeof(fingerprint), " "); + silc_snprintf(cp++, sizeof(fingerprint), " "); } i--; if ((i + 1) % 2 == 0) diff --git a/lib/silcutil/symbian/silcsymbiannet.cpp b/lib/silcutil/symbian/silcsymbiannet.cpp index f2ae993d..6cc8d736 100644 --- a/lib/silcutil/symbian/silcsymbiannet.cpp +++ b/lib/silcutil/symbian/silcsymbiannet.cpp @@ -1,744 +1,757 @@ -/* - - silcsymbiannet.cpp - - Author: Pekka Riikonen - - Copyright (C) 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. - -*/ - -#include "silc.h" -#include "silcsymbiansocketstream.h" - -/****************************** TCP Listener ********************************/ - -class SilcSymbianTCPListener; - -/* Deliver new stream to upper layer */ - -static void silc_net_accept_stream(SilcSocketStreamStatus status, - SilcStream stream, void *context) -{ - SilcNetListener listener = (SilcNetListener)context; - - /* In case of error, the socket has been destroyed already */ - if (status != SILC_SOCKET_OK) - return; - - listener->callback(SILC_NET_OK, stream, listener->context); -} - -/* TCP Listener class */ - -class SilcSymbianTCPListener : public CActive { -public: - /* Constructor */ - SilcSymbianTCPListener() : CActive(CActive::EPriorityStandard) - { - CActiveScheduler::Add(this); - } - - /* Destructor */ - ~SilcSymbianTCPListener() - { - Cancel(); - } - - /* Listen for connection */ - void Listen() - { - new_conn = new RSocket; - if (!new_conn) - return; - User::LeaveIfError(new_conn->Open(ss)); - - /* Start listenning */ - sock.Accept(*new_conn, iStatus); - SetActive(); - } - - /* Listener callback */ - void RunL() - { - if (iStatus != KErrNone) { - if (new_conn) - delete new_conn; - new_conn = NULL; - Listen(); - return; - } - - /* Set socket options */ - new_conn->SetOpt(KSoReuseAddr, KSolInetIp, 1); - - /* Create socket stream */ - silc_socket_tcp_stream_create( - (SilcSocket)silc_create_symbian_socket(new_conn, NULL), - listener->lookup, listener->require_fqdn, - listener->schedule, silc_net_accept_stream, - (void *)listener); - - /* Continue listenning */ - Listen(); - } - - /* Cancel */ - void DoCancel() - { - sock.CancelAll(); - ss.Close(); - if (new_conn) - delete new_conn; - } - - RSocket *new_conn; - RSocket sock; - RSocketServ ss; - SilcNetListener listener; -}; - -/* Create TCP listener */ - -SilcNetListener -silc_net_tcp_create_listener(const char **local_ip_addr, - SilcUInt32 local_ip_count, int port, - SilcBool lookup, SilcBool require_fqdn, - SilcSchedule schedule, - SilcNetCallback callback, void *context) -{ - SilcNetListener listener = NULL; - SilcSymbianTCPListener *l = NULL; - TInetAddr server; - TInt ret; - TBuf<64> tmp; - int i; - - SILC_LOG_DEBUG(("Creating TCP listener")); - - if (port < 0 || !schedule || !callback) - goto err; - - listener = (SilcNetListener)silc_calloc(1, sizeof(*listener)); - if (!listener) { - callback(SILC_NET_NO_MEMORY, NULL, context); - return NULL; - } - listener->schedule = schedule; - listener->callback = callback; - listener->context = context; - listener->require_fqdn = require_fqdn; - listener->lookup = lookup; - - if (local_ip_count > 0) { - listener->socks = (SilcSocket *)silc_calloc(local_ip_count, - sizeof(*listener->socks)); - if (!listener->socks) { - callback(SILC_NET_NO_MEMORY, NULL, context); - return NULL; - } - } else { - listener->socks = (SilcSocket *)silc_calloc(1, sizeof(*listener->socks)); - if (!listener->socks) { - callback(SILC_NET_NO_MEMORY, NULL, context); - return NULL; - } - - local_ip_count = 1; - } - - /* Bind to local addresses */ - for (i = 0; i < local_ip_count; i++) { - SILC_LOG_DEBUG(("Binding to local address %s", - local_ip_addr ? local_ip_addr[i] : "0.0.0.0")); - - l = new SilcSymbianTCPListener; - if (!l) - goto err; - - /* Connect to socket server */ - ret = l->ss.Connect(); - if (ret != KErrNone) - goto err; - - /* Set listener address */ - if (local_ip_addr) { - server = TInetAddr(port); - tmp = (TText *)local_ip_addr[i]; - ret = server.Input(tmp); - if (ret != KErrNone) - goto err; - } else { - server = TInetAddr(KInetAddrAny, port); - } - - /* Create the socket */ - ret = l->sock.Open(l->ss, KAfInet, KSockStream, KProtocolInetTcp); - if (ret != KErrNone) { - SILC_LOG_ERROR(("Cannot create socket")); - goto err; - } - - /* Set the socket options */ - ret = l->sock.SetOpt(KSoReuseAddr, KSolInetIp, 1); - if (ret != KErrNone) { - SILC_LOG_ERROR(("Cannot set socket options")); - goto err; - } - - /* Bind the listener socket */ - ret = l->sock.Bind(server); - if (ret != KErrNone) { - SILC_LOG_DEBUG(("Cannot bind socket")); - goto err; - } - - /* Specify that we are listenning */ - ret = l->sock.Listen(5); - if (ret != KErrNone) { - SILC_LOG_ERROR(("Cannot set socket listenning")); - goto err; - } - l->Listen(); - - l->listener = listener; - listener->socks[i] = (SilcSocket)l; - listener->socks_count++; - } - - SILC_LOG_DEBUG(("TCP listener created")); - - return listener; - - err: - if (l) - delete l; - if (callback) - callback(SILC_NET_ERROR, NULL, context); - if (listener) - silc_net_close_listener(listener); - return NULL; -} - -/* Close network listener */ - -void silc_net_close_listener(SilcNetListener listener) -{ - int i; - - SILC_LOG_DEBUG(("Closing network listener")); - - for (i = 0; i < listener->socks_count; i++) { - SilcSymbianTCPListener *l = (SilcSymbianTCPListener *)listener->socks[i]; - l->sock.CancelAll(); - l->sock.Close(); - l->ss.Close(); - if (l->new_conn) - delete l->new_conn; - delete l; - } - - silc_free(listener->socks); - silc_free(listener); -} - -/**************************** TCP/IP connecting *****************************/ - -static void silc_net_connect_stream(SilcSocketStreamStatus status, - SilcStream stream, void *context); - -/* TCP connecting class */ - -class SilcSymbianTCPConnect : public CActive { -public: - /* Constructor */ - SilcSymbianTCPConnect() : CActive(CActive::EPriorityStandard) - { - CActiveScheduler::Add(this); - } - - /* Destructor */ - ~SilcSymbianTCPConnect() - { - silc_free(remote); - if (op) - silc_async_free(op); - Cancel(); - } - - /* Connect to remote host */ - void Connect(TSockAddr &addr) - { - sock->Connect(addr, iStatus); - SetActive(); - } - - /* Connection callback */ - void RunL() - { - if (iStatus != KErrNone) { - if (callback) - callback(SILC_NET_ERROR, NULL, context); - sock->CancelConnect(); - delete sock; - ss->Close(); - delete ss; - delete this; - } - - /* Create stream */ - if (callback) { - silc_socket_tcp_stream_create( - (SilcSocket)silc_create_symbian_socket(sock, ss), - FALSE, FALSE, schedule, silc_net_connect_stream, - (void *)this); - } else { - sock->Close(); - delete sock; - ss->Close(); - delete ss; - } - - delete this; - } - - /* Cancel */ - void DoCancel() - { - sock->CancelConnect(); - ss->Close(); - delete ss; - delete sock; - delete this; - } - - RSocket *sock; - RSocketServ *ss; - char *remote; - char remote_ip[64]; - int port; - SilcAsyncOperation op; - SilcSchedule schedule; - SilcNetCallback callback; - void *context; -}; - -/* Stream creation callback */ - -static void silc_net_connect_stream(SilcSocketStreamStatus status, - SilcStream stream, void *context) -{ - SilcSymbianTCPConnect *conn = (SilcSymbianTCPConnect *)context; - SilcNetStatus net_status = SILC_NET_OK; - - if (status != SILC_SOCKET_OK) { - /* In case of error, the socket has been destroyed already */ - if (status == SILC_SOCKET_UNKNOWN_IP) - net_status = SILC_NET_UNKNOWN_IP; - else if (status == SILC_SOCKET_UNKNOWN_HOST) - net_status = SILC_NET_UNKNOWN_HOST; - else - net_status = SILC_NET_ERROR; - } - - /* Set stream information */ - if (stream && conn->callback) - silc_socket_stream_set_info(stream, - !silc_net_is_ip(conn->remote) ? conn->remote : - conn->remote_ip, conn->remote_ip, conn->port); - - /* Call connection callback */ - if (conn->callback) - conn->callback(net_status, stream, conn->context); - else if (stream) - silc_stream_destroy(stream); - - delete conn; -} - -/* Connecting abort callback */ - -static void silc_net_connect_abort(SilcAsyncOperation op, void *context) -{ - SilcSymbianTCPConnect *conn = (SilcSymbianTCPConnect *)context; - - /* Abort */ - conn->callback = NULL; - conn->op = NULL; - conn->DoCancel(); -} - -/* Create TCP/IP connection */ - -SilcAsyncOperation silc_net_tcp_connect(const char *local_ip_addr, - const char *remote_ip_addr, - int remote_port, - SilcSchedule schedule, - SilcNetCallback callback, - void *context) -{ - SilcSymbianTCPConnect *conn; - TInetAddr local, remote; - SilcNetStatus status; - TBuf<64> tmp; - TInt ret; - - if (!remote_ip_addr || remote_port < 1 || !schedule || !callback) - return NULL; - - SILC_LOG_DEBUG(("Creating connection to host %s port %d", - remote_ip_addr, remote_port)); - - conn = new SilcSymbianTCPConnect; - if (!conn) { - callback(SILC_NET_NO_MEMORY, NULL, context); - return NULL; - } - conn->schedule = schedule; - conn->callback = callback; - conn->context = context; - conn->port = remote_port; - conn->remote = strdup(remote_ip_addr); - if (!conn->remote) { - status = SILC_NET_NO_MEMORY; - goto err; - } - - /* Allocate socket */ - conn->sock = new RSocket; - if (!conn->sock) { - status = SILC_NET_NO_MEMORY; - goto err; - } - - /* Allocate socket server */ - conn->ss = new RSocketServ; - if (!conn->ss) { - status = SILC_NET_NO_MEMORY; - goto err; - } - - /* Connect to socket server */ - ret = conn->ss->Connect(); - if (ret != KErrNone) { - status = SILC_NET_ERROR; - goto err; - } - - /* Start async operation */ - conn->op = silc_async_alloc(silc_net_connect_abort, NULL, (void *)conn); - if (!conn->op) { - status = SILC_NET_NO_MEMORY; - goto err; - } - - /* Do host lookup */ - if (!silc_net_is_ip(remote_ip_addr)) { - if (!silc_net_gethostbyname(remote_ip_addr, FALSE, conn->remote_ip, - sizeof(conn->remote_ip))) { - SILC_LOG_ERROR(("Network (%s) unreachable: could not resolve the " - "host", conn->remote)); - status = SILC_NET_HOST_UNREACHABLE; - goto err; - } - } else { - strcpy(conn->remote_ip, remote_ip_addr); - } - - /* Create the connection socket */ - ret = conn->sock->Open(*conn->ss, KAfInet, KSockStream, KProtocolInetTcp); - if (ret != KErrNone) { - SILC_LOG_ERROR(("Cannot create socket")); - status = SILC_NET_ERROR; - goto err; - } - - /* Set appropriate options */ - conn->sock->SetOpt(KSoTcpNoDelay, KSolInetTcp, 1); - conn->sock->SetOpt(KSoTcpKeepAlive, KSolInetTcp, 1); - - /* Bind to the local address if provided */ - if (local_ip_addr) { - local = TInetAddr(0); - tmp = (TText *)local_ip_addr; - ret = local.Input(tmp); - if (ret == KErrNone) - ret = conn->sock->Bind(local); - } - - /* Connect to the host */ - remote = TInetAddr(remote_port); - tmp = (TText *)conn->remote_ip; - ret = remote.Input(tmp); - if (ret != KErrNone) { - SILC_LOG_ERROR(("Cannot connect (cannot set address)")); - status = SILC_NET_ERROR; - goto err; - } - conn->Connect(remote); - - SILC_LOG_DEBUG(("Connection operation in progress")); - - return conn->op; - - err: - if (conn->ss) { - conn->ss->Close(); - delete conn->ss; - } - if (conn->sock) - delete conn->sock; - if (conn->remote) - silc_free(conn->remote); - if (conn->op) - silc_async_free(conn->op); - callback(status, NULL, context); - delete conn; - return NULL; -} - -/****************************** UDP routines ********************************/ - -/* Create UDP/IP connection */ - -SilcStream silc_net_udp_connect(const char *local_ip_addr, int local_port, - const char *remote_ip_addr, int remote_port, - SilcSchedule schedule) -{ - SilcSymbianSocket *s; - SilcStream stream; - TInetAddr local, remote; - TRequestStatus status; - RSocket *sock = NULL; - RSocketServ *ss = NULL; - TBuf<64> tmp; - TInt ret; - - SILC_LOG_DEBUG(("Creating UDP stream")); - - if (!schedule) - goto err; - - SILC_LOG_DEBUG(("Binding to local address %s", - local_ip_addr ? local_ip_addr : "0.0.0.0")); - - sock = new RSocket; - if (!sock) - goto err; - - ss = new RSocketServ; - if (!ss) - goto err; - - /* Open socket server */ - ret = ss->Connect(); - if (ret != KErrNone) - goto err; - - /* Get local bind address */ - if (local_ip_addr) { - local = TInetAddr(local_port); - tmp = (TText *)local_ip_addr; - ret = local.Input(tmp); - if (ret != KErrNone) - goto err; - } else { - local = TInetAddr(KInetAddrAny, local_port); - } - - /* Create the socket */ - ret = sock->Open(*ss, KAfInet, KSockDatagram, KProtocolInetUdp); - if (ret != KErrNone) { - SILC_LOG_ERROR(("Cannot create socket")); - goto err; - } - - /* Set the socket options */ - sock->SetOpt(KSoReuseAddr, KSolInetIp, 1); - - /* Bind the listener socket */ - ret = sock->Bind(local); - if (ret != KErrNone) { - SILC_LOG_DEBUG(("Cannot bind socket")); - goto err; - } - - /* Set to connected state if remote address is provided. */ - if (remote_ip_addr && remote_port) { - remote = TInetAddr(remote_port); - tmp = (TText *)remote_ip_addr; - ret = remote.Input(tmp); - if (ret != KErrNone) - goto err; - - sock->Connect(remote, status); - if (status != KErrNone) { - SILC_LOG_DEBUG(("Cannot connect UDP stream")); - goto err; - } - } - - /* Encapsulate into socket stream */ - s = silc_create_symbian_socket(sock, ss); - if (!s) - goto err; - stream = - silc_socket_udp_stream_create((SilcSocket)s, local_ip_addr ? - silc_net_is_ip6(local_ip_addr) : FALSE, - remote_ip_addr ? TRUE : FALSE, schedule); - if (!stream) - goto err; - - SILC_LOG_DEBUG(("UDP stream created, fd=%d", sock)); - return stream; - - err: - if (sock) - delete sock; - if (ss) { - ss->Close(); - delete ss; - } - return NULL; -} - -/* Sets socket to non-blocking mode */ - -int silc_net_set_socket_nonblock(SilcSocket sock) -{ - /* Nothing to do in Symbian where blocking socket mode is asynchronous - already (ie. non-blocking). */ - return 0; -} - -/* Converts the IP number string from numbers-and-dots notation to - binary form. */ - -SilcBool silc_net_addr2bin(const char *addr, void *bin, SilcUInt32 bin_len) -{ - int ret = 0; - - struct in_addr tmp; - ret = inet_aton(addr, &tmp); - if (bin_len < 4) - return FALSE; - - memcpy(bin, (unsigned char *)&tmp.s_addr, 4); - - return ret != 0; -} - -/* Get remote host and IP from socket */ - -SilcBool silc_net_check_host_by_sock(SilcSocket sock, char **hostname, - char **ip) -{ - SilcSymbianSocket *s = (SilcSymbianSocket *)sock; - TInetAddr addr; - char host[256]; - TBuf<64> tmp; - - if (hostname) - *hostname = NULL; - *ip = NULL; - - s->sock->RemoteName(addr); - addr.Output(tmp); - - *ip = (char *)silc_memdup(tmp.Ptr(), tmp.Length()); - if (*ip == NULL) - return FALSE; - - /* Do reverse lookup if we want hostname too. */ - if (hostname) { - /* Get host by address */ - if (!silc_net_gethostbyaddr(*ip, host, sizeof(host))) - return FALSE; - - *hostname = (char *)silc_memdup(host, strlen(host)); - SILC_LOG_DEBUG(("Resolved hostname `%s'", *hostname)); - - /* Reverse */ - if (!silc_net_gethostbyname(*hostname, TRUE, host, sizeof(host))) - return FALSE; - - if (strcmp(*ip, host)) - return FALSE; - } - - SILC_LOG_DEBUG(("Resolved IP address `%s'", *ip)); - return TRUE; -} - -/* Get local host and IP from socket */ - -SilcBool silc_net_check_local_by_sock(SilcSocket sock, char **hostname, - char **ip) -{ - SilcSymbianSocket *s = (SilcSymbianSocket *)sock; - TInetAddr addr; - char host[256]; - TBuf<64> tmp; - - if (hostname) - *hostname = NULL; - *ip = NULL; - - s->sock->LocalName(addr); - addr.Output(tmp); - - *ip = (char *)silc_memdup(tmp.Ptr(), tmp.Length()); - if (*ip == NULL) - return FALSE; - - /* Do reverse lookup if we want hostname too. */ - if (hostname) { - /* Get host by address */ - if (!silc_net_gethostbyaddr(*ip, host, sizeof(host))) - return FALSE; - - *hostname = (char *)silc_memdup(host, strlen(host)); - SILC_LOG_DEBUG(("Resolved hostname `%s'", *hostname)); - - /* Reverse */ - if (!silc_net_gethostbyname(*hostname, TRUE, host, sizeof(host))) - return FALSE; - - if (strcmp(*ip, host)) - return FALSE; - } - - SILC_LOG_DEBUG(("Resolved IP address `%s'", *ip)); - return TRUE; -} - -/* Get remote port from socket */ - -SilcUInt16 silc_net_get_remote_port(SilcSocket sock) -{ - SilcSymbianSocket *s = (SilcSymbianSocket *)sock; - TInetAddr addr; - - s->sock->RemoteName(addr); - return (SilcUInt16)addr.Port(); -} - -/* Get local port from socket */ - -SilcUInt16 silc_net_get_local_port(SilcSocket sock) -{ - SilcSymbianSocket *s = (SilcSymbianSocket *)sock; - TInetAddr addr; - - s->sock->LocalName(addr); - return (SilcUInt16)addr.Port(); -} +/* + + silcsymbiannet.cpp + + Author: Pekka Riikonen + + Copyright (C) 2006 - 2007 Pekka Riikonen + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + +*/ + +#include "silc.h" +#include "silcsymbiansocketstream.h" + +/****************************** TCP Listener ********************************/ + +class SilcSymbianTCPListener; + +/* Deliver new stream to upper layer */ + +static void silc_net_accept_stream(SilcSocketStreamStatus status, + SilcStream stream, void *context) +{ + SilcNetListener listener = (SilcNetListener)context; + + /* In case of error, the socket has been destroyed already */ + if (status != SILC_SOCKET_OK) + return; + + listener->callback(SILC_NET_OK, stream, listener->context); +} + +/* TCP Listener class */ + +class SilcSymbianTCPListener : public CActive { +public: + /* Constructor */ + SilcSymbianTCPListener() : CActive(CActive::EPriorityStandard) + { + CActiveScheduler::Add(this); + } + + /* Destructor */ + ~SilcSymbianTCPListener() + { + Cancel(); + } + + /* Listen for connection */ + void Listen() + { + new_conn = new RSocket; + if (!new_conn) + return; + if (new_conn->Open(ss) != KErrNone) { + Listen(); + return; + } + + /* Start listenning */ + sock.Accept(*new_conn, iStatus); + SetActive(); + } + + /* Listener callback */ + virtual void RunL() + { + if (iStatus != KErrNone) { + if (new_conn) + delete new_conn; + new_conn = NULL; + Listen(); + return; + } + + /* Set socket options */ + new_conn->SetOpt(KSoReuseAddr, KSolInetIp, 1); + + /* Create socket stream */ + silc_socket_tcp_stream_create( + (SilcSocket)silc_create_symbian_socket(new_conn, NULL), + listener->lookup, listener->require_fqdn, + listener->schedule, silc_net_accept_stream, + (void *)listener); + new_conn = NULL; + + /* Continue listenning */ + Listen(); + } + + /* Cancel */ + virtual void DoCancel() + { + sock.CancelAll(); + ss.Close(); + if (new_conn) + delete new_conn; + } + + RSocket *new_conn; + RSocket sock; + RSocketServ ss; + SilcNetListener listener; +}; + +/* Create TCP listener */ + +SilcNetListener +silc_net_tcp_create_listener(const char **local_ip_addr, + SilcUInt32 local_ip_count, int port, + SilcBool lookup, SilcBool require_fqdn, + SilcSchedule schedule, + SilcNetCallback callback, void *context) +{ + SilcNetListener listener = NULL; + SilcSymbianTCPListener *l = NULL; + TInetAddr server; + TInt ret; + TBuf<64> tmp; + int i; + + SILC_LOG_DEBUG(("Creating TCP listener")); + + if (port < 0 || !schedule || !callback) + goto err; + + listener = (SilcNetListener)silc_calloc(1, sizeof(*listener)); + if (!listener) { + callback(SILC_NET_NO_MEMORY, NULL, context); + return NULL; + } + listener->schedule = schedule; + listener->callback = callback; + listener->context = context; + listener->require_fqdn = require_fqdn; + listener->lookup = lookup; + + if (local_ip_count > 0) { + listener->socks = (SilcSocket *)silc_calloc(local_ip_count, + sizeof(*listener->socks)); + if (!listener->socks) { + callback(SILC_NET_NO_MEMORY, NULL, context); + return NULL; + } + } else { + listener->socks = (SilcSocket *)silc_calloc(1, sizeof(*listener->socks)); + if (!listener->socks) { + callback(SILC_NET_NO_MEMORY, NULL, context); + return NULL; + } + + local_ip_count = 1; + } + + /* Bind to local addresses */ + for (i = 0; i < local_ip_count; i++) { + SILC_LOG_DEBUG(("Binding to local address %s", + local_ip_addr ? local_ip_addr[i] : "0.0.0.0")); + + l = new SilcSymbianTCPListener; + if (!l) + goto err; + + /* Connect to socket server */ + ret = l->ss.Connect(); + if (ret != KErrNone) + goto err; + + /* Set listener address */ + if (local_ip_addr) { + server = TInetAddr(port); + tmp = (TText *)local_ip_addr[i]; + ret = server.Input(tmp); + if (ret != KErrNone) + goto err; + } else { + server = TInetAddr(KInetAddrAny, port); + } + + /* Create the socket */ + ret = l->sock.Open(l->ss, KAfInet, KSockStream, KProtocolInetTcp); + if (ret != KErrNone) { + SILC_LOG_ERROR(("Cannot create socket")); + goto err; + } + + /* Set the socket options */ + ret = l->sock.SetOpt(KSoReuseAddr, KSolInetIp, 1); + if (ret != KErrNone) { + SILC_LOG_ERROR(("Cannot set socket options")); + goto err; + } + + /* Bind the listener socket */ + ret = l->sock.Bind(server); + if (ret != KErrNone) { + SILC_LOG_DEBUG(("Cannot bind socket")); + goto err; + } + + /* Specify that we are listenning */ + ret = l->sock.Listen(5); + if (ret != KErrNone) { + SILC_LOG_ERROR(("Cannot set socket listenning")); + goto err; + } + l->Listen(); + + l->listener = listener; + listener->socks[i] = (SilcSocket)l; + listener->socks_count++; + } + + SILC_LOG_DEBUG(("TCP listener created")); + + return listener; + + err: + if (l) + delete l; + if (callback) + callback(SILC_NET_ERROR, NULL, context); + if (listener) + silc_net_close_listener(listener); + return NULL; +} + +/* Close network listener */ + +void silc_net_close_listener(SilcNetListener listener) +{ + int i; + + SILC_LOG_DEBUG(("Closing network listener")); + + for (i = 0; i < listener->socks_count; i++) { + SilcSymbianTCPListener *l = (SilcSymbianTCPListener *)listener->socks[i]; + l->sock.CancelAll(); + l->sock.Close(); + l->ss.Close(); + if (l->new_conn) + delete l->new_conn; + delete l; + } + + silc_free(listener->socks); + silc_free(listener); +} + +/**************************** TCP/IP connecting *****************************/ + +static void silc_net_connect_stream(SilcSocketStreamStatus status, + SilcStream stream, void *context); + +/* TCP connecting class */ + +class SilcSymbianTCPConnect : public CActive { +public: + /* Constructor */ + SilcSymbianTCPConnect() : CActive(CActive::EPriorityStandard) + { + CActiveScheduler::Add(this); + } + + /* Destructor */ + ~SilcSymbianTCPConnect() + { + silc_free(remote); + if (op) + silc_async_free(op); + Cancel(); + } + + /* Connect to remote host */ + void Connect(TSockAddr &addr) + { + sock->Connect(addr, iStatus); + SetActive(); + } + + /* Connection callback */ + virtual void RunL() + { + if (iStatus != KErrNone) { + if (callback) + callback(SILC_NET_ERROR, NULL, context); + sock->CancelConnect(); + delete sock; + ss->Close(); + delete ss; + sock = NULL; + ss = NULL; + delete this; + return; + } + + /* Create stream */ + if (callback) { + silc_socket_tcp_stream_create( + (SilcSocket)silc_create_symbian_socket(sock, ss), + FALSE, FALSE, schedule, silc_net_connect_stream, + (void *)this); + } else { + sock->Close(); + delete sock; + ss->Close(); + delete ss; + sock = NULL; + ss = NULL; + } + + delete this; + } + + /* Cancel */ + virtual void DoCancel() + { + if (ss) { + ss->Close(); + delete ss; + } + if (sock) { + sock->CancelConnect(); + delete sock; + } + } + + RSocket *sock; + RSocketServ *ss; + char *remote; + char remote_ip[64]; + int port; + SilcAsyncOperation op; + SilcSchedule schedule; + SilcNetCallback callback; + void *context; +}; + +/* Stream creation callback */ + +static void silc_net_connect_stream(SilcSocketStreamStatus status, + SilcStream stream, void *context) +{ + SilcSymbianTCPConnect *conn = (SilcSymbianTCPConnect *)context; + SilcNetStatus net_status = SILC_NET_OK; + + if (status != SILC_SOCKET_OK) { + /* In case of error, the socket has been destroyed already */ + if (status == SILC_SOCKET_UNKNOWN_IP) + net_status = SILC_NET_UNKNOWN_IP; + else if (status == SILC_SOCKET_UNKNOWN_HOST) + net_status = SILC_NET_UNKNOWN_HOST; + else + net_status = SILC_NET_ERROR; + } + + /* Set stream information */ + if (stream && conn->callback) + silc_socket_stream_set_info(stream, + !silc_net_is_ip(conn->remote) ? conn->remote : + conn->remote_ip, conn->remote_ip, conn->port); + + /* Call connection callback */ + if (conn->callback) + conn->callback(net_status, stream, conn->context); + else if (stream) + silc_stream_destroy(stream); + + delete conn; +} + +/* Connecting abort callback */ + +static void silc_net_connect_abort(SilcAsyncOperation op, void *context) +{ + SilcSymbianTCPConnect *conn = (SilcSymbianTCPConnect *)context; + + /* Abort */ + conn->callback = NULL; + conn->op = NULL; + if (conn->sock) + sock->CancelConnect(); +} + +/* Create TCP/IP connection */ + +SilcAsyncOperation silc_net_tcp_connect(const char *local_ip_addr, + const char *remote_ip_addr, + int remote_port, + SilcSchedule schedule, + SilcNetCallback callback, + void *context) +{ + SilcSymbianTCPConnect *conn; + TInetAddr local, remote; + SilcNetStatus status; + TBuf<64> tmp; + TInt ret; + + if (!remote_ip_addr || remote_port < 1 || !schedule || !callback) + return NULL; + + SILC_LOG_DEBUG(("Creating connection to host %s port %d", + remote_ip_addr, remote_port)); + + conn = new SilcSymbianTCPConnect; + if (!conn) { + callback(SILC_NET_NO_MEMORY, NULL, context); + return NULL; + } + conn->schedule = schedule; + conn->callback = callback; + conn->context = context; + conn->port = remote_port; + conn->remote = strdup(remote_ip_addr); + if (!conn->remote) { + status = SILC_NET_NO_MEMORY; + goto err; + } + + /* Allocate socket */ + conn->sock = new RSocket; + if (!conn->sock) { + status = SILC_NET_NO_MEMORY; + goto err; + } + + /* Allocate socket server */ + conn->ss = new RSocketServ; + if (!conn->ss) { + status = SILC_NET_NO_MEMORY; + goto err; + } + + /* Connect to socket server */ + ret = conn->ss->Connect(); + if (ret != KErrNone) { + status = SILC_NET_ERROR; + goto err; + } + + /* Start async operation */ + conn->op = silc_async_alloc(silc_net_connect_abort, NULL, (void *)conn); + if (!conn->op) { + status = SILC_NET_NO_MEMORY; + goto err; + } + + /* Do host lookup */ + if (!silc_net_is_ip(remote_ip_addr)) { + if (!silc_net_gethostbyname(remote_ip_addr, FALSE, conn->remote_ip, + sizeof(conn->remote_ip))) { + SILC_LOG_ERROR(("Network (%s) unreachable: could not resolve the " + "host", conn->remote)); + status = SILC_NET_HOST_UNREACHABLE; + goto err; + } + } else { + strcpy(conn->remote_ip, remote_ip_addr); + } + + /* Create the connection socket */ + ret = conn->sock->Open(*conn->ss, KAfInet, KSockStream, KProtocolInetTcp); + if (ret != KErrNone) { + SILC_LOG_ERROR(("Cannot create socket")); + status = SILC_NET_ERROR; + goto err; + } + + /* Set appropriate options */ + conn->sock->SetOpt(KSoTcpNoDelay, KSolInetTcp, 1); + conn->sock->SetOpt(KSoTcpKeepAlive, KSolInetTcp, 1); + + /* Bind to the local address if provided */ + if (local_ip_addr) { + local = TInetAddr(0); + tmp = (TText *)local_ip_addr; + ret = local.Input(tmp); + if (ret == KErrNone) + ret = conn->sock->Bind(local); + } + + /* Connect to the host */ + remote = TInetAddr(remote_port); + tmp = (TText *)conn->remote_ip; + ret = remote.Input(tmp); + if (ret != KErrNone) { + SILC_LOG_ERROR(("Cannot connect (cannot set address)")); + status = SILC_NET_ERROR; + goto err; + } + conn->Connect(remote); + + SILC_LOG_DEBUG(("Connection operation in progress")); + + return conn->op; + + err: + if (conn->ss) { + conn->ss->Close(); + delete conn->ss; + } + if (conn->sock) + delete conn->sock; + if (conn->remote) + silc_free(conn->remote); + if (conn->op) + silc_async_free(conn->op); + callback(status, NULL, context); + delete conn; + return NULL; +} + +/****************************** UDP routines ********************************/ + +/* Create UDP/IP connection */ + +SilcStream silc_net_udp_connect(const char *local_ip_addr, int local_port, + const char *remote_ip_addr, int remote_port, + SilcSchedule schedule) +{ + SilcSymbianSocket *s; + SilcStream stream; + TInetAddr local, remote; + TRequestStatus status; + RSocket *sock = NULL; + RSocketServ *ss = NULL; + TBuf<64> tmp; + TInt ret; + + SILC_LOG_DEBUG(("Creating UDP stream")); + + if (!schedule) + goto err; + + SILC_LOG_DEBUG(("Binding to local address %s", + local_ip_addr ? local_ip_addr : "0.0.0.0")); + + sock = new RSocket; + if (!sock) + goto err; + + ss = new RSocketServ; + if (!ss) + goto err; + + /* Open socket server */ + ret = ss->Connect(); + if (ret != KErrNone) + goto err; + + /* Get local bind address */ + if (local_ip_addr) { + local = TInetAddr(local_port); + tmp = (TText *)local_ip_addr; + ret = local.Input(tmp); + if (ret != KErrNone) + goto err; + } else { + local = TInetAddr(KInetAddrAny, local_port); + } + + /* Create the socket */ + ret = sock->Open(*ss, KAfInet, KSockDatagram, KProtocolInetUdp); + if (ret != KErrNone) { + SILC_LOG_ERROR(("Cannot create socket")); + goto err; + } + + /* Set the socket options */ + sock->SetOpt(KSoReuseAddr, KSolInetIp, 1); + + /* Bind the listener socket */ + ret = sock->Bind(local); + if (ret != KErrNone) { + SILC_LOG_DEBUG(("Cannot bind socket")); + goto err; + } + + /* Set to connected state if remote address is provided. */ + if (remote_ip_addr && remote_port) { + remote = TInetAddr(remote_port); + tmp = (TText *)remote_ip_addr; + ret = remote.Input(tmp); + if (ret != KErrNone) + goto err; + + sock->Connect(remote, status); + if (status != KErrNone) { + SILC_LOG_DEBUG(("Cannot connect UDP stream")); + goto err; + } + } + + /* Encapsulate into socket stream */ + s = silc_create_symbian_socket(sock, ss); + if (!s) + goto err; + stream = + silc_socket_udp_stream_create((SilcSocket)s, local_ip_addr ? + silc_net_is_ip6(local_ip_addr) : FALSE, + remote_ip_addr ? TRUE : FALSE, schedule); + if (!stream) + goto err; + + SILC_LOG_DEBUG(("UDP stream created, fd=%d", sock)); + return stream; + + err: + if (sock) + delete sock; + if (ss) { + ss->Close(); + delete ss; + } + return NULL; +} + +/* Sets socket to non-blocking mode */ + +int silc_net_set_socket_nonblock(SilcSocket sock) +{ + /* Nothing to do in Symbian where blocking socket mode is asynchronous + already (ie. non-blocking). */ + return 0; +} + +/* Converts the IP number string from numbers-and-dots notation to + binary form. */ + +SilcBool silc_net_addr2bin(const char *addr, void *bin, SilcUInt32 bin_len) +{ + int ret = 0; + + struct in_addr tmp; + ret = inet_aton(addr, &tmp); + if (bin_len < 4) + return FALSE; + + memcpy(bin, (unsigned char *)&tmp.s_addr, 4); + + return ret != 0; +} + +/* Get remote host and IP from socket */ + +SilcBool silc_net_check_host_by_sock(SilcSocket sock, char **hostname, + char **ip) +{ + SilcSymbianSocket *s = (SilcSymbianSocket *)sock; + TInetAddr addr; + char host[256]; + TBuf<64> tmp; + + if (hostname) + *hostname = NULL; + *ip = NULL; + + s->sock->RemoteName(addr); + addr.Output(tmp); + + *ip = (char *)silc_memdup(tmp.Ptr(), tmp.Length()); + if (*ip == NULL) + return FALSE; + + /* Do reverse lookup if we want hostname too. */ + if (hostname) { + /* Get host by address */ + if (!silc_net_gethostbyaddr(*ip, host, sizeof(host))) + return FALSE; + + *hostname = (char *)silc_memdup(host, strlen(host)); + SILC_LOG_DEBUG(("Resolved hostname `%s'", *hostname)); + + /* Reverse */ + if (!silc_net_gethostbyname(*hostname, TRUE, host, sizeof(host))) + return FALSE; + + if (strcmp(*ip, host)) + return FALSE; + } + + SILC_LOG_DEBUG(("Resolved IP address `%s'", *ip)); + return TRUE; +} + +/* Get local host and IP from socket */ + +SilcBool silc_net_check_local_by_sock(SilcSocket sock, char **hostname, + char **ip) +{ + SilcSymbianSocket *s = (SilcSymbianSocket *)sock; + TInetAddr addr; + char host[256]; + TBuf<64> tmp; + + if (hostname) + *hostname = NULL; + *ip = NULL; + + s->sock->LocalName(addr); + addr.Output(tmp); + + *ip = (char *)silc_memdup(tmp.Ptr(), tmp.Length()); + if (*ip == NULL) + return FALSE; + + /* Do reverse lookup if we want hostname too. */ + if (hostname) { + /* Get host by address */ + if (!silc_net_gethostbyaddr(*ip, host, sizeof(host))) + return FALSE; + + *hostname = (char *)silc_memdup(host, strlen(host)); + SILC_LOG_DEBUG(("Resolved hostname `%s'", *hostname)); + + /* Reverse */ + if (!silc_net_gethostbyname(*hostname, TRUE, host, sizeof(host))) + return FALSE; + + if (strcmp(*ip, host)) + return FALSE; + } + + SILC_LOG_DEBUG(("Resolved IP address `%s'", *ip)); + return TRUE; +} + +/* Get remote port from socket */ + +SilcUInt16 silc_net_get_remote_port(SilcSocket sock) +{ + SilcSymbianSocket *s = (SilcSymbianSocket *)sock; + TInetAddr addr; + + s->sock->RemoteName(addr); + return (SilcUInt16)addr.Port(); +} + +/* Get local port from socket */ + +SilcUInt16 silc_net_get_local_port(SilcSocket sock) +{ + SilcSymbianSocket *s = (SilcSymbianSocket *)sock; + TInetAddr addr; + + s->sock->LocalName(addr); + return (SilcUInt16)addr.Port(); +} diff --git a/lib/silcutil/symbian/silcsymbiansocketstream.cpp b/lib/silcutil/symbian/silcsymbiansocketstream.cpp index fe9d57d6..2d90808b 100644 --- a/lib/silcutil/symbian/silcsymbiansocketstream.cpp +++ b/lib/silcutil/symbian/silcsymbiansocketstream.cpp @@ -1,11 +1,10 @@ - /* silcsymbiansocketstream.cpp Author: Pekka Riikonen - Copyright (C) 2006 Pekka Riikonen + Copyright (C) 2006 - 2007 Pekka Riikonen This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -69,7 +68,7 @@ public: } /* Sending callback */ - void RunL() + virtual void RunL() { if (iStatus != KErrNone) { if (iStatus == KErrEof) @@ -86,7 +85,7 @@ public: } /* Cancel */ - void DoCancel() + virtual void DoCancel() { s->sock->CancelWrite(); } @@ -121,7 +120,7 @@ public: } /* Reading callback */ - void RunL() + virtual void RunL() { if (iStatus != KErrNone) { if (iStatus == KErrEof) @@ -145,7 +144,7 @@ public: } /* Cancel */ - void DoCancel() + virtual void DoCancel() { s->sock->CancelRecv(); } @@ -392,7 +391,7 @@ void silc_socket_stream_destroy(SilcStream stream) s->ss->Close(); delete s->ss; } - delete s; + silc_free(s); } /* Sets stream notification callback for the stream */ diff --git a/lib/silcutil/symbian/silcsymbianthread.cpp b/lib/silcutil/symbian/silcsymbianthread.cpp index 5d637b42..7e134e52 100644 --- a/lib/silcutil/symbian/silcsymbianthread.cpp +++ b/lib/silcutil/symbian/silcsymbianthread.cpp @@ -1,270 +1,292 @@ -/* - - silcsymbianthread.cpp - - Author: Pekka Riikonen - - Copyright (C) 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. - -*/ - -#include "silc.h" -#include - -/**************************** SILC Thread API *******************************/ - -/* Thread structure for Symbian */ -typedef struct { -#ifdef SILC_THREADS - RThread *thread; - SilcThreadStart start_func; - void *context; - bool waitable; -#else - void *tmp; -#endif -} *SilcSymbianThread; - -/* The actual thread function */ - -TInt silc_thread_epoc_start(TAny *context) -{ -#ifdef SILC_THREADS - SilcSymbianThread thread = (SilcSymbianThread)context; - void *ret; - - ret = thread->start_func(thread->context); - silc_thread_exit(ret); - -#endif - return 0; -} - -SilcThread silc_thread_create(SilcThreadStart start_func, void *context, - bool waitable) -{ -#ifdef SILC_THREADS - SilcSymbianThread thread; - TInt ret; - TBuf<32> name; - - SILC_LOG_DEBUG(("Creating new thread")); - - thread = (SilcSymbianThread)silc_calloc(1, sizeof(*thread)); - if (!thread) - return NULL; - 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(); - if (!thread->thread) { - silc_free(thread); - return NULL; - } - - name = (TText *)"silc" + time(NULL); - ret = thread->thread->Create(name, silc_thread_epoc_start, - 8192, 4096, 1024 * 1024, (TAny *)thread); - if (ret != KErrNone) { - SILC_LOG_ERROR(("Could not create new thread")); - delete thread->thread; - silc_free(thread); - return NULL; - } - thread->thread->Resume(); - - 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 -} - -SilcBool silc_thread_wait(SilcThread thread, void **exit_value) -{ -#ifdef SILC_THREADS - /* XXX */ - return TRUE; -#else - return FALSE; -#endif -} - -/***************************** SILC Mutex API *******************************/ - -/* SILC Mutex structure */ -struct SilcMutexStruct { -#ifdef SILC_THREADS - RMutex *mutex; -#endif /* SILC_THREADS */ - unsigned int locked : 1; -}; - -SilcBool silc_mutex_alloc(SilcMutex *mutex) -{ -#ifdef SILC_THREADS - *mutex = (SilcMutex)silc_calloc(1, sizeof(**mutex)); - if (*mutex == NULL) - return FALSE; - (*mutex)->mutex = new RMutex(); - if (!(*mutex)->mutex) { - silc_free(*mutex); - return FALSE; - } - if ((*mutex)->mutex->CreateLocal() != KErrNone) { - delete (*mutex)->mutex; - silc_free(*mutex); - return FALSE; - } - (*mutex)->locked = FALSE; - return TRUE; -#else - return FALSE; -#endif /* SILC_THREADS */ -} - -void silc_mutex_free(SilcMutex mutex) -{ -#ifdef SILC_THREADS - if (mutex) { - mutex->mutex->Close(); - delete mutex->mutex; - silc_free(mutex); - } -#endif /* SILC_THREADS */ -} - -void silc_mutex_lock(SilcMutex mutex) -{ -#ifdef SILC_THREADS - if (mutex) { - mutex->mutex->Wait(); - mutex->locked = TRUE; - } -#endif /* SILC_THREADS */ -} - -void silc_mutex_unlock(SilcMutex mutex) -{ -#ifdef SILC_THREADS - if (mutex) { - mutex->mutex->Signal(); - mutex->locked = FALSE; - } -#endif /* SILC_THREADS */ -} - -void silc_mutex_assert_locked(SilcMutex mutex) -{ -#ifdef SILC_THREADS - if (mutex) - SILC_ASSERT(mutex->locked); -#endif /* SILC_THREADS */ -} - - -/****************************** SILC Cond API *******************************/ - -/* SILC Conditional Variable context */ -struct SilcCondStruct { -#ifdef SILC_THREADS - RCondVar *cond; -#else - void *tmp; -#endif /* SILC_THREADS*/ -}; - -SilcBool silc_cond_alloc(SilcCond *cond) -{ -#ifdef SILC_THREADS - *cond = (SilcCond)silc_calloc(1, sizeof(**cond)); - if (*cond == NULL) - return FALSE; - (*cond)->cond = new RCondVar(); - if (!(*cond)->cond) { - silc_free(*cond); - return FALSE; - } - if ((*cond)->cond->CreateLocal() != KErrNone) { - delete (*cond)->cond; - silc_free(*cond); - return FALSE; - } - return TRUE; -#else - return FALSE; -#endif /* SILC_THREADS*/ -} - -void silc_cond_free(SilcCond cond) -{ -#ifdef SILC_THREADS - cond->cond->Close(); - delete cond->cond; - silc_free(cond); -#endif /* SILC_THREADS*/ -} - -void silc_cond_signal(SilcCond cond) -{ -#ifdef SILC_THREADS - cond->cond->Signal(); -#endif /* SILC_THREADS*/ -} - -void silc_cond_broadcast(SilcCond cond) -{ -#ifdef SILC_THREADS - cond->cond->Broadcast(); -#endif /* SILC_THREADS*/ -} - -void silc_cond_wait(SilcCond cond, SilcMutex mutex) -{ -#ifdef SILC_THREADS - cond->cond->Wait(*mutex->mutex); -#endif /* SILC_THREADS*/ -} - -SilcBool silc_cond_timedwait(SilcCond cond, SilcMutex mutex, - int timeout) -{ -#ifdef SILC_THREADS - if (timeout) - return (cond->cond->TimedWait(*mutex->mutex, (TInt)timeout * 1000) == - KErrNone); - return (cond->cond->Wait(*mutex->mutex) == KErrNone); -#else - return FALSE; -#endif /* SILC_THREADS*/ -} +/* + + silcsymbianthread.cpp + + Author: Pekka Riikonen + + Copyright (C) 2006 - 2007 Pekka Riikonen + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + +*/ + +#include "silc.h" +#include + +/**************************** SILC Thread API *******************************/ + +/* Thread structure for Symbian */ +typedef struct { +#ifdef SILC_THREADS + SilcThreadStart start_func; + void *context; + SilcBool waitable; +#else + void *tmp; +#endif +} *SilcSymbianThread; + +/* The actual thread function */ + +static TInt silc_thread_start(TAny *context) +{ +#ifdef SILC_THREADS + SilcSymbianThread tc = (SilcSymbianThread)context; + SilcThreadStart start_func = tc->start_func; + void *context = tc->context; + SilcBool waitable = tc->waitable; + + silc_free(tc); + + /* Call the thread function */ + if (waitable) + silc_thread_exit(start_func(context)); + else + start_func(context); + +#endif + return KErrNone; +} + +/* Executed new thread */ + +SilcThread silc_thread_create(SilcThreadStart start_func, void *context, + bool waitable) +{ +#ifdef SILC_THREADS + SilcSymbianThread tc; + RThread *thread; + TInt ret; + TBuf<32> name; + + SILC_LOG_DEBUG(("Creating new thread")); + + tc = (SilcSymbianThread)silc_calloc(1, sizeof(*thread)); + if (!tc) + return NULL; + tc->start_func = start_func; + tc->context = context; + tc->waitable = waitable; + + /* Allocate thread */ + thread = new RThread(); + if (!thread) { + silc_free(tc); + return NULL; + } + + /* Create the thread */ + name = (TText *)silc_time_string(0); + ret = thread->Create(name, silc_thread_start, 8192, 4096, 1024 * 1024, + (TAny *)tc); + if (ret != KErrNone) { + SILC_LOG_ERROR(("Could not create new thread")); + delete thread; + silc_free(tc); + return NULL; + } + + /* Start the thread */ + thread->Resume(); + + /* Close our instance to the thread */ + thread->Close(); + + return (SilcThread)thread; +#else + /* Call thread callback immediately */ + (*start_func)(context); + return NULL; +#endif +} + +/* Exits current thread */ + +void silc_thread_exit(void *exit_value) +{ +#ifdef SILC_THREADS + RThread().Kill((Tint)exit_value); +#endif +} + +/* Returns current thread context */ + +SilcThread silc_thread_self(void) +{ +#ifdef SILC_THREADS + return (SilcThread)&RThread(); +#else + return NULL; +#endif +} + +/* Blocks calling thread to wait for `thread' to finish. */ + +SilcBool silc_thread_wait(SilcThread thread, void **exit_value) +{ +#ifdef SILC_THREADS + TRequestStatus req; + RThread *t = (RThread *)thread; + t->Logon(req); + User::WaitForAnyRequest(); + return TRUE; +#else + return FALSE; +#endif +} + +/***************************** SILC Mutex API *******************************/ + +/* SILC Mutex structure */ +struct SilcMutexStruct { +#ifdef SILC_THREADS + RMutex *mutex; +#endif /* SILC_THREADS */ + unsigned int locked : 1; +}; + +SilcBool silc_mutex_alloc(SilcMutex *mutex) +{ +#ifdef SILC_THREADS + *mutex = (SilcMutex)silc_calloc(1, sizeof(**mutex)); + if (*mutex == NULL) + return FALSE; + (*mutex)->mutex = new RMutex(); + if (!(*mutex)->mutex) { + silc_free(*mutex); + return FALSE; + } + if ((*mutex)->mutex->CreateLocal() != KErrNone) { + delete (*mutex)->mutex; + silc_free(*mutex); + return FALSE; + } + (*mutex)->locked = FALSE; + return TRUE; +#else + return FALSE; +#endif /* SILC_THREADS */ +} + +void silc_mutex_free(SilcMutex mutex) +{ +#ifdef SILC_THREADS + if (mutex) { + mutex->mutex->Close(); + delete mutex->mutex; + silc_free(mutex); + } +#endif /* SILC_THREADS */ +} + +void silc_mutex_lock(SilcMutex mutex) +{ +#ifdef SILC_THREADS + if (mutex) { + mutex->mutex->Wait(); + mutex->locked = TRUE; + } +#endif /* SILC_THREADS */ +} + +void silc_mutex_unlock(SilcMutex mutex) +{ +#ifdef SILC_THREADS + if (mutex) { + mutex->mutex->Signal(); + mutex->locked = FALSE; + } +#endif /* SILC_THREADS */ +} + +void silc_mutex_assert_locked(SilcMutex mutex) +{ +#ifdef SILC_THREADS + if (mutex) + SILC_ASSERT(mutex->locked); +#endif /* SILC_THREADS */ +} + + +/****************************** SILC Cond API *******************************/ + +/* SILC Conditional Variable context */ +struct SilcCondStruct { +#ifdef SILC_THREADS + RCondVar *cond; +#else + void *tmp; +#endif /* SILC_THREADS*/ +}; + +SilcBool silc_cond_alloc(SilcCond *cond) +{ +#ifdef SILC_THREADS + *cond = (SilcCond)silc_calloc(1, sizeof(**cond)); + if (*cond == NULL) + return FALSE; + (*cond)->cond = new RCondVar(); + if (!(*cond)->cond) { + silc_free(*cond); + return FALSE; + } + if ((*cond)->cond->CreateLocal() != KErrNone) { + delete (*cond)->cond; + silc_free(*cond); + return FALSE; + } + return TRUE; +#else + return FALSE; +#endif /* SILC_THREADS*/ +} + +void silc_cond_free(SilcCond cond) +{ +#ifdef SILC_THREADS + cond->cond->Close(); + delete cond->cond; + silc_free(cond); +#endif /* SILC_THREADS*/ +} + +void silc_cond_signal(SilcCond cond) +{ +#ifdef SILC_THREADS + cond->cond->Signal(); +#endif /* SILC_THREADS*/ +} + +void silc_cond_broadcast(SilcCond cond) +{ +#ifdef SILC_THREADS + cond->cond->Broadcast(); +#endif /* SILC_THREADS*/ +} + +void silc_cond_wait(SilcCond cond, SilcMutex mutex) +{ +#ifdef SILC_THREADS + cond->cond->Wait(*mutex->mutex); +#endif /* SILC_THREADS*/ +} + +SilcBool silc_cond_timedwait(SilcCond cond, SilcMutex mutex, + int timeout) +{ +#ifdef SILC_THREADS + if (timeout) + return (cond->cond->TimedWait(*mutex->mutex, (TInt)timeout * 1000) == + KErrNone); + return (cond->cond->Wait(*mutex->mutex) == KErrNone); +#else + return FALSE; +#endif /* SILC_THREADS*/ +} diff --git a/symbian/silcdistdefs.h b/symbian/silcdistdefs.h deleted file mode 100644 index fd186f29..00000000 --- a/symbian/silcdistdefs.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - Automatically generated by Autodist 1.3. Do not edit. - - Generated: Fri Dec 22 21:56:55 EET 2006 by priikone - Distribution: default - License: -*/ - -#ifndef _SILC_DISTDEFS_H -#define _SILC_DISTDEFS_H - -#define SILC_DIST_TOOLKIT 1 -#define SILC_DIST_ASN1 1 -#define SILC_DIST_COMPILER 1 -#define SILC_DIST_DOC 1 -#define SILC_DIST_IDCACHE 1 -#define SILC_DIST_INCLUDES 1 -#define SILC_DIST_LIB 1 -#define SILC_DIST_MATH 1 -#define SILC_DIST_SILC 1 -#define SILC_DIST_SKR 1 -#define SILC_DIST_TMA 1 -#define SILC_DIST_VCARD 1 - -#endif /* _SILC_DISTDEFS_H */