Author: Pekka Riikonen <priikone@silcnet.org>
- Copyright (C) 1997 - 2007 Pekka Riikonen
+ Copyright (C) 1997 - 2008 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
GNU General Public License for more details.
*/
-/* $Id$ */
#include "silc.h"
#include "silcclient.h"
SilcClient client = silc_fsm_get_state_context(fsm);
/* Signal client that we have finished */
- silc_atomic_sub_int16(&client->internal->conns, 1);
+ silc_atomic_sub_int32(&client->internal->conns, 1);
client->internal->connection_closed = TRUE;
SILC_FSM_EVENT_SIGNAL(&client->internal->wait_event);
void *callback_context,
void *stream_context)
{
- /* Nothing */
+ SilcClient client = callback_context;
+ SilcClientConnection conn = stream_context;
+
+ /* Read and write errors are silent */
+ if (error == SILC_PACKET_ERR_READ || error == SILC_PACKET_ERR_WRITE)
+ return;
+
+ client->internal->ops->say(client, conn, SILC_CLIENT_MESSAGE_ERROR,
+ (char *)silc_packet_error_string(error));
}
/* Packet stream callbacks */
/* Process events */
- if (client->internal->run_callback && client->internal->running) {
+ if (client->internal->run_callback) {
/* Call running callbcak back to application */
- SILC_LOG_DEBUG(("We are up, call running callback"));
client->internal->run_callback = FALSE;
- client->internal->running(client, client->internal->running_context);
+ if (client->internal->running) {
+ SILC_LOG_DEBUG(("We are up, call running callback"));
+ client->internal->running(client, client->internal->running_context);
+ }
return SILC_FSM_CONTINUE;
}
/* A connection finished */
SILC_LOG_DEBUG(("Event: connection closed"));
client->internal->connection_closed = FALSE;
- if (silc_atomic_get_int16(&client->internal->conns) == 0 &&
+ if (silc_atomic_get_int32(&client->internal->conns) == 0 &&
client->internal->stop)
SILC_FSM_EVENT_SIGNAL(&client->internal->wait_event);
return SILC_FSM_CONTINUE;
if (client->internal->stop) {
/* Stop client libarry. If we have running connections, wait until
they finish first. */
- if (silc_atomic_get_int16(&client->internal->conns) == 0) {
+ if (silc_atomic_get_int32(&client->internal->conns) == 0) {
SILC_LOG_DEBUG(("Event: stop"));
silc_fsm_next(fsm, silc_client_st_stop);
}
silc_fsm_start(thread, silc_client_connection_st_start);
SILC_LOG_DEBUG(("New connection %p", conn));
- silc_atomic_add_int16(&client->internal->conns, 1);
+ silc_atomic_add_int32(&client->internal->conns, 1);
return conn;
}
if (!client || !remote_host)
return NULL;
+ if (client->internal->run_callback) {
+ SILC_LOG_ERROR(("Client library is not started yet. SilcClientRunning "
+ "callback has not been called yet."));
+ return NULL;
+ }
+
/* Add new connection */
conn = silc_client_add_connection(client, SILC_CONN_SERVER, TRUE, params,
public_key, private_key, remote_host,
if (!client || !remote_host)
return NULL;
+ if (client->internal->run_callback) {
+ SILC_LOG_ERROR(("Client library is not started yet. SilcClientRunning "
+ "callback has not been called yet."));
+ return NULL;
+ }
+
if (params)
params->no_authentication = TRUE;
if (!client || !stream)
return NULL;
+ if (client->internal->run_callback) {
+ SILC_LOG_ERROR(("Client library is not started yet. SilcClientRunning "
+ "callback has not been called yet."));
+ return NULL;
+ }
+
if (!silc_socket_stream_get_info(stream, NULL, &host, NULL, &port)) {
SILC_LOG_ERROR(("Socket stream does not have remote host name set"));
callback(client, NULL, SILC_CLIENT_CONN_ERROR, 0, NULL, context);
nickname_format[sizeof(new_client->internal->
params->nickname_format) - 1] = 0;
- silc_atomic_init16(&new_client->internal->conns, 0);
+ silc_atomic_init32(&new_client->internal->conns, 0);
return new_client;
}
void silc_client_free(SilcClient client)
{
- silc_schedule_uninit(client->schedule);
+ if (client->schedule)
+ silc_schedule_uninit(client->schedule);
if (client->rng)
silc_rng_free(client->rng);
- if (!client->internal->params->dont_register_crypto_library) {
- silc_cipher_unregister_all();
- silc_pkcs_unregister_all();
- silc_hash_unregister_all();
- silc_hmac_unregister_all();
- }
+ if (!client->internal->params->dont_register_crypto_library)
+ silc_crypto_uninit();
- silc_packet_engine_stop(client->internal->packet_engine);
- silc_dlist_uninit(client->internal->ftp_sessions);
- silc_atomic_uninit16(&client->internal->conns);
- silc_mutex_free(client->internal->lock);
+ if (client->internal->packet_engine)
+ silc_packet_engine_stop(client->internal->packet_engine);
+ if (client->internal->ftp_sessions)
+ silc_dlist_uninit(client->internal->ftp_sessions);
+ if (client->internal->lock)
+ silc_mutex_free(client->internal->lock);
+ silc_atomic_uninit32(&client->internal->conns);
silc_free(client->username);
silc_free(client->hostname);
silc_free(client->realname);
if (!client->internal->ftp_sessions)
return FALSE;
- if (!client->internal->params->dont_register_crypto_library) {
+ if (!client->internal->params->dont_register_crypto_library)
/* Initialize the crypto library. If application has done this already
- this has no effect. Also, we will not be overriding something
- application might have registered earlier. */
- silc_cipher_register_default();
- silc_pkcs_register_default();
- silc_hash_register_default();
- silc_hmac_register_default();
- }
+ this has no effect. */
+ silc_crypto_init(NULL);
/* Initialize random number generator */
client->rng = silc_rng_alloc();
silc_rng_global_init(client->rng);
/* Initialize the scheduler */
- client->schedule = silc_schedule_init(0, client);
+ client->schedule = silc_schedule_init(0, client, NULL, NULL);
if (!client->schedule)
return FALSE;
{
SILC_LOG_DEBUG(("Stopping client"));
+ if (!silc_fsm_is_started(&client->internal->fsm)) {
+ SILC_LOG_WARNING(("Attempting to stop client library before it has been "
+ "started (silc_client_init not called)"));
+ return;
+ }
+
client->internal->running = (SilcClientRunning)stopped;
client->internal->running_context = context;