Author: Pekka Riikonen <priikone@silcnet.org>
- 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
{
SilcClientConnection conn = fsm_context;
SilcClient client = conn->client;
+ char *nick = NULL;
SILC_LOG_DEBUG(("Register to network"));
+ /* From SILC protocol version 1.3, nickname is in NEW_CLIENT packet */
+ if (conn->internal->remote_version >= 13)
+ nick = (conn->internal->params.nickname ?
+ conn->internal->params.nickname : client->username);
+
/* Send NEW_CLIENT packet to register to network */
if (!silc_packet_send_va(conn->stream, SILC_PACKET_NEW_CLIENT, 0,
SILC_STR_UI_SHORT(strlen(client->username)),
SILC_STR_UI_SHORT(strlen(client->realname)),
SILC_STR_DATA(client->realname,
strlen(client->realname)),
+ SILC_STR_UI_SHORT(nick ? strlen(nick) : 0),
+ SILC_STR_DATA(nick, nick ? strlen(nick) : 0),
SILC_STR_END)) {
/** Error sending packet */
silc_fsm_next(fsm, silc_client_st_register_error);
1, 5, silc_buffer_data(conn->internal->local_idp),
silc_buffer_len(conn->internal->local_idp));
- /* Call NICK command if the nickname was set by the application (and is
- not same as the username). */
- if (conn->internal->params.nickname &&
+ /* With SILC protocol version 1.2 call NICK command if the nickname was
+ set by the application. */
+ if (conn->internal->params.nickname && conn->internal->remote_version < 13 &&
!silc_utf8_strcasecmp(conn->internal->params.nickname, client->username))
silc_client_command_call(client, conn, NULL,
"NICK", conn->internal->params.nickname, NULL);
SILC_FSM_STATE(silc_client_st_register_error)
{
SilcClientConnection conn = fsm_context;
- SilcClient client = conn->client;
SILC_LOG_DEBUG(("Error registering to network"));
/* Signal to close connection */
+ conn->internal->status = SILC_CLIENT_CONN_ERROR;
if (!conn->internal->disconnected) {
conn->internal->disconnected = TRUE;
- SILC_FSM_SEMA_POST(&conn->internal->wait_event);
+ SILC_FSM_EVENT_SIGNAL(&conn->internal->wait_event);
}
- /* Call connect callback */
- if (conn->internal->callback_called)
- conn->callback(client, conn, SILC_CLIENT_CONN_ERROR, 0, NULL,
- conn->callback_context);
- conn->internal->callback_called = TRUE;
-
silc_schedule_task_del_by_all(conn->internal->schedule, 0,
silc_client_connect_timeout, conn);
return SILC_FSM_CONTINUE;
}
+ /** Wait for channels */
+ silc_fsm_next(fsm, silc_client_st_resume_resolve_cmodes);
+
/* Change our nickname */
silc_client_change_nickname(client, conn, conn->local_entry,
resume->nickname, NULL, NULL, 0);
1, 1, silc_buffer_data(conn->internal->local_idp),
silc_buffer_len(conn->internal->local_idp));
+ if (!resume->channel_count)
+ return SILC_FSM_YIELD;
+
/* Send IDENTIFY command for all channels we know about. These are the
channels we've joined to according our detachment data. */
for (i = 0; i < resume->channel_count; i++) {
silc_free(res_argv_lens);
silc_free(res_argv_types);
- /** Wait for channels */
- silc_fsm_next(fsm, silc_client_st_resume_resolve_cmodes);
return SILC_FSM_WAIT;
}
silc_fsm_next(fsm, silc_client_st_resume_completed);
if (!silc_idcache_get_all(conn->internal->channel_cache, &channels))
- return SILC_FSM_CONTINUE;
+ return SILC_FSM_YIELD;
/* Resolve channels' mode, users and topic */
resume->channel_count = silc_list_count(channels) * 3;
conn->callback(client, conn, SILC_CLIENT_CONN_SUCCESS_RESUME, 0, NULL,
conn->callback_context);
+ /* Call UMODE command reply. */
+ if (conn->local_entry->mode)
+ silc_client_resume_command_callback(client, conn, SILC_COMMAND_UMODE,
+ conn->local_entry->mode);
+
/* Call NICK command reply. */
silc_client_resume_command_callback(client, conn, SILC_COMMAND_NICK,
conn->local_entry,
const char *cipher, *hmac;
channel = entry->context;
- cipher = (channel->internal.channel_key ?
- silc_cipher_get_name(channel->internal.channel_key) : NULL);
+ cipher = (channel->internal.send_key ?
+ silc_cipher_get_name(channel->internal.send_key) : NULL);
hmac = (channel->internal.hmac ?
silc_hmac_get_name(channel->internal.hmac) : NULL);
silc_hash_table_list(channel->user_list, &htl);
SILC_FSM_STATE(silc_client_st_resume_error)
{
SilcClientConnection conn = fsm_context;
- SilcClient client = conn->client;
SilcClientResumeSession resume = state_context;
if (conn->internal->disconnected) {
SILC_LOG_DEBUG(("Error resuming to network"));
/* Signal to close connection */
+ conn->internal->status = SILC_CLIENT_CONN_ERROR;
if (!conn->internal->disconnected) {
conn->internal->disconnected = TRUE;
- SILC_FSM_SEMA_POST(&conn->internal->wait_event);
+ SILC_FSM_EVENT_SIGNAL(&conn->internal->wait_event);
}
- /* Call connect callback */
- if (conn->internal->callback_called)
- conn->callback(client, conn, SILC_CLIENT_CONN_ERROR, 0, NULL,
- conn->callback_context);
- conn->internal->callback_called = TRUE;
-
silc_schedule_task_del_by_all(conn->internal->schedule, 0,
silc_client_connect_timeout, conn);