Author: Pekka Riikonen <priikone@silcnet.org>
- Copyright (C) 2002 Pekka Riikonen
+ Copyright (C) 2002, 2004, 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
*/
/* $Id$ */
-#include "silcincludes.h"
+#include "silc.h"
#include "silcclient.h"
#include "client_internal.h"
#define RESUME_CALL_COMPLETION(client, session, s) \
do { \
+ SILC_LOG_DEBUG(("Calling completion")); \
session->success = s; \
silc_schedule_task_add(client->schedule, 0, \
silc_client_resume_call_completion, session, \
0, 1, SILC_TASK_TIMEOUT, SILC_TASK_PRI_LOW); \
} while(0)
-/* Generates the session detachment data. This data can be used later
- to resume back to the server. */
-
-SilcBuffer silc_client_get_detach_data(SilcClient client,
- SilcClientConnection conn)
-{
- SilcBuffer detach;
- SilcHashTableList htl;
- SilcChannelUser chu;
- int ch_count;
-
- SILC_LOG_DEBUG(("Creating detachment data"));
-
- ch_count = silc_hash_table_count(conn->local_entry->channels);
-
- /* Save the nickname, Client ID and user mode in SILC network */
- detach = silc_buffer_alloc_size(2 + strlen(conn->nickname) +
- 2 + conn->local_id_data_len + 4 + 4);
- silc_buffer_format(detach,
- SILC_STR_UI_SHORT(strlen(conn->nickname)),
- SILC_STR_UI_XNSTRING(conn->nickname,
- strlen(conn->nickname)),
- SILC_STR_UI_SHORT(conn->local_id_data_len),
- SILC_STR_UI_XNSTRING(conn->local_id_data,
- conn->local_id_data_len),
- SILC_STR_UI_INT(conn->local_entry->mode),
- SILC_STR_UI_INT(ch_count),
- SILC_STR_END);
-
- /* Save all joined channels */
- silc_hash_table_list(conn->local_entry->channels, &htl);
- while (silc_hash_table_get(&htl, NULL, (void **)&chu)) {
- unsigned char *chid = silc_id_id2str(chu->channel->id, SILC_ID_CHANNEL);
- SilcUInt16 chid_len = silc_id_get_len(chu->channel->id, SILC_ID_CHANNEL);
-
- detach = silc_buffer_realloc(detach, detach->truelen + 2 +
- strlen(chu->channel->channel_name) +
- 2 + chid_len + 4);
- silc_buffer_pull(detach, detach->len);
- silc_buffer_pull_tail(detach, 2 + strlen(chu->channel->channel_name) +
- 2 + chid_len + 4);
- silc_buffer_format(detach,
- SILC_STR_UI_SHORT(strlen(chu->channel->channel_name)),
- SILC_STR_UI_XNSTRING(chu->channel->channel_name,
- strlen(chu->channel->channel_name)),
- SILC_STR_UI_SHORT(chid_len),
- SILC_STR_UI_XNSTRING(chid, chid_len),
- SILC_STR_UI_INT(chu->channel->mode),
- SILC_STR_END);
- silc_free(chid);
- }
- silc_hash_table_list_reset(&htl);
-
- silc_buffer_push(detach, detach->data - detach->head);
-
- SILC_LOG_HEXDUMP(("Detach data"), detach->data, detach->len);
-
- return detach;
-}
-
-/* Processes the detachment data. This creates channels and other
- stuff according the data found in the the connection parameters.
- This doesn't actually resolve any detailed information from the
- server. To do that call silc_client_resume_session function.
- This returns the old detached session client ID. */
-
-bool silc_client_process_detach_data(SilcClient client,
- SilcClientConnection conn,
- unsigned char **old_id,
- SilcUInt16 *old_id_len)
-{
- SilcBufferStruct detach;
- SilcUInt32 ch_count;
- int i, len;
-
- SILC_LOG_DEBUG(("Start"));
-
- silc_free(conn->nickname);
- silc_buffer_set(&detach, conn->params.detach_data,
- conn->params.detach_data_len);
-
- SILC_LOG_HEXDUMP(("Detach data"), detach.data, detach.len);
-
- /* Take the old client ID from the detachment data */
- len = silc_buffer_unformat(&detach,
- SILC_STR_UI16_NSTRING_ALLOC(&conn->nickname,
- NULL),
- SILC_STR_UI16_NSTRING_ALLOC(old_id, old_id_len),
- SILC_STR_UI_INT(NULL),
- SILC_STR_UI_INT(&ch_count),
- SILC_STR_END);
- if (len == -1)
- return FALSE;
-
- silc_buffer_pull(&detach, len);
-
- for (i = 0; i < ch_count; i++) {
- char *channel;
- unsigned char *chid;
- SilcUInt16 chid_len;
- SilcUInt32 ch_mode;
- SilcChannelID *channel_id;
- SilcChannelEntry channel_entry;
-
- len = silc_buffer_unformat(&detach,
- SILC_STR_UI16_NSTRING_ALLOC(&channel, NULL),
- SILC_STR_UI16_NSTRING(&chid, &chid_len),
- SILC_STR_UI_INT(&ch_mode),
- SILC_STR_END);
- if (len == -1)
- return FALSE;
-
- /* Add new channel */
- channel_id = silc_id_str2id(chid, chid_len, SILC_ID_CHANNEL);
- channel_entry = silc_client_get_channel_by_id(client, conn, channel_id);
- if (!channel_entry) {
- channel_entry = silc_client_add_channel(client, conn, channel, ch_mode,
- channel_id);
- } else {
- silc_free(channel);
- silc_free(channel_id);
- }
-
- silc_buffer_pull(&detach, len);
- }
- silc_buffer_push(&detach, detach.data - detach.head);
-
- return TRUE;
-}
-
-
-/* Resume session context */
-typedef struct {
- SilcClient client;
- SilcClientConnection conn;
- SilcClientResumeSessionCallback callback;
- void *context;
- SilcUInt32 channel_count;
- SilcUInt32 *cmd_idents;
- SilcUInt32 cmd_idents_count;
- bool success;
-} *SilcClientResumeSession;
-
/* Generic command reply callback. */
SILC_CLIENT_CMD_REPLY_FUNC(resume)
SilcClientResumeSession session = context;
int i;
- session->callback(session->client, session->conn, session->success,
- session->context);
+ SILC_LOG_DEBUG(("Session completed"));
for (i = 0; i < session->cmd_idents_count; i++)
- silc_client_command_pending_del(session->conn, SILC_COMMAND_IDENTIFY,
+ silc_client_command_pending_del(session->conn, SILC_COMMAND_IDENTIFY,
session->cmd_idents[i]);
silc_free(session->cmd_idents);
+ session->callback(session->client, session->conn, session->success,
+ session->context);
+
memset(session, 'F', sizeof(*session));
silc_free(session);
}
SilcChannelEntry channel;
SilcBuffer tmp;
int i;
- bool ret;
+ SilcBool ret;
SILC_LOG_DEBUG(("Resuming detached session"));
/* Second, send IDENTIFY command of all channels we know about. These
are the channels we've joined to according our detachment data. */
- if (silc_idcache_get_all(conn->channel_cache, &list)) {
+ if (silc_idcache_get_all(conn->internal->channel_cache, &list)) {
unsigned char **res_argv = NULL;
SilcUInt32 *res_argv_lens = NULL, *res_argv_types = NULL, res_argc = 0;
silc_client_command_register(client, SILC_COMMAND_IDENTIFY, NULL, NULL,
silc_client_command_reply_resume_special,
0, ++conn->cmd_ident);
- silc_client_command_pending(conn, SILC_COMMAND_IDENTIFY,
+ silc_client_command_pending(conn, SILC_COMMAND_IDENTIFY,
conn->cmd_ident,
silc_client_command_resume_identify,
session);
tmp = silc_command_payload_encode(SILC_COMMAND_IDENTIFY,
res_argc, res_argv, res_argv_lens,
res_argv_types, conn->cmd_ident);
- silc_client_packet_send(client, conn->sock, SILC_PACKET_COMMAND,
+ silc_client_packet_send(client, conn->sock, SILC_PACKET_COMMAND,
NULL, 0, NULL, NULL, tmp->data, tmp->len, TRUE);
session->cmd_idents = silc_realloc(session->cmd_idents,
return;
/* Unregister this command reply */
- silc_client_command_unregister(client, SILC_COMMAND_IDENTIFY, NULL,
+ silc_client_command_unregister(client, SILC_COMMAND_IDENTIFY, NULL,
silc_client_command_reply_resume,
cmd->ident);
return;
SILC_LOG_DEBUG(("Start"));
/* Unregister this command reply */
- silc_client_command_unregister(client, SILC_COMMAND_CMODE, NULL,
+ silc_client_command_unregister(client, SILC_COMMAND_CMODE, NULL,
silc_client_command_reply_resume,
cmd->ident);
SILC_LOG_DEBUG(("Start"));
/* Unregister this command reply */
- silc_client_command_unregister(client, SILC_COMMAND_USERS, NULL,
+ silc_client_command_unregister(client, SILC_COMMAND_USERS, NULL,
silc_client_command_reply_users_i,
cmd->ident);
/* Get channel ID */
tmp = silc_argument_get_arg_type(cmd->args, 2, &tmp_len);
if (!tmp) {
- COMMAND_REPLY_ERROR;
+ COMMAND_REPLY_ERROR(SILC_STATUS_ERR_NOT_ENOUGH_PARAMS);
goto err;
}
channel_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
if (!channel_id) {
- COMMAND_REPLY_ERROR;
+ COMMAND_REPLY_ERROR(SILC_STATUS_ERR_NOT_ENOUGH_PARAMS);
goto err;
}
/* Get the list count */
tmp = silc_argument_get_arg_type(cmd->args, 3, &tmp_len);
if (!tmp) {
- COMMAND_REPLY_ERROR;
+ COMMAND_REPLY_ERROR(SILC_STATUS_ERR_NOT_ENOUGH_PARAMS);
goto err;
}
SILC_GET32_MSB(list_count, tmp);
/* Get Client ID list */
tmp = silc_argument_get_arg_type(cmd->args, 4, &tmp_len);
if (!tmp) {
- COMMAND_REPLY_ERROR;
+ COMMAND_REPLY_ERROR(SILC_STATUS_ERR_NOT_ENOUGH_PARAMS);
goto err;
}
silc_buffer_set(&client_id_list, tmp, tmp_len);
/* Get client mode list */
tmp = silc_argument_get_arg_type(cmd->args, 5, &tmp_len);
if (!tmp) {
- COMMAND_REPLY_ERROR;
+ COMMAND_REPLY_ERROR(SILC_STATUS_ERR_NOT_ENOUGH_PARAMS);
goto err;
}
silc_buffer_set(&client_mode_list, tmp, tmp_len);
client->internal->ops->command_reply(client, conn, cmd->payload, TRUE,
SILC_COMMAND_JOIN, cmd->status,
channel->channel_name, channel,
- channel->mode, 0,
- NULL, NULL, NULL, NULL,
+ channel->mode, 0,
+ NULL, NULL, NULL, NULL,
channel->hmac, list_count,
&client_id_list, client_mode_list);