{ STAT(NO_SERVER_ID), "No Server ID given" },
{ STAT(BAD_CLIENT_ID), "Bad Client ID" },
{ STAT(BAD_CHANNEL_ID), "Bad Channel ID" },
- { STAT(NO_SUCH_CLIENT_ID), "There was no such client" },
- { STAT(NO_SUCH_CHANNEL_ID),"There was no such channel" },
+ { STAT(NO_SUCH_CLIENT_ID), "There is no such client" },
+ { STAT(NO_SUCH_CHANNEL_ID),"There is no such channel" },
{ STAT(NICKNAME_IN_USE), "Nickname already exists" },
{ STAT(NOT_ON_CHANNEL), "You are not on that channel" },
{ STAT(USER_NOT_ON_CHANNEL),"They are not on the channel" },
silc_hash_client_id_compare, NULL,
&id_cache)) {
SILC_LOG_DEBUG(("Adding new client entry"));
-
- client_entry = silc_calloc(1, sizeof(*client_entry));
- client_entry->id = client_id;
- silc_parse_nickname(nickname, &client_entry->nickname,
- &client_entry->server, &client_entry->num);
- client_entry->username = strdup(username);
- if (realname)
- client_entry->realname = strdup(realname);
- client_entry->mode = mode;
-
- /* Add client to cache */
- silc_idcache_add(conn->client_cache, client_entry->nickname,
- client_id, (void *)client_entry, FALSE);
+ client_entry =
+ silc_client_add_client(cmd->client, conn, nickname, username, realname,
+ client_id, mode);
} else {
client_entry = (SilcClientEntry)id_cache->context;
- if (client_entry->nickname)
- silc_free(client_entry->nickname);
- if (client_entry->server)
- silc_free(client_entry->server);
- if (client_entry->username)
- silc_free(client_entry->username);
- if (client_entry->realname)
- silc_free(client_entry->realname);
- client_entry->mode = mode;
-
- SILC_LOG_DEBUG(("Updating client entry"));
-
- silc_parse_nickname(nickname, &client_entry->nickname,
- &client_entry->server, &client_entry->num);
- client_entry->username = strdup(username);
- if (realname)
- client_entry->realname = strdup(realname);
-
- /* Remove the old cache entry and create a new one */
- silc_idcache_del_by_context(conn->client_cache, client_entry);
- silc_idcache_add(conn->client_cache, client_entry->nickname,
- client_entry->id, client_entry, FALSE);
+ silc_client_update_client(cmd->client, conn, client_entry,
+ nickname, username, realname, mode);
silc_free(client_id);
}
SilcCommandStatus status)
{
SilcClientConnection conn = (SilcClientConnection)cmd->sock->user_data;
- SilcClientID *client_id;
+ SilcClient client = cmd->client;
+ SilcClientID *client_id = NULL;
+ SilcServerID *server_id = NULL;
+ SilcChannelID *channel_id = NULL;
SilcIDCacheEntry id_cache = NULL;
- SilcClientEntry client_entry = NULL;
+ SilcClientEntry client_entry;
+ SilcServerEntry server_entry;
+ SilcChannelEntry channel_entry;
int argc;
uint32 len;
unsigned char *id_data;
- char *nickname = NULL, *username = NULL;
+ char *name = NULL, *info = NULL;
+ SilcIDPayload idp = NULL;
+ SilcIdType id_type;
argc = silc_argument_get_arg_num(cmd->args);
COMMAND_REPLY_ERROR;
return;
}
-
- client_id = silc_id_payload_parse_id(id_data, len);
- if (!client_id) {
+ idp = silc_id_payload_parse_data(id_data, len);
+ if (!idp) {
COMMAND_REPLY_ERROR;
return;
}
-
- nickname = silc_argument_get_arg_type(cmd->args, 3, &len);
- username = silc_argument_get_arg_type(cmd->args, 4, &len);
- /* Check if we have this client cached already. */
- if (!silc_idcache_find_by_id_one_ext(conn->client_cache, (void *)client_id,
- NULL, NULL,
- silc_hash_client_id_compare, NULL,
- &id_cache)) {
- SILC_LOG_DEBUG(("Adding new client entry"));
+ name = silc_argument_get_arg_type(cmd->args, 3, &len);
+ info = silc_argument_get_arg_type(cmd->args, 4, &len);
- client_entry = silc_calloc(1, sizeof(*client_entry));
- client_entry->id = client_id;
- silc_parse_nickname(nickname, &client_entry->nickname,
- &client_entry->server, &client_entry->num);
- if (username)
- client_entry->username = strdup(username);
-
- /* Add client to cache */
- silc_idcache_add(conn->client_cache, client_entry->nickname,
- client_id, (void *)client_entry, FALSE);
- } else {
- client_entry = (SilcClientEntry)id_cache->context;
- if (client_entry->nickname)
- silc_free(client_entry->nickname);
- if (client_entry->server)
- silc_free(client_entry->server);
- if (username && client_entry->username)
- silc_free(client_entry->username);
-
- SILC_LOG_DEBUG(("Updating client entry"));
+ id_type = silc_id_payload_get_type(idp);
- silc_parse_nickname(nickname, &client_entry->nickname,
- &client_entry->server, &client_entry->num);
-
- if (username)
- client_entry->username = strdup(username);
-
- /* Remove the old cache entry and create a new one */
- silc_idcache_del_by_context(conn->client_cache, client_entry);
- silc_idcache_add(conn->client_cache, client_entry->nickname,
- client_entry->id, client_entry, FALSE);
- silc_free(client_id);
+ switch (id_type) {
+ case SILC_ID_CLIENT:
+ client_id = silc_id_payload_get_id(idp);
+
+ SILC_LOG_DEBUG(("Received client information"));
+
+ /* Check if we have this client cached already. */
+ if (!silc_idcache_find_by_id_one_ext(conn->client_cache,
+ (void *)client_id,
+ NULL, NULL,
+ silc_hash_client_id_compare, NULL,
+ &id_cache)) {
+ SILC_LOG_DEBUG(("Adding new client entry"));
+ client_entry =
+ silc_client_add_client(cmd->client, conn, name, info, NULL,
+ silc_id_dup(client_id, id_type), 0);
+ } else {
+ client_entry = (SilcClientEntry)id_cache->context;
+ silc_client_update_client(cmd->client, conn, client_entry,
+ name, info, NULL, 0);
+ }
+
+ /* Notify application */
+ COMMAND_REPLY((ARGS, client_entry, name, info));
+ break;
+
+ case SILC_ID_SERVER:
+ server_id = silc_id_payload_get_id(idp);
+
+ SILC_LOG_DEBUG(("Received server information"));
+
+ /* Check if we have this server cached already. */
+ if (!silc_idcache_find_by_id_one(conn->server_cache,
+ (void *)server_id, &id_cache)) {
+ SILC_LOG_DEBUG(("Adding new server entry"));
+
+ server_entry = silc_calloc(1, sizeof(*server_entry));
+ server_entry->server_id = silc_id_dup(server_id, id_type);
+ if (name)
+ server_entry->server_name = strdup(name);
+ if (info)
+ server_entry->server_info = strdup(info);
+
+ /* Add server to cache */
+ silc_idcache_add(conn->server_cache, server_entry->server_name,
+ server_entry->server_id, (void *)server_entry, FALSE);
+ } else {
+ server_entry = (SilcServerEntry)id_cache->context;
+ }
+
+ /* Notify application */
+ COMMAND_REPLY((ARGS, server_entry, name, info));
+ break;
+
+ case SILC_ID_CHANNEL:
+ channel_id = silc_id_payload_get_id(idp);
+
+ SILC_LOG_DEBUG(("Received channel information"));
+
+ /* Check if we have this channel cached already. */
+ if (!silc_idcache_find_by_id_one(conn->channel_cache,
+ (void *)channel_id, &id_cache)) {
+ if (!name)
+ break;
+
+ SILC_LOG_DEBUG(("Adding new channel entry"));
+ channel_entry = silc_client_new_channel_id(client, conn->sock,
+ strdup(name), 0, idp);
+ } else {
+ channel_entry = (SilcChannelEntry)id_cache->context;
+ }
+
+ /* Notify application */
+ COMMAND_REPLY((ARGS, channel_entry, name, info));
+ break;
}
- /* Notify application */
- COMMAND_REPLY((ARGS, client_entry, nickname, username));
+ silc_id_payload_free(idp);
+ silc_free(client_id);
+ silc_free(server_id);
+ silc_free(channel_id);
}
/* Received reply for IDENTIFY command. This maybe called several times
mode, idp);
silc_id_payload_free(idp);
+ conn->current_channel = channel;
+
/* Get hmac */
hmac = silc_argument_get_arg_type(cmd->args, 11, NULL);
if (hmac) {
silc_hash_client_id_compare, NULL,
&id_cache)) {
/* No, we don't have it, add entry for it. */
- client_entry = silc_calloc(1, sizeof(*client_entry));
- client_entry->id = silc_id_dup(client_id, SILC_ID_CLIENT);
- silc_idcache_add(conn->client_cache, NULL, client_entry->id,
- (void *)client_entry, FALSE);
+ client_entry =
+ silc_client_add_client(cmd->client, conn, NULL, NULL, NULL,
+ silc_id_dup(client_id, SILC_ID_CLIENT), 0);
} else {
/* Yes, we have it already */
client_entry = (SilcClientEntry)id_cache->context;
/* Get channel ID */
tmp = silc_argument_get_arg_type(cmd->args, 2, &tmp_len);
- if (!tmp)
+ if (!tmp) {
+ COMMAND_REPLY_ERROR;
goto out;
+ }
channel_id = silc_id_payload_parse_id(tmp, tmp_len);
- if (!channel_id)
+ if (!channel_id) {
+ COMMAND_REPLY_ERROR;
goto out;
-
+ }
+
/* Get the list count */
tmp = silc_argument_get_arg_type(cmd->args, 3, &tmp_len);
- if (!tmp)
+ if (!tmp) {
+ COMMAND_REPLY_ERROR;
goto out;
+ }
SILC_GET32_MSB(list_count, tmp);
/* Get Client ID list */
tmp = silc_argument_get_arg_type(cmd->args, 4, &tmp_len);
- if (!tmp)
+ if (!tmp) {
+ COMMAND_REPLY_ERROR;
goto out;
+ }
client_id_list = silc_buffer_alloc(tmp_len);
silc_buffer_pull_tail(client_id_list, tmp_len);
/* Get client mode list */
tmp = silc_argument_get_arg_type(cmd->args, 5, &tmp_len);
- if (!tmp)
+ if (!tmp) {
+ COMMAND_REPLY_ERROR;
goto out;
+ }
client_mode_list = silc_buffer_alloc(tmp_len);
silc_buffer_pull_tail(client_mode_list, tmp_len);
/* Get channel entry */
if (!silc_idcache_find_by_id_one(conn->channel_cache, (void *)channel_id,
&id_cache)) {
- COMMAND_REPLY_ERROR;
- goto out;
+ /* Resolve the channel from server */
+ silc_idlist_get_channel_by_id(cmd->client, conn, channel_id, TRUE);
+
+ /* Register pending command callback. After we've received the channel
+ information we will reprocess this command reply by re-calling this
+ USERS command reply callback. */
+ silc_client_command_pending(conn, SILC_COMMAND_IDENTIFY, conn->cmd_ident,
+ NULL, silc_client_command_reply_users, cmd);
+ return;
+ } else {
+ channel = (SilcChannelEntry)id_cache->context;
}
- channel = (SilcChannelEntry)id_cache->context;
/* Remove old client list from channel. */
silc_list_start(channel->clients);
silc_free(chu);
}
- /* Cache the received Client ID's and modes. This cache expires
- whenever server sends notify message to channel. It means two things;
- some user has joined or leaved the channel. XXX! */
+ /* Cache the received Client ID's and modes. */
for (i = 0; i < list_count; i++) {
uint16 idp_len;
uint32 mode;
SilcIDPayload idp = NULL;
SilcClientID *client_id = NULL;
SilcClientEntry client_entry;
+ SilcServerID *server_id = NULL;
+ SilcServerEntry server_entry;
SilcSKEPKType type;
unsigned char *tmp, *pk;
uint32 len;
/* Get the public key payload */
tmp = silc_argument_get_arg_type(cmd->args, 3, &len);
- if (!tmp)
- goto out;
-
- /* Decode the public key */
-
- SILC_GET16_MSB(pk_len, tmp);
- SILC_GET16_MSB(type, tmp + 2);
- pk = tmp + 4;
-
- if (type != SILC_SKE_PK_TYPE_SILC)
- goto out;
-
- if (!silc_pkcs_public_key_decode(pk, pk_len, &public_key))
- goto out;
-
+ if (tmp) {
+ /* Decode the public key */
+ SILC_GET16_MSB(pk_len, tmp);
+ SILC_GET16_MSB(type, tmp + 2);
+ pk = tmp + 4;
+
+ if (type != SILC_SKE_PK_TYPE_SILC)
+ goto out;
+
+ if (!silc_pkcs_public_key_decode(pk, pk_len, &public_key))
+ goto out;
+ }
+
id_type = silc_id_payload_get_type(idp);
if (id_type == SILC_ID_CLIENT) {
+ /* Received client's public key */
client_id = silc_id_payload_get_id(idp);
-
if (!silc_idcache_find_by_id_one_ext(conn->client_cache,
(void *)client_id,
NULL, NULL,
/* Notify application */
COMMAND_REPLY((ARGS, id_type, client_entry, public_key));
} else if (id_type == SILC_ID_SERVER) {
- /* XXX we don't have server entries at all */
- goto out;
- } else {
- goto out;
+ /* Received server's public key */
+ server_id = silc_id_payload_get_id(idp);
+ if (!silc_idcache_find_by_id_one(conn->server_cache, (void *)server_id,
+ &id_cache))
+ goto out;
+
+ server_entry = (SilcServerEntry)id_cache->context;
+
+ /* Notify application */
+ COMMAND_REPLY((ARGS, id_type, server_entry, public_key));
}
out:
if (public_key)
silc_pkcs_public_key_free(public_key);
silc_free(client_id);
+ silc_free(server_id);
silc_client_command_reply_free(cmd);
}