+Wed Feb 20 20:41:01 EET 2002 Pekka Riikonen <priikone@silcnet.org>
+
+ * Added automatic extern "C" { ... } for C++ compilers so the
+ application does not need to define them. Affected file
+ includes/silcincludes.h.
+
+ * Renamed lib/silcclient/silcapi.h to silcclient.h as the
+ old name went against naming convention. Applications now
+ include "silcclient.h" instead of "clientlibincludes.h".
+ Removed includes/clientlibincludes.h, it is redundant now.
+
+ * Renamed includes/version.h to silcversion.h.
+
+ * Added really preliminary support for OS/2 into the util
+ library. Only thread & mutex API is implemented, others
+ are still to be implemented. Created the lib/silcutil/os2/
+ directory. Created also file includes/silcos2.h.
+
Wed Feb 20 18:48:49 EET 2002 Pekka Riikonen <priikone@silcnet.org>
* Added preliminary BeOS support into the util library.
#undef PACKAGE
#undef VERSION
#include "silcincludes.h"
-#include "clientlibincludes.h"
+#include "silcclient.h"
#include "silc-core.h"
#undef PACKAGE
#undef VERSION
#include "silcincludes.h"
-#include "clientlibincludes.h"
+#include "silcclient.h"
#include "client_ops.h"
#include "silc-core.h"
#include "silc-channels.h"
#include "silc-queries.h"
#include "silc-nicklist.h"
-#include "version_internal.h"
-#include "version.h"
+#include "silcversion.h"
#include "signals.h"
#include "levels.h"
#include "serverincludes.h"
#include "server_internal.h"
-#include "version.h"
+#include "silcversion.h"
/* For now, we'll have this one server context global for this module. */
static SilcServer silcd;
-I$(silc_top_srcdir)/lib/silcclient \
-I$(silc_top_srcdir)/lib/contrib \
-I$(silc_top_srcdir)/includes \
- -I$(silc_top_srcdir)/doc \
- -I$(silc_top_srcdir)/lib/trq
+ -I$(silc_top_srcdir)/doc
EXTRA_DIST =
#include <libgnomeui/gnome-window-icon.h>
#include <gnome--/client.h>
+#include "silcversion.h"
+
// Pointer to the application
SilcerApp *Silcer_App;
string package = "silcer";
silc_pkcs_register_default();
silc_hash_register_default();
silc_hmac_register_default();
+
+ // XXXXX
+ // In real application at this point it would be of course checked
+ // whether ~/.silc direectory or something exists and key pair exists.
+ // If not then some firstsetup-wizard would be lauched that creates
+ // the keypair. In our example we'll always create a key pair. :(
silc_create_key_pair("rsa", 1024, "kk", "UN=foobar, "
"HN=foo.bar.foobar.com",
&silc_client->public_key, &silc_client->private_key);
+
+ // We are ready to initialize the SILC Client library.
silc_client_init(silc_client);
- // Setup SILC scheduler as timeout task
+ // Setup SILC scheduler as timeout task. This will handle the SILC
+ // client library every 50 milliseconds. It will actually make the
+ // SILC client work on background.
Gnome::Main::timeout.connect(slot(this, &SilcerApp::silc_scheduler), 50);
// XXXXX
#include "SilcerMainDlg.hh"
#include "silcer_gladehelper.hh"
-extern "C" {
#include "silcincludes.h"
-#include "clientlibincludes.h"
-}
+#include "silcclient.h"
#include <fstream>
#include <glade/glade-xml.h>
#include "silcer_gladehelper.hh"
-extern "C" {
#include "silcincludes.h"
-#include "clientlibincludes.h"
-}
+#include "silcclient.h"
#include <sigc++/signal_system.h>
#include <sigc++/object_slot.h>
# GNU General Public License for more details.
#
-AC_INIT(includes/version.h)
+AC_INIT(includes/silcversion.h)
#
# Put here any platform specific stuff
#
AM_CONDITIONAL(SILC_BEOS, test xfalse = xtrue)
+#
+# Native OS2 support (disabled by default)
+#
+AM_CONDITIONAL(SILC_OS2, test xfalse = xtrue)
+
#
# IPv6 support
#
#
# Other configure scripts
#
+if test "x$silc_dist" = "xsilc-client"; then
AC_CONFIG_SUBDIRS(irssi)
+fi
AC_CONFIG_SUBDIRS(lib/silcmath/mpi)
#AC_CONFIG_SUBDIRS(lib/zlib)
if SILC_DIST_TOOLKIT
include_HEADERS = \
bitmove.h \
- clientlibincludes.h \
silcincludes.h \
silcwin32.h \
- version.h \
- version_internal.h \
+ silcversion.h \
+ silcversion_internal.h \
silcdefs.h
endif
EXTRA_DIST = \
bitmove.h \
- clientlibincludes.h \
silcincludes.h \
silcwin32.h \
- version.h \
- version_internal.h \
+ silcversion.h \
+ silcversion_internal.h \
silcdefs.h.in
+++ /dev/null
-/*
-
- clientlibincludes.h
-
- Author: Pekka Riikonen <priikone@poseidon.pspt.fi>
-
- Copyright (C) 1997 - 2000 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.
-
-*/
-
-#ifndef CLIENTLIBINCLUDES_H
-#define CLIENTLIBINCLUDES_H
-
-#include "silcdefs.h"
-
-/* Generic includes */
-#include "silcincludes.h"
-
-/* SILC Client includes */
-#include "client.h"
-#include "command.h"
-#include "command_reply.h"
-#include "idlist.h"
-#include "protocol.h"
-#include "silcapi.h"
-
-#endif
/* Automatically generated configuration header */
#include "silcdefs.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
#ifdef WIN32
#ifndef SILC_WIN32
#define SILC_WIN32
#endif
#endif
+#if defined(OS2)
+#ifndef SILC_OS2
+#define SILC_OS2
+#endif
+#endif
+
/* Platform specific includes */
#ifdef SILC_WIN32
#include "silcbeos.h"
#endif
+#ifdef SILC_OS2
+#include "silcos2.h"
+#endif
+
#ifndef DLLAPI
#define DLLAPI
#endif
#include "silcsftp.h"
#include "silcsftp_fs.h"
+#ifdef __cplusplus
+}
#endif
+
+#endif /* SILCINCLUDES_H */
--- /dev/null
+/*
+
+ silcos2.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 OS2 specific includes and definitions. */
+
+#ifndef SILCOS2_H
+#define SILCOS2_H
+
+#define INCL_DOS
+#define INCL_DOSERRORS
+#include <os2.h>
+
+#endif /* SILCOS2_H */
/*
- version.h
+ silcversion.h
- Author: Pekka Riikonen <priikone@poseidon.pspt.fi>
+ Author: Pekka Riikonen <priikone@silcnet.org>
- Copyright (C) 1997 - 2000 Pekka Riikonen
+ Copyright (C) 1997 - 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.
-
+ 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
*/
-#ifndef VERSION_H
-#define VERSION_H
+#ifndef SILCVERSION_H
+#define SILCVERSION_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
#include "version_internal.h"
const char *silc_name = SILC_NAME;
const char *silc_fullname = "Secure Internet Live Conferencing";
+#ifdef __cplusplus
+}
#endif
+
+#endif /* SILCVERSION_H */
from lib/silcske and general utility routines from lib/silcutil.
<br /> <br />
-The `silcapi.h' file defines the function prototypes that application
+The `silcclient.h' file defines the function prototypes that application
must implement in order to be able to create the user interface with the
library. The idea is that the application can implement whatever user
interface routines in the functions and display the data whatever way
it wants. The library is entirely transparent to the user interface and
it does not include any user interface specific issues such as window
handling or item handling on the screen etc. These does not interest
-the library. The `silcapi.h' also defines the client libary interface
+the library. The `silcclient.h' also defines the client libary interface
the application can call. The interface includes for example functions
for sending channel and private messages, client and channel retrieval
and other utility functions.
<br /> <br />
<tt>
#include "silcincludes.h"<br />
-#include "clientlibincludes.h"
-</tt>
-
-<br /> <br />
-If you are compiling with C++ compiler then you need to include the
-headers as follows:
-
-<br /> <br />
-<tt>
-extern "C" {<br />
-#include "silcincludes.h"<br />
-#include "clientlibincludes.h"<br &/>
-}
+#include "silcclient.h"
</tt>
manner:
<br /> <br />
-<tt> SilcClient client = silc_client_alloc(&ops, params, context, version);</tt>
+<tt> SilcClient client = silc_client_alloc(&ops, params, context, silc_version_string);</tt>
<br /> <br />
`ops' is the static structure of client operations that library will call.
specific context can be retrieved from the SilcClient object. See
`client.h' file for detailed definition of SilcClient object.
+<br /> <br />
+The `silc_version_string' is the current protocol version string, and you
+can get it by including `silcversion.h' header in your source code.
+
<br /> <br />
`ops' can be defined for example as follows:
<br /> <br />
<pre>
#include "silcincludes.h"
-#include "silcapi.h"
+#include "silcclient.h"
int main()
{
@LIBRARY=SILC Client Library
@FILENAME=silcclientlib.html
@LINK=silcclient_using.html:Using SILC Client Library
-@LINK=silcapi.html:Client Library Interface
+@LINK=silcclient.html:Client Library Interface
-->
<BIG><B>SILC Client Library</B></BIG>
it wants.
<BR /><BR />
-The `silcapi.h' file defines the function prototypes that application must
+The `silcclient.h' file defines the function prototypes that application must
implement in order to be able to create the user interface with the
library. The idea is that the application can implement whatever user
interface routines in the functions and display the data whatever way
command_reply.h \
idlist.h \
protocol.h \
- silcapi.h
+ silcclient.h
endif
EXTRA_DIST = *.h client_ops_example.c
*/
/* $Id$ */
-#include "clientlibincludes.h"
+#include "silcincludes.h"
+#include "silcclient.h"
#include "client_internal.h"
/* Static task callback prototypes */
#define CLIENT_H
/* Forward declarations */
-typedef struct SilcClientStruct *SilcClient;
typedef struct SilcClientInternalStruct *SilcClientInternal;
-typedef struct SilcClientConnectionStruct *SilcClientConnection;
-typedef struct SilcClientPingStruct SilcClientPing;
-typedef struct SilcClientAwayStruct SilcClientAway;
-typedef struct SilcClientKeyAgreementStruct *SilcClientKeyAgreement;
-typedef struct SilcClientFtpSessionStruct *SilcClientFtpSession;
-
-#include "idlist.h"
-#include "command.h"
-#include "silcapi.h"
/* Generic rekey context for connections */
typedef struct {
channel key receiving and setting, and channel private key handling
routines. */
-#include "clientlibincludes.h"
+#include "silcincludes.h"
+#include "silcclient.h"
#include "client_internal.h"
/* Sends packet to the `channel'. Packet to channel is always encrypted
*/
/* $Id$ */
-#include "clientlibincludes.h"
+#include "silcincludes.h"
+#include "silcclient.h"
#include "client_internal.h"
static int
and in protocol.c. This file implements the client-to-client key
agreement as defined by the SILC protocol. */
-#include "clientlibincludes.h"
+#include "silcincludes.h"
+#include "silcclient.h"
#include "client_internal.h"
SILC_TASK_CALLBACK(silc_client_key_agreement_final);
important packets sent by the server. They tell different things to the
client such as nick changes, mode changes etc. */
-#include "clientlibincludes.h"
+#include "silcincludes.h"
+#include "silcclient.h"
#include "client_internal.h"
typedef struct {
At the end of this file SilcClientOperation structure is defined, and
it is the one the you will give as an argument to the silc_client_alloc
- function. See also lib/silcclient/README file, and silcapi.h. */
+ function. See also lib/silcclient/README file, and silcclient.h. */
/* Message sent to the application by library. `conn' associates the
/* This file includes the private message sending and receiving routines
and private message key handling routines. */
-#include "clientlibincludes.h"
+#include "silcincludes.h"
+#include "silcclient.h"
#include "client_internal.h"
/* Sends private message to remote client. If private message key has
*/
/* $Id$ */
-#include "clientlibincludes.h"
+#include "silcincludes.h"
+#include "silcclient.h"
#include "client_internal.h"
#define SILC_NOT_CONNECTED(x, c) \
#ifndef COMMAND_H
#define COMMAND_H
-/* Forward declarations */
-typedef struct SilcClientCommandStruct *SilcClientCommand;
-typedef struct SilcClientCommandContextStruct *SilcClientCommandContext;
-
-#include "silcapi.h"
#include "command_reply.h"
/* Structure holding one command and pointer to its function. This
* received but ID entry does not exist, NULL is sent.
*/
-#include "clientlibincludes.h"
+#include "silcincludes.h"
+#include "silcclient.h"
#include "client_internal.h"
const SilcCommandStatusMessage silc_command_status_messages[] = {
} SilcClientCommandReply;
/* Context sent as argument to all command reply functions */
-typedef struct {
+struct SilcClientCommandReplyContextStruct {
SilcClient client;
SilcSocketConnection sock;
SilcCommandPayload payload;
SilcCommandCb callback;
void *context;
uint16 ident;
-} *SilcClientCommandReplyContext;
+};
/* Macros */
*/
/* $Id$ */
-#include "clientlibincludes.h"
+#include "silcincludes.h"
+#include "silcclient.h"
#include "client_internal.h"
/******************************************************************************
#ifndef IDLIST_H
#define IDLIST_H
-typedef struct SilcChannelEntryStruct *SilcChannelEntry;
-
/* Client entry status */
typedef enum {
SILC_CLIENT_STATUS_NONE = 0x0000,
(it receives its ID, for example, by IDENTIFY request) we create new
client entry. This entry also includes the private message keys if
they are used. */
-typedef struct {
+struct SilcClientEntryStruct {
char *nickname; /* nickname */
char *username; /* username */
char *hostname; /* hostname */
SilcClientKeyAgreement ke; /* Current key agreement context or NULL */
SilcClientStatus status; /* Status mask */
SilcHashTable channels; /* All channels client has joined */
-} *SilcClientEntry;
+};
/* Client and its mode on a channel */
-typedef struct SilcChannelUserStruct {
+struct SilcChannelUserStruct {
SilcClientEntry client;
uint32 mode;
SilcChannelEntry channel;
-} *SilcChannelUser;
+};
/* Structure to hold one channel private key. */
-typedef struct {
+struct SilcChannelPrivateKeyStruct {
SilcCipher cipher; /* The cipher and key */
SilcHmac hmac; /* The HMAC and hmac key */
unsigned char *key; /* The key data */
uint32 key_len; /* The key length */
-} *SilcChannelPrivateKey;
+};
/* Channel entry context. This is allocate for every channel client has
joined to. This includes for example the channel specific keys */
/* Server entry context. This represents one server. When server information
is resolved with INFO command the server info is saved in this context.
Also the connected servers are saved here. */
-typedef struct {
+struct SilcServerEntryStruct {
char *server_name;
char *server_info;
SilcServerID *server_id;
-} *SilcServerEntry;
+};
/* Prototypes. These are used only by the library. Application should not
call these directly. */
*/
/* $Id$ */
-#include "clientlibincludes.h"
+#include "silcincludes.h"
+#include "silcclient.h"
#include "client_internal.h"
SILC_TASK_CALLBACK(silc_client_protocol_connection_auth);
/*
- silcapi.h
-
+ silcclient.h
+
Author: Pekka Riikonen <priikone@silcnet.org>
-
- Copyright (C) 2000 - 2001 Pekka Riikonen
-
+
+ Copyright (C) 2000 - 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.
-
+ 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
*
***/
-#ifndef SILCAPI_H
-#define SILCAPI_H
+#ifndef SILCCLIENT_H
+#define SILCCLIENT_H
-#include "clientlibincludes.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Forward declarations */
+typedef struct SilcClientStruct *SilcClient;
+typedef struct SilcClientConnectionStruct *SilcClientConnection;
+typedef struct SilcClientPingStruct SilcClientPing;
+typedef struct SilcClientAwayStruct SilcClientAway;
+typedef struct SilcClientKeyAgreementStruct *SilcClientKeyAgreement;
+typedef struct SilcClientFtpSessionStruct *SilcClientFtpSession;
+typedef struct SilcClientEntryStruct *SilcClientEntry;
+typedef struct SilcChannelEntryStruct *SilcChannelEntry;
+typedef struct SilcServerEntryStruct *SilcServerEntry;
+typedef struct SilcClientCommandStruct *SilcClientCommand;
+typedef struct SilcClientCommandContextStruct *SilcClientCommandContext;
+typedef struct SilcClientCommandReplyContextStruct
+ *SilcClientCommandReplyContext;
+typedef struct SilcChannelPrivateKeyStruct *SilcChannelPrivateKey;
+typedef struct SilcChannelUserStruct *SilcChannelUser;
/* General definitions */
SilcClientConnection conn,
uint32 session_id);
+#include "client.h"
+#include "command.h"
+#include "command_reply.h"
+#include "idlist.h"
+#include "protocol.h"
+
+#ifdef __cplusplus
+}
#endif
+
+#endif /* SILCCLIENT_H */
if SILC_BEOS
SUBDIRS=beos
else
+if SILC_OS2
+SUBDIRS=os2
+else
SUBDIRS=unix
endif
endif
endif
+endif
noinst_LIBRARIES = libsilcutil.a
/* SILC Mutex structure */
struct SilcMutexStruct {
- int sema_count;
sem_id sema;
};
return FALSE;
}
- (*mutex)->sema_count = 0;
(*mutex)->sema = ret;
return TRUE;
void silc_mutex_lock(SilcMutex mutex)
{
- if (atomic_add(&mutex->sema_count, 1) > 0) {
- if (acquire_sem(mutex->sema) < B_NO_ERROR)
- assert(FALSE);
- }
+ if (acquire_sem(mutex->sema) < B_NO_ERROR)
+ assert(FALSE);
}
void silc_mutex_unlock(SilcMutex mutex)
{
- if (atomic_add(&mutes->sema_count, -1) > 1) {
- if (release_sem(mutex->sema) < B_NO_ERROR)
- assert(FALSE);
- }
+ if (release_sem(mutex->sema) < B_NO_ERROR)
+ assert(FALSE);
}
#endif /* SILC_THREADS */
/* I used Apache's APR code as a reference here. */
/* $Id$ */
+/* XXX This leaks memory. Perhaps the SilcThread API should be changed
+ since the silc_thread_self() causes that BeOS and OS/2 is hard to
+ do to support this SilcThread API */
+
#include "silcincludes.h"
#ifdef SILC_THREADS
--- /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
+
+noinst_LIBRARIES = libsilcos2util.a
+
+libsilcos2util_a_SOURCES = \
+ silcos2schedule.c \
+ silcos2net.c \
+ silcos2util.c \
+ silcos2sockconn.c \
+ silcos2mutex.c \
+ silcos2thread.c
+
+include $(top_srcdir)/Makefile.defines.in
--- /dev/null
+/*
+
+ silcos2mutex.c
+
+ 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.
+
+*/
+/* I used Apache's APR code as a reference here. */
+/* $Id$ */
+
+#include "silcincludes.h"
+
+#ifdef SILC_THREADS
+
+/* SILC Mutex structure */
+struct SilcMutexStruct {
+ HMTX mutex;
+};
+
+bool silc_mutex_alloc(SilcMutex *mutex)
+{
+ char name[64];
+
+ *mutex = silc_calloc(1, sizeof(**mutex));
+ if (*mutex == NULL)
+ return FALSE;
+
+ /* Create the lock. Is the name working? :) */
+ memset(name, 0, sizeof(name));
+ snprintf(name, sizeof(name) - 1, "%p/SEM32/SILC1234$", *mutex);
+ if (!DosCreateMutexSem(name, &(*mutex)->mutex, DC_SEM_SHARED, FALSE)) {
+ silc_free(*mutex);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+void silc_mutex_free(SilcMutex mutex)
+{
+ DosCloseMutexSem(mutex->mutex);
+ silc_free(mutex);
+}
+
+void silc_mutex_lock(SilcMutex mutex)
+{
+ if (!DosRequestMutexSem(mutex->mutex, SEM_INDEFINITE_WAIT))
+ assert(FALSE);
+}
+
+void silc_mutex_unlock(SilcMutex mutex)
+{
+ if (!DosReleaseMutexSem(mutex->mutex)
+ assert(FALSE);
+}
+
+#endif /* SILC_THREADS */
--- /dev/null
+/*
+
+ silcos2net.c
+
+ 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"
+#include "silcnet.h"
+
+/* XXX TODO */
+
+#ifdef HAVE_IPV6
+#define SIZEOF_SOCKADDR(so) ((so).sa.sa_family == AF_INET6 ? \
+ sizeof(so.sin6) : sizeof(so.sin))
+#else
+#define SIZEOF_SOCKADDR(so) (sizeof(so.sin))
+#endif
+
+typedef union {
+ struct sockaddr sa;
+ struct sockaddr_in sin;
+#ifdef HAVE_IPV6
+ struct sockaddr_in6 sin6;
+#endif
+} SilcSockaddr;
+
+static bool silc_net_set_sockaddr(SilcSockaddr *addr, const char *ip_addr,
+ int port)
+{
+ int len;
+
+ memset(addr, 0, sizeof(*addr));
+
+ /* Check for IPv4 and IPv6 addresses */
+ if (ip_addr) {
+ if (!silc_net_is_ip(ip_addr)) {
+ SILC_LOG_ERROR(("%s is not IP address", ip_addr));
+ return FALSE;
+ }
+
+ if (silc_net_is_ip4(ip_addr)) {
+ /* IPv4 address */
+ len = sizeof(addr->sin.sin_addr);
+ silc_net_addr2bin(ip_addr,
+ (unsigned char *)&addr->sin.sin_addr.s_addr, len);
+ addr->sin.sin_family = AF_INET;
+ addr->sin.sin_port = port ? htons(port) : 0;
+ } else {
+#ifdef HAVE_IPV6
+ /* IPv6 address */
+ len = sizeof(addr->sin6.sin6_addr);
+ silc_net_addr2bin(ip_addr,
+ (unsigned char *)&addr->sin6.sin6_addr, len);
+ addr->sin6.sin6_family = AF_INET6;
+ addr->sin6.sin6_port = port ? htons(port) : 0;
+#else
+ SILC_LOG_ERROR(("IPv6 support is not compiled in"));
+ return FALSE;
+#endif
+ }
+ } else {
+ /* Any address */
+ addr->sin.sin_family = AF_INET;
+ addr->sin.sin_addr.s_addr = INADDR_ANY;
+ if (port)
+ addr->sin.sin_port = htons(port);
+ }
+
+ return TRUE;
+}
+
+/* This function creates server or daemon or listener or what ever. This
+ does not fork a new process, it must be done by the caller if caller
+ wants to create a child process. This is used by the SILC server.
+ If argument `ip_addr' is NULL `any' address will be used. Returns
+ the created socket or -1 on error. */
+
+int silc_net_create_server(int port, const char *ip_addr)
+{
+ int sock, rval;
+ SilcSockaddr server;
+
+ SILC_LOG_DEBUG(("Creating a new server listener"));
+
+ /* Set sockaddr for server */
+ if (!silc_net_set_sockaddr(&server, ip_addr, port))
+ return -1;
+
+ /* Create the socket */
+ sock = socket(server.sin.sin_family, SOCK_STREAM, 0);
+ if (sock < 0) {
+ SILC_LOG_ERROR(("Cannot create socket: %s", strerror(errno)));
+ return -1;
+ }
+
+ /* Set the socket options */
+ rval = silc_net_set_socket_opt(sock, SOL_SOCKET, SO_REUSEADDR, 1);
+ if (rval < 0) {
+ SILC_LOG_ERROR(("Cannot set socket options: %s", strerror(errno)));
+ return -1;
+ }
+
+ /* Bind the server socket */
+ rval = bind(sock, &server.sa, SIZEOF_SOCKADDR(server));
+ if (rval < 0) {
+ SILC_LOG_DEBUG(("Cannot bind socket: %s", strerror(errno)));
+ return -1;
+ }
+
+ /* Specify that we are listenning */
+ rval = listen(sock, 5);
+ if (rval < 0) {
+ SILC_LOG_ERROR(("Cannot set socket listenning: %s", strerror(errno)));
+ return -1;
+ }
+
+ /* Set the server socket to non-blocking mode */
+ silc_net_set_socket_nonblock(sock);
+
+ SILC_LOG_DEBUG(("Server listener created, fd=%d", sock));
+
+ return sock;
+}
+
+/* Closes the server by closing the socket connection. */
+
+void silc_net_close_server(int sock)
+{
+ shutdown(sock, 2);
+ close(sock);
+
+ SILC_LOG_DEBUG(("Server socket closed"));
+}
+
+/* Creates a connection (TCP/IP) to a remote host. Returns the connection
+ socket or -1 on error. This blocks the process while trying to create
+ the connection. */
+
+int silc_net_create_connection(const char *local_ip, int port,
+ const char *host)
+{
+ int sock, rval;
+ char ip_addr[64];
+ SilcSockaddr desthost;
+
+ SILC_LOG_DEBUG(("Creating connection to host %s port %d", host, port));
+
+ /* Do host lookup */
+ if (!silc_net_gethostbyname(host, ip_addr, sizeof(ip_addr))) {
+ SILC_LOG_ERROR(("Network (%s) unreachable: could not resolve the "
+ "IP address", host));
+ return -1;
+ }
+
+ /* Set sockaddr for this connection */
+ if (!silc_net_set_sockaddr(&desthost, ip_addr, port))
+ return -1;
+
+ /* Create the connection socket */
+ sock = socket(desthost.sin.sin_family, SOCK_STREAM, 0);
+ if (sock < 0) {
+ SILC_LOG_ERROR(("Cannot create socket: %s", strerror(errno)));
+ return -1;
+ }
+
+ /* Bind to the local address if provided */
+ if (local_ip) {
+ SilcSockaddr local;
+
+ /* Set sockaddr for local listener, and try to bind it. */
+ if (silc_net_set_sockaddr(&local, local_ip, 0))
+ bind(sock, &local.sa, sizeof(local));
+ }
+
+ /* Connect to the host */
+ rval = connect(sock, &desthost.sa, sizeof(desthost));
+ if (rval < 0) {
+ SILC_LOG_ERROR(("Cannot connect to remote host: %s", strerror(errno)));
+ shutdown(sock, 2);
+ close(sock);
+ return -1;
+ }
+
+ /* Set appropriate options */
+#if defined(TCP_NODELAY)
+ silc_net_set_socket_opt(sock, IPPROTO_TCP, TCP_NODELAY, 1);
+#endif
+ silc_net_set_socket_opt(sock, SOL_SOCKET, SO_KEEPALIVE, 1);
+
+ SILC_LOG_DEBUG(("Connection created"));
+
+ return sock;
+}
+
+/* Creates a connection (TCP/IP) to a remote host. Returns the connection
+ socket or -1 on error. This creates non-blocking socket hence the
+ connection returns directly. To get the result of the connect() one
+ must select() the socket and read the result after it's ready. */
+
+int silc_net_create_connection_async(const char *local_ip, int port,
+ const char *host)
+{
+ int sock, rval;
+ char ip_addr[64];
+ SilcSockaddr desthost;
+
+ SILC_LOG_DEBUG(("Creating connection (async) to host %s port %d",
+ host, port));
+
+ /* Do host lookup */
+ if (!silc_net_gethostbyname(host, ip_addr, sizeof(ip_addr))) {
+ SILC_LOG_ERROR(("Network (%s) unreachable: could not resolve the "
+ "IP address", host));
+ return -1;
+ }
+
+ /* Set sockaddr for this connection */
+ if (!silc_net_set_sockaddr(&desthost, ip_addr, port))
+ return -1;
+
+ /* Create the connection socket */
+ sock = socket(desthost.sin.sin_family, SOCK_STREAM, 0);
+ if (sock < 0) {
+ SILC_LOG_ERROR(("Cannot create socket: %s", strerror(errno)));
+ return -1;
+ }
+
+ /* Bind to the local address if provided */
+ if (local_ip) {
+ SilcSockaddr local;
+
+ /* Set sockaddr for local listener, and try to bind it. */
+ if (silc_net_set_sockaddr(&local, local_ip, 0))
+ bind(sock, &local.sa, sizeof(local));
+ }
+
+ /* Set the socket to non-blocking mode */
+ silc_net_set_socket_nonblock(sock);
+
+ /* Connect to the host */
+ rval = connect(sock, &desthost.sa, sizeof(desthost));
+ if (rval < 0) {
+ if (errno != EINPROGRESS) {
+ SILC_LOG_ERROR(("Cannot connect to remote host: %s", strerror(errno)));
+ shutdown(sock, 2);
+ close(sock);
+ return -1;
+ }
+ }
+
+ /* Set appropriate options */
+#if defined(TCP_NODELAY)
+ silc_net_set_socket_opt(sock, IPPROTO_TCP, TCP_NODELAY, 1);
+#endif
+ silc_net_set_socket_opt(sock, SOL_SOCKET, SO_KEEPALIVE, 1);
+
+ SILC_LOG_DEBUG(("Connection operation in progress"));
+
+ return sock;
+}
+
+/* Closes the connection by closing the socket connection. */
+
+void silc_net_close_connection(int sock)
+{
+ close(sock);
+}
+
+/* Set's the socket to non-blocking mode. */
+
+int silc_net_set_socket_nonblock(int sock)
+{
+ return fcntl(sock, F_SETFL, fcntl(sock, F_GETFL, 0) | O_NONBLOCK);
+}
+
+/* Converts the IP number string from numbers-and-dots notation to
+ binary form. */
+
+bool silc_net_addr2bin(const char *addr, void *bin, uint32 bin_len)
+{
+ int ret = 0;
+
+ if (silc_net_is_ip4(addr)) {
+ /* IPv4 address */
+ struct in_addr tmp;
+ ret = inet_aton(addr, &tmp);
+ if (bin_len < 4)
+ return FALSE;
+
+ memcpy(bin, (unsigned char *)&tmp.s_addr, 4);
+#ifdef HAVE_IPV6
+ } else {
+ /* IPv6 address */
+ if (bin_len < 16)
+ return FALSE;
+
+ ret = inet_pton(AF_INET6, addr, &bin);
+#endif /* HAVE_IPV6 */
+ }
+
+ return ret != 0;
+}
--- /dev/null
+/*
+
+ silcos2schedule.c
+
+ 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$ */
+
+/* XXX TODO */
+
+#include "silcincludes.h"
+#include "silcschedule_i.h"
+
+/* Calls normal select() system call. */
+
+int silc_select(SilcScheduleFd fds, uint32 fds_count, struct timeval *timeout)
+{
+ fd_set in, out;
+ int ret, i, max_fd = 0;
+
+ FD_ZERO(&in);
+ FD_ZERO(&out);
+
+ for (i = 0; i < fds_count; i++) {
+ if (!fds[i].events)
+ continue;
+
+ if (fds[i].fd > max_fd)
+ max_fd = fds[i].fd;
+
+ if (fds[i].events & SILC_TASK_READ)
+ FD_SET(fds[i].fd, &in);
+ if (fds[i].events & SILC_TASK_WRITE)
+ FD_SET(fds[i].fd, &out);
+
+ fds[i].revents = 0;
+ }
+
+ /* ret = select(max_fd + 1, &in, &out, NULL, timeout); */
+ if (ret <= 0)
+ return ret;
+
+ for (i = 0; i < fds_count; i++) {
+ if (!fds[i].events)
+ continue;
+
+ if (FD_ISSET(fds[i].fd, &in))
+ fds[i].revents |= SILC_TASK_READ;
+ if (FD_ISSET(fds[i].fd, &out))
+ fds[i].revents |= SILC_TASK_WRITE;
+ }
+
+ return ret;
+}
+
+#ifdef SILC_THREADS
+
+/* XXX Do this like it's done in win32/ */
+
+/* Internal wakeup context. */
+typedef struct {
+
+} *SilcOs2Wakeup;
+
+SILC_TASK_CALLBACK(silc_schedule_wakeup_cb)
+{
+
+}
+
+#endif /* SILC_THREADS */
+
+/* Initializes the wakeup of the scheduler. In multi-threaded environment
+ the scheduler needs to be wakenup when tasks are added or removed from
+ the task queues. This will initialize the wakeup for the scheduler.
+ Any tasks that needs to be registered must be registered to the `queue'.
+ It is quaranteed that the scheduler will automatically free any
+ registered tasks in this queue. This is system specific routine. */
+
+void *silc_schedule_wakeup_init(SilcSchedule schedule)
+{
+#ifdef SILC_THREADS
+ return NULL;
+
+#endif
+ return NULL;
+}
+
+/* Uninitializes the system specific wakeup. */
+
+void silc_schedule_wakeup_uninit(void *context)
+{
+#ifdef SILC_THREADS
+
+#endif
+}
+
+/* Wakes up the scheduler */
+
+void silc_schedule_wakeup_internal(void *context)
+{
+#ifdef SILC_THREADS
+
+#endif
+}
--- /dev/null
+/*
+
+ silcos2sockconn.c
+
+ 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$ */
+
+/* XXX TODO */
+
+#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)
+{
+ int ret = 0, err;
+ SilcBuffer src = sock->outbuf;
+
+ if (SILC_IS_DISABLED(sock))
+ return -1;
+
+ SILC_LOG_DEBUG(("Writing data to socket %d", sock->sock));
+
+ if (src->len > 0) {
+ ret = send(sock->sock, src->data, src->len, 0);
+ if (ret == -1) {
+ if (errno == EWOULDBLOCK) {
+ SILC_LOG_DEBUG(("Could not write immediately, will do it later"));
+ return -2;
+ }
+ SILC_LOG_ERROR(("Cannot write to socket: %d", sock->sock));
+ sock->sock_error = errno;
+ return -1;
+ }
+
+ silc_buffer_pull(src, ret);
+ }
+
+ SILC_LOG_DEBUG(("Wrote data %d bytes", ret));
+
+ return ret;
+}
+
+/* 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)
+{
+ int len = 0;
+ unsigned char buf[SILC_SOCKET_READ_SIZE];
+
+ if (SILC_IS_DISABLED(sock))
+ return -1;
+
+ SILC_LOG_DEBUG(("Reading data from socket %d", sock->sock));
+
+ /* Read the data from the socket. */
+ len = recv(sock->sock, buf, sizeof(buf), 0);
+ if (len == -1) {
+ if (errno == EWOULDBLOCK || errno == EINTR) {
+ SILC_LOG_DEBUG(("Could not read immediately, will do it later"));
+ return -2;
+ }
+ SILC_LOG_ERROR(("Cannot read from socket: %d", sock->sock));
+ sock->sock_error = errno;
+ return -1;
+ }
+
+ if (!len)
+ return 0;
+
+ /* Insert the data to the buffer. */
+
+ if (!sock->inbuf)
+ sock->inbuf = silc_buffer_alloc(SILC_SOCKET_BUF_SIZE);
+
+ /* If the data does not fit to the buffer reallocate it */
+ if ((sock->inbuf->end - sock->inbuf->tail) < len)
+ sock->inbuf = silc_buffer_realloc(sock->inbuf, sock->inbuf->truelen +
+ (len * 2));
+ silc_buffer_put_tail(sock->inbuf, buf, len);
+ silc_buffer_pull_tail(sock->inbuf, len);
+
+ SILC_LOG_DEBUG(("Read %d bytes", len));
+
+ return len;
+}
+
+/* Returns human readable socket error message */
+
+bool silc_socket_get_error(SilcSocketConnection sock, char *error,
+ uint32 error_len)
+{
+ /* XXX TODO */
+ return FALSE;
+}
--- /dev/null
+/*
+
+ silcos2thread.c
+
+ 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.
+
+*/
+/* I used Apache's APR code as a reference here. */
+/* $Id$ */
+
+#include "silcincludes.h"
+
+/* XXX This leaks memory. Perhaps the SilcThread API should be changed
+ since the silc_thread_self() causes that BeOS and OS/2 is hard to
+ do to support this SilcThread API */
+
+#ifdef SILC_THREADS
+
+/* Thread structure for OS/2 */
+typedef struct {
+ unsigned long thread;
+ SilcThreadStart start_func;
+ void *context;
+ bool waitable;
+} *SilcOs2Thread;
+
+/* Actual routine that is called by OS/2 when the thread is created.
+ We will call the start_func from here. When this returns the thread
+ is destroyed. */
+
+static void silc_thread_os2_start(void *context)
+{
+ SilcOs2Thread thread = (SilcOs2Thread)context;
+ silc_thread_exit((*thread->start_func)(thread->context));
+}
+
+#endif
+
+SilcThread silc_thread_create(SilcThreadStart start_func, void *context,
+ bool waitable)
+{
+#ifdef SILC_THREADS
+ int ret;
+ SilcOs2Thread thread = silc_calloc(1, sizeof(*thread));
+ if (!thread)
+ return NULL;
+
+ thread->start_func = start_func;
+ thread->context = context;
+ thread->waitable = waitable;
+
+ /* Create the thread, and run it */
+ thread->thread = _beginthread(silc_thread_os2_start, NULL, 65536, thread);
+ if (thread->thread < 0) {
+ SILC_LOG_ERROR(("Could not create new thread"));
+ silc_free(thread);
+ return NULL;
+ }
+
+ return (SilcThread)thread->thread;
+#else
+ /* Call thread callback immediately */
+ (*start_func)(context);
+ return NULL;
+#endif
+}
+
+void silc_thread_exit(void *exit_value)
+{
+#ifdef SILC_THREADS
+ _endthread();
+#endif
+}
+
+SilcThread silc_thread_self(void)
+{
+#ifdef SILC_THREADS
+ PIB *pib;
+ TIB *tib;
+ DosGetInfoBlocks(&tib, &pib);
+ return (SilcThread)tib->tib_ptib2->tib2_ultid;
+#else
+ return NULL;
+#endif
+}
+
+bool silc_thread_wait(SilcThread thread, void **exit_value)
+{
+#ifdef SILC_THREADS
+
+ if (DosWaitThread((unsigned long)thread, DCWW_WAIT) !=
+ ERROR_INVALID_THREADID) {
+ if (exit_value)
+ *exit_value = NULL;
+ return TRUE;
+ }
+
+ return FALSE;
+#else
+ return FALSE;
+#endif
+}
--- /dev/null
+/*
+
+ silcos2util.c
+
+ 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"
+
+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;
+}
+
+#define FILETIME_1970 0x019db1ded53e8000
+const BYTE DWLEN = sizeof(DWORD) * 8;
+
+/* Return current time in struct timeval. Code ripped from some xntp
+ implementation on http://src.openresources.com. */
+
+int silc_gettimeofday(struct timeval *tv)
+{
+ FILETIME ft;
+ __int64 msec;
+
+ GetSystemTimeAsFileTime(&ft);
+ msec = (__int64) ft.dwHighDateTime << DWLEN | ft.dwLowDateTime;
+ msec = (msec - FILETIME_1970) / 10;
+ tv->tv_sec = (long) (msec / 1000000);
+ tv->tv_usec = (long) (msec % 1000000);
+
+ return 0;
+}
*/
/* These routines are based on GLib's WIN32 gthread implementation and
thus credits should go there. */
+/* XXX Is the use of Tls necessary?? */
/* $Id$ */
#include "silcincludes.h"
SilcWin32Thread thread = (SilcWin32Thread)context;
TlsSetValue(silc_thread_tls, context);
- thread->start_func(thread->context);
- silc_thread_exit(NULL);
+ silc_thread_exit(thread->start_func(thread->context));
return 0;
}
# SILC Distribution versions. Set here or give the version on the command
# line as argument.
#
-SILC_VERSION=0.7.3 # Base version
+SILC_VERSION=0.8 # Base version
#############################################################################