X-Git-Url: http://git.silcnet.org/gitweb/?a=blobdiff_plain;f=lib%2Fsilcclient%2Fcommand_reply.c;h=79acee69291f3865e8a859debadc8201eab32c59;hb=017dec75a98209fbef49eb496c2269b0c49e736d;hp=17d0b3301c9eb9deeba88572870afa4490079763;hpb=44cc109b5932ed1c84539f2da0b86392539d2b55;p=silc.git diff --git a/lib/silcclient/command_reply.c b/lib/silcclient/command_reply.c index 17d0b330..79acee69 100644 --- a/lib/silcclient/command_reply.c +++ b/lib/silcclient/command_reply.c @@ -82,8 +82,8 @@ const SilcCommandStatusMessage silc_command_status_messages[] = { { 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), "No such Client ID" }, - { STAT(NO_SUCH_CHANNEL_ID),"No such Channel ID" }, + { 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" }, @@ -168,7 +168,7 @@ void silc_client_command_reply_process(SilcClient client, return; } - cmd->cb(ctx); + cmd->cb(ctx, NULL); } /* Returns status message string */ @@ -257,43 +257,13 @@ silc_client_command_reply_whois_save(SilcClientCommandReplyContext cmd, 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); } @@ -431,13 +401,20 @@ silc_client_command_reply_identify_save(SilcClientCommandReplyContext cmd, 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); @@ -446,59 +423,98 @@ silc_client_command_reply_identify_save(SilcClientCommandReplyContext cmd, 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 @@ -564,7 +580,8 @@ SILC_CLIENT_CMD_REPLY_FUNC(nick) SILC_GET16_MSB(status, silc_argument_get_arg_type(cmd->args, 1, NULL)); if (status != SILC_STATUS_OK) { - cmd->client->ops->say(cmd->client, conn, "Cannot set nickname: %s", + cmd->client->ops->say(cmd->client, conn, SILC_CLIENT_MESSAGE_ERROR, + "Cannot set nickname: %s", silc_client_command_status_message(status)); COMMAND_REPLY_ERROR; goto out; @@ -572,7 +589,7 @@ SILC_CLIENT_CMD_REPLY_FUNC(nick) argc = silc_argument_get_arg_num(cmd->args); if (argc < 2 || argc > 2) { - cmd->client->ops->say(cmd->client, conn, + cmd->client->ops->say(cmd->client, conn, SILC_CLIENT_MESSAGE_ERROR, "Cannot set nickname: bad reply to command"); COMMAND_REPLY_ERROR; goto out; @@ -657,7 +674,7 @@ SILC_CLIENT_CMD_REPLY_FUNC(topic) SILC_GET16_MSB(status, silc_argument_get_arg_type(cmd->args, 1, NULL)); if (status != SILC_STATUS_OK) { - cmd->client->ops->say(cmd->client, conn, + cmd->client->ops->say(cmd->client, conn, SILC_CLIENT_MESSAGE_ERROR, "%s", silc_client_command_status_message(status)); COMMAND_REPLY_ERROR; SILC_CLIENT_PENDING_DESTRUCTOR(cmd, SILC_COMMAND_TOPIC); @@ -722,7 +739,7 @@ SILC_CLIENT_CMD_REPLY_FUNC(invite) tmp = silc_argument_get_arg_type(cmd->args, 1, NULL); SILC_GET16_MSB(status, tmp); if (status != SILC_STATUS_OK) { - cmd->client->ops->say(cmd->client, conn, + cmd->client->ops->say(cmd->client, conn, SILC_CLIENT_MESSAGE_ERROR, "%s", silc_client_command_status_message(status)); COMMAND_REPLY_ERROR; SILC_CLIENT_PENDING_DESTRUCTOR(cmd, SILC_COMMAND_INVITE); @@ -775,7 +792,7 @@ SILC_CLIENT_CMD_REPLY_FUNC(kill) tmp = silc_argument_get_arg_type(cmd->args, 1, NULL); SILC_GET16_MSB(status, tmp); if (status != SILC_STATUS_OK) { - cmd->client->ops->say(cmd->client, conn, + cmd->client->ops->say(cmd->client, conn, SILC_CLIENT_MESSAGE_ERROR, "%s", silc_client_command_status_message(status)); COMMAND_REPLY_ERROR; goto out; @@ -799,14 +816,18 @@ SILC_CLIENT_CMD_REPLY_FUNC(info) { SilcClientCommandReplyContext cmd = (SilcClientCommandReplyContext)context; SilcClientConnection conn = (SilcClientConnection)cmd->sock->user_data; - SilcClient client = cmd->client; SilcCommandStatus status; unsigned char *tmp; + SilcIDCacheEntry id_cache; + SilcServerEntry server; + SilcServerID *server_id = NULL; + char *server_name, *server_info; + uint32 len; tmp = silc_argument_get_arg_type(cmd->args, 1, NULL); SILC_GET16_MSB(status, tmp); if (status != SILC_STATUS_OK) { - cmd->client->ops->say(cmd->client, conn, + cmd->client->ops->say(cmd->client, conn, SILC_CLIENT_MESSAGE_ERROR, "%s", silc_client_command_status_message(status)); COMMAND_REPLY_ERROR; SILC_CLIENT_PENDING_DESTRUCTOR(cmd, SILC_COMMAND_INFO); @@ -815,31 +836,50 @@ SILC_CLIENT_CMD_REPLY_FUNC(info) } /* Get server ID */ - tmp = silc_argument_get_arg_type(cmd->args, 2, NULL); + tmp = silc_argument_get_arg_type(cmd->args, 2, &len); if (!tmp) goto out; - /* XXX save server id */ + server_id = silc_id_payload_parse_id(tmp, len); + if (!server_id) + goto out; /* Get server name */ - tmp = silc_argument_get_arg_type(cmd->args, 3, NULL); - if (!tmp) + server_name = silc_argument_get_arg_type(cmd->args, 3, NULL); + if (!server_name) goto out; /* Get server info */ - tmp = silc_argument_get_arg_type(cmd->args, 4, NULL); - if (!tmp) + server_info = silc_argument_get_arg_type(cmd->args, 4, NULL); + if (!server_info) goto out; - client->ops->say(cmd->client, conn, "Info: %s", tmp); + /* See whether we have this server cached. If not create it. */ + if (!silc_idcache_find_by_id_one(conn->server_cache, (void *)server_id, + &id_cache)) { + SILC_LOG_DEBUG(("New server entry")); + + server = silc_calloc(1, sizeof(*server)); + server->server_name = strdup(server_name); + server->server_info = strdup(server_info); + server->server_id = silc_id_dup(server_id, SILC_ID_SERVER); + /* Add it to the cache */ + silc_idcache_add(conn->server_cache, server->server_name, + server->server_id, (void *)server, FALSE); + } else { + server = (SilcServerEntry)id_cache->context; + } + /* Notify application */ - COMMAND_REPLY((ARGS, NULL, (char *)tmp)); + COMMAND_REPLY((ARGS, server, server->server_name, server->server_info)); /* Execute any pending command callbacks */ SILC_CLIENT_PENDING_EXEC(cmd, SILC_COMMAND_INFO); out: + if (server_id) + silc_free(server_id); SILC_CLIENT_PENDING_DESTRUCTOR(cmd, SILC_COMMAND_INFO); silc_client_command_reply_free(cmd); } @@ -857,7 +897,7 @@ SILC_CLIENT_CMD_REPLY_FUNC(ping) SILC_GET16_MSB(status, silc_argument_get_arg_type(cmd->args, 1, NULL)); if (status != SILC_STATUS_OK) { - cmd->client->ops->say(cmd->client, conn, + cmd->client->ops->say(cmd->client, conn, SILC_CLIENT_MESSAGE_ERROR, "%s", silc_client_command_status_message(status)); COMMAND_REPLY_ERROR; goto out; @@ -874,7 +914,7 @@ SILC_CLIENT_CMD_REPLY_FUNC(ping) for (i = 0; i < conn->ping_count; i++) { if (SILC_ID_SERVER_COMPARE(conn->ping[i].dest_id, id)) { diff = curtime - conn->ping[i].start_time; - cmd->client->ops->say(cmd->client, conn, + cmd->client->ops->say(cmd->client, conn, SILC_CLIENT_MESSAGE_INFO, "Ping reply from %s: %d second%s", conn->ping[i].dest_name, diff, diff == 1 ? "" : "s"); @@ -921,7 +961,7 @@ SILC_CLIENT_CMD_REPLY_FUNC(join) SILC_GET16_MSB(status, silc_argument_get_arg_type(cmd->args, 1, NULL)); if (status != SILC_STATUS_OK) { - cmd->client->ops->say(cmd->client, conn, + cmd->client->ops->say(cmd->client, conn, SILC_CLIENT_MESSAGE_ERROR, "%s", silc_client_command_status_message(status)); COMMAND_REPLY_ERROR; goto out; @@ -929,7 +969,7 @@ SILC_CLIENT_CMD_REPLY_FUNC(join) argc = silc_argument_get_arg_num(cmd->args); if (argc < 7 || argc > 14) { - cmd->client->ops->say(cmd->client, conn, + cmd->client->ops->say(cmd->client, conn, SILC_CLIENT_MESSAGE_ERROR, "Cannot join channel: Bad reply packet"); COMMAND_REPLY_ERROR; goto out; @@ -938,7 +978,7 @@ SILC_CLIENT_CMD_REPLY_FUNC(join) /* Get channel name */ tmp = silc_argument_get_arg_type(cmd->args, 2, NULL); if (!tmp) { - cmd->client->ops->say(cmd->client, conn, + cmd->client->ops->say(cmd->client, conn, SILC_CLIENT_MESSAGE_ERROR, "Cannot join channel: Bad reply packet"); COMMAND_REPLY_ERROR; goto out; @@ -948,7 +988,7 @@ SILC_CLIENT_CMD_REPLY_FUNC(join) /* Get Channel ID */ tmp = silc_argument_get_arg_type(cmd->args, 3, &len); if (!tmp) { - cmd->client->ops->say(cmd->client, conn, + cmd->client->ops->say(cmd->client, conn, SILC_CLIENT_MESSAGE_ERROR, "Cannot join channel: Bad reply packet"); COMMAND_REPLY_ERROR; silc_free(channel_name); @@ -984,11 +1024,13 @@ SILC_CLIENT_CMD_REPLY_FUNC(join) 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) { if (!silc_hmac_alloc(hmac, NULL, &channel->hmac)) { - cmd->client->ops->say(cmd->client, conn, + cmd->client->ops->say(cmd->client, conn, SILC_CLIENT_MESSAGE_ERROR, "Cannot join channel: Unsupported HMAC `%s'", hmac); COMMAND_REPLY_ERROR; @@ -1045,10 +1087,9 @@ SILC_CLIENT_CMD_REPLY_FUNC(join) 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; @@ -1109,7 +1150,7 @@ SILC_CLIENT_CMD_REPLY_FUNC(motd) tmp = silc_argument_get_arg_type(cmd->args, 1, NULL); SILC_GET16_MSB(status, tmp); if (status != SILC_STATUS_OK) { - cmd->client->ops->say(cmd->client, conn, + cmd->client->ops->say(cmd->client, conn, SILC_CLIENT_MESSAGE_ERROR, "%s", silc_client_command_status_message(status)); COMMAND_REPLY_ERROR; return; @@ -1139,7 +1180,8 @@ SILC_CLIENT_CMD_REPLY_FUNC(motd) if (i == 2) line[0] = ' '; - cmd->client->ops->say(cmd->client, conn, "%s", line); + cmd->client->ops->say(cmd->client, conn, SILC_CLIENT_MESSAGE_INFO, + "%s", line); if (!strlen(cp)) break; @@ -1172,7 +1214,7 @@ SILC_CLIENT_CMD_REPLY_FUNC(umode) tmp = silc_argument_get_arg_type(cmd->args, 1, NULL); SILC_GET16_MSB(status, tmp); if (status != SILC_STATUS_OK) { - cmd->client->ops->say(cmd->client, conn, + cmd->client->ops->say(cmd->client, conn, SILC_CLIENT_MESSAGE_ERROR, "%s", silc_client_command_status_message(status)); COMMAND_REPLY_ERROR; goto out; @@ -1206,24 +1248,53 @@ SILC_CLIENT_CMD_REPLY_FUNC(cmode) SilcClientConnection conn = (SilcClientConnection)cmd->sock->user_data; SilcCommandStatus status; unsigned char *tmp; + uint32 mode; + SilcIDCacheEntry id_cache; + SilcChannelID *channel_id; + SilcChannelEntry channel; + uint32 len; SILC_GET16_MSB(status, silc_argument_get_arg_type(cmd->args, 1, NULL)); if (status != SILC_STATUS_OK) { - cmd->client->ops->say(cmd->client, conn, + cmd->client->ops->say(cmd->client, conn, SILC_CLIENT_MESSAGE_ERROR, "%s", silc_client_command_status_message(status)); COMMAND_REPLY_ERROR; goto out; } + /* Take Channel ID */ + tmp = silc_argument_get_arg_type(cmd->args, 2, &len); + if (!tmp) + goto out; + channel_id = silc_id_payload_parse_id(tmp, len); + if (!channel_id) + goto out; + + /* Get the channel entry */ + if (!silc_idcache_find_by_id_one(conn->channel_cache, (void *)channel_id, + &id_cache)) { + silc_free(channel_id); + COMMAND_REPLY_ERROR; + goto out; + } + + channel = (SilcChannelEntry)id_cache->context; + /* Get channel mode */ - tmp = silc_argument_get_arg_type(cmd->args, 2, NULL); + tmp = silc_argument_get_arg_type(cmd->args, 3, NULL); if (!tmp) { + silc_free(channel_id); COMMAND_REPLY_ERROR; goto out; } + /* Save the mode */ + SILC_GET32_MSB(mode, tmp); + channel->mode = mode; + /* Notify application */ - COMMAND_REPLY((ARGS, tmp)); + COMMAND_REPLY((ARGS, channel, mode)); + silc_free(channel_id); /* Execute any pending command callbacks */ SILC_CLIENT_PENDING_EXEC(cmd, SILC_COMMAND_CMODE); @@ -1242,12 +1313,16 @@ SILC_CLIENT_CMD_REPLY_FUNC(cumode) SilcCommandStatus status; SilcIDCacheEntry id_cache = NULL; SilcClientID *client_id; + SilcChannelID *channel_id; + SilcClientEntry client_entry; + SilcChannelEntry channel; + SilcChannelUser chu; unsigned char *tmp, *id; - uint32 len; + uint32 len, mode; SILC_GET16_MSB(status, silc_argument_get_arg_type(cmd->args, 1, NULL)); if (status != SILC_STATUS_OK) { - cmd->client->ops->say(cmd->client, conn, + cmd->client->ops->say(cmd->client, conn, SILC_CLIENT_MESSAGE_ERROR, "%s", silc_client_command_status_message(status)); COMMAND_REPLY_ERROR; goto out; @@ -1260,14 +1335,34 @@ SILC_CLIENT_CMD_REPLY_FUNC(cumode) goto out; } + /* Take Channel ID */ + tmp = silc_argument_get_arg_type(cmd->args, 3, &len); + if (!tmp) + goto out; + channel_id = silc_id_payload_parse_id(tmp, len); + if (!channel_id) + goto out; + + /* Get the channel entry */ + if (!silc_idcache_find_by_id_one(conn->channel_cache, (void *)channel_id, + &id_cache)) { + silc_free(channel_id); + COMMAND_REPLY_ERROR; + goto out; + } + + channel = (SilcChannelEntry)id_cache->context; + /* Get Client ID */ - id = silc_argument_get_arg_type(cmd->args, 3, &len); + id = silc_argument_get_arg_type(cmd->args, 4, &len); if (!id) { + silc_free(channel_id); COMMAND_REPLY_ERROR; goto out; } client_id = silc_id_payload_parse_id(id, len); if (!client_id) { + silc_free(channel_id); COMMAND_REPLY_ERROR; goto out; } @@ -1277,13 +1372,27 @@ SILC_CLIENT_CMD_REPLY_FUNC(cumode) NULL, NULL, silc_hash_client_id_compare, NULL, &id_cache)) { + silc_free(channel_id); + silc_free(client_id); COMMAND_REPLY_ERROR; goto out; } + client_entry = (SilcClientEntry)id_cache->context; + + /* Save the mode */ + SILC_GET32_MSB(mode, tmp); + while ((chu = silc_list_get(channel->clients)) != SILC_LIST_END) { + if (chu->client == client_entry) { + chu->mode = mode; + break; + } + } + /* Notify application */ - COMMAND_REPLY((ARGS, tmp, (SilcClientEntry)id_cache->context)); + COMMAND_REPLY((ARGS, mode, channel, client_entry)); silc_free(client_id); + silc_free(channel_id); /* Execute any pending command callbacks */ SILC_CLIENT_PENDING_EXEC(cmd, SILC_COMMAND_CUMODE); @@ -1303,7 +1412,7 @@ SILC_CLIENT_CMD_REPLY_FUNC(kick) tmp = silc_argument_get_arg_type(cmd->args, 1, NULL); SILC_GET16_MSB(status, tmp); if (status != SILC_STATUS_OK) { - cmd->client->ops->say(cmd->client, conn, + cmd->client->ops->say(cmd->client, conn, SILC_CLIENT_MESSAGE_ERROR, "%s", silc_client_command_status_message(status)); COMMAND_REPLY_ERROR; goto out; @@ -1330,7 +1439,7 @@ SILC_CLIENT_CMD_REPLY_FUNC(silcoper) tmp = silc_argument_get_arg_type(cmd->args, 1, NULL); SILC_GET16_MSB(status, tmp); if (status != SILC_STATUS_OK) { - cmd->client->ops->say(cmd->client, conn, + cmd->client->ops->say(cmd->client, conn, SILC_CLIENT_MESSAGE_ERROR, "%s", silc_client_command_status_message(status)); COMMAND_REPLY_ERROR; goto out; @@ -1357,7 +1466,7 @@ SILC_CLIENT_CMD_REPLY_FUNC(oper) tmp = silc_argument_get_arg_type(cmd->args, 1, NULL); SILC_GET16_MSB(status, tmp); if (status != SILC_STATUS_OK) { - cmd->client->ops->say(cmd->client, conn, + cmd->client->ops->say(cmd->client, conn, SILC_CLIENT_MESSAGE_ERROR, "%s", silc_client_command_status_message(status)); COMMAND_REPLY_ERROR; goto out; @@ -1384,7 +1493,7 @@ SILC_CLIENT_CMD_REPLY_FUNC(connect) tmp = silc_argument_get_arg_type(cmd->args, 1, NULL); SILC_GET16_MSB(status, tmp); if (status != SILC_STATUS_OK) { - cmd->client->ops->say(cmd->client, conn, + cmd->client->ops->say(cmd->client, conn, SILC_CLIENT_MESSAGE_ERROR, "%s", silc_client_command_status_message(status)); COMMAND_REPLY_ERROR; goto out; @@ -1415,7 +1524,7 @@ SILC_CLIENT_CMD_REPLY_FUNC(ban) tmp = silc_argument_get_arg_type(cmd->args, 1, NULL); SILC_GET16_MSB(status, tmp); if (status != SILC_STATUS_OK) { - cmd->client->ops->say(cmd->client, conn, + cmd->client->ops->say(cmd->client, conn, SILC_CLIENT_MESSAGE_ERROR, "%s", silc_client_command_status_message(status)); COMMAND_REPLY_ERROR; goto out; @@ -1464,7 +1573,7 @@ SILC_CLIENT_CMD_REPLY_FUNC(close) tmp = silc_argument_get_arg_type(cmd->args, 1, NULL); SILC_GET16_MSB(status, tmp); if (status != SILC_STATUS_OK) { - cmd->client->ops->say(cmd->client, conn, + cmd->client->ops->say(cmd->client, conn, SILC_CLIENT_MESSAGE_ERROR, "%s", silc_client_command_status_message(status)); COMMAND_REPLY_ERROR; goto out; @@ -1491,7 +1600,7 @@ SILC_CLIENT_CMD_REPLY_FUNC(shutdown) tmp = silc_argument_get_arg_type(cmd->args, 1, NULL); SILC_GET16_MSB(status, tmp); if (status != SILC_STATUS_OK) { - cmd->client->ops->say(cmd->client, conn, + cmd->client->ops->say(cmd->client, conn, SILC_CLIENT_MESSAGE_ERROR, "%s", silc_client_command_status_message(status)); COMMAND_REPLY_ERROR; goto out; @@ -1520,7 +1629,7 @@ SILC_CLIENT_CMD_REPLY_FUNC(leave) tmp = silc_argument_get_arg_type(cmd->args, 1, NULL); SILC_GET16_MSB(status, tmp); if (status != SILC_STATUS_OK) { - cmd->client->ops->say(cmd->client, conn, + cmd->client->ops->say(cmd->client, conn, SILC_CLIENT_MESSAGE_ERROR, "%s", silc_client_command_status_message(status)); COMMAND_REPLY_ERROR; goto out; @@ -1562,7 +1671,7 @@ SILC_CLIENT_CMD_REPLY_FUNC(users) tmp = silc_argument_get_arg_type(cmd->args, 1, NULL); SILC_GET16_MSB(status, tmp); if (status != SILC_STATUS_OK) { - cmd->client->ops->say(cmd->client, conn, + cmd->client->ops->say(cmd->client, conn, SILC_CLIENT_MESSAGE_ERROR, "%s", silc_client_command_status_message(status)); COMMAND_REPLY_ERROR; goto out; @@ -1570,22 +1679,30 @@ SILC_CLIENT_CMD_REPLY_FUNC(users) /* 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); @@ -1593,8 +1710,10 @@ SILC_CLIENT_CMD_REPLY_FUNC(users) /* 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); @@ -1603,10 +1722,18 @@ SILC_CLIENT_CMD_REPLY_FUNC(users) /* 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); @@ -1615,9 +1742,7 @@ SILC_CLIENT_CMD_REPLY_FUNC(users) 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; @@ -1645,7 +1770,7 @@ SILC_CLIENT_CMD_REPLY_FUNC(users) if (!id_cache || !((SilcClientEntry)id_cache->context)->username) { /* No we don't have it (or it is incomplete in information), query it from the server. Assemble argument table that will be sent - for the IDENTIFY command later. */ + for the WHOIS command later. */ res_argv = silc_realloc(res_argv, sizeof(*res_argv) * (res_argc + 1)); res_argv_lens = silc_realloc(res_argv_lens, sizeof(*res_argv_lens) * @@ -1677,18 +1802,18 @@ SILC_CLIENT_CMD_REPLY_FUNC(users) if (res_argc) { SilcBuffer res_cmd; - /* Send the IDENTIFY command to server */ - res_cmd = silc_command_payload_encode(SILC_COMMAND_IDENTIFY, + /* Send the WHOIS command to server */ + res_cmd = silc_command_payload_encode(SILC_COMMAND_WHOIS, res_argc, res_argv, res_argv_lens, res_argv_types, ++conn->cmd_ident); silc_client_packet_send(cmd->client, conn->sock, SILC_PACKET_COMMAND, NULL, 0, NULL, NULL, res_cmd->data, res_cmd->len, TRUE); - /* Register pending command callback. After we've received the IDENTIFY + /* Register pending command callback. After we've received the WHOIS command reply 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, + silc_client_command_pending(conn, SILC_COMMAND_WHOIS, conn->cmd_ident, NULL, silc_client_command_reply_users, cmd); silc_buffer_free(res_cmd); @@ -1729,6 +1854,8 @@ SILC_CLIENT_CMD_REPLY_FUNC(getkey) 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; @@ -1741,7 +1868,7 @@ SILC_CLIENT_CMD_REPLY_FUNC(getkey) tmp = silc_argument_get_arg_type(cmd->args, 1, NULL); SILC_GET16_MSB(status, tmp); if (status != SILC_STATUS_OK) { - cmd->client->ops->say(cmd->client, conn, + cmd->client->ops->say(cmd->client, conn, SILC_CLIENT_MESSAGE_ERROR, "%s", silc_client_command_status_message(status)); COMMAND_REPLY_ERROR; goto out; @@ -1756,25 +1883,23 @@ SILC_CLIENT_CMD_REPLY_FUNC(getkey) /* 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, @@ -1787,10 +1912,16 @@ SILC_CLIENT_CMD_REPLY_FUNC(getkey) /* 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: @@ -1800,5 +1931,6 @@ SILC_CLIENT_CMD_REPLY_FUNC(getkey) if (public_key) silc_pkcs_public_key_free(public_key); silc_free(client_id); + silc_free(server_id); silc_client_command_reply_free(cmd); }