From: Pekka Riikonen Date: Thu, 1 Feb 2001 18:04:08 +0000 (+0000) Subject: updates. X-Git-Tag: SILC.0.1~285 X-Git-Url: http://git.silcnet.org/gitweb/?p=silc.git;a=commitdiff_plain;h=a6f113620145a6b00aae2fdd44552d9f2221f5f9 updates. --- diff --git a/CHANGES b/CHANGES index b147d908..b2c25a07 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,35 @@ +Thu Feb 1 21:32:27 EET 2001 Pekka Riikonen + + * Fixed some minor bugs in client when sending WHOIS command. The + arguments was in wrong order. + + * Removed statis function add_to_channel from server in + silcd/command.c that was previously used with the joining but + is obsolete now. + + * Tested USERS command in router environment successfully with two + routers, two servers and two clients. + +Thu Feb 1 00:54:26 EET 2001 Pekka Riikonen + + * Reorganized the USERS command and command reply in client library + in lib/silcclient/command.c and lib/silcclient/command_reply.c. + When the command is given by user we register a pending command + callback that will reprocess the command after the reply has been + received from the server. When reprocessing the packet we then + display the information. Thus, the USERS information is displayed + now in the command callback instead of in the command reply + callback. The processing of the command is same as previously + when server has sent the command reply in the JOINing process. + + * Added to USERS command in silcd/command_reply.c to join the client, + we didn't use to know about, to the channel after we've created + a client entry for it. Also, for clienet we did know already still + check whether it is on the channel or not and add it if not. + + * Removed silc_server_command_join_notify as the function and its + use was obsolete. + Tue Jan 30 22:39:15 EET 2001 Pekka Riikonen * Changed the client's pending command handling to the same as the diff --git a/apps/silcd/command.c b/apps/silcd/command.c index b7f9f680..31420b44 100644 --- a/apps/silcd/command.c +++ b/apps/silcd/command.c @@ -40,7 +40,8 @@ silc_server_command_send_status_data(SilcServerCommandContext cmd, static void silc_server_command_free(SilcServerCommandContext cmd); void silc_server_command_send_users(SilcServer server, SilcSocketConnection sock, - SilcChannelEntry channel); + SilcChannelEntry channel, + int pending); /* Server command list. */ SilcServerCommand silc_command_list[] = @@ -325,7 +326,7 @@ silc_server_command_whois_parse(SilcServerCommandContext cmd, int i, k; /* If client ID is in the command it must be used instead of nickname */ - tmp = silc_argument_get_arg_type(cmd->args, 2, &len); + tmp = silc_argument_get_arg_type(cmd->args, 3, &len); if (!tmp) { /* No ID, get the nickname@server string and parse it. */ tmp = silc_argument_get_arg_type(cmd->args, 1, NULL); @@ -919,7 +920,7 @@ silc_server_command_identify_from_client(SilcServerCommandContext cmd) { SilcServer server = cmd->server; char *nick = NULL, *server_name = NULL; - int count = 0, clients_count; + int count = 0, clients_count = 0; SilcClientEntry *clients = NULL, entry; SilcClientID **client_id = NULL; unsigned int client_id_count = 0; @@ -1052,7 +1053,7 @@ silc_server_command_identify_from_server(SilcServerCommandContext cmd) { SilcServer server = cmd->server; char *nick = NULL, *server_name = NULL; - int count = 0, clients_count; + int count = 0, clients_count = 0; SilcClientEntry *clients = NULL, entry; SilcClientID **client_id = NULL; unsigned int client_id_count = 0; @@ -1114,9 +1115,17 @@ silc_server_command_identify_from_server(SilcServerCommandContext cmd) if (!clients) { /* Such a client really does not exist in the SILC network. */ - silc_server_command_send_status_data(cmd, SILC_COMMAND_IDENTIFY, - SILC_STATUS_ERR_NO_SUCH_NICK, - 3, nick, strlen(nick)); + if (!client_id_count) { + silc_server_command_send_status_data(cmd, SILC_COMMAND_IDENTIFY, + SILC_STATUS_ERR_NO_SUCH_NICK, + 3, nick, strlen(nick)); + } else { + SilcBuffer idp = silc_id_payload_encode(client_id[0], SILC_ID_CLIENT); + silc_server_command_send_status_data(cmd, SILC_COMMAND_IDENTIFY, + SILC_STATUS_ERR_NO_SUCH_CLIENT_ID, + 2, idp->data, idp->len); + silc_buffer_free(idp); + } goto out; } @@ -1619,63 +1628,20 @@ SILC_SERVER_CMD_FUNC(oper) { } -typedef struct { - char *channel_name; - char *nickname; - char *username; - char *hostname; - SilcChannelEntry channel; - SilcServer server; - SilcClientEntry client; -} JoinInternalContext; - -SILC_TASK_CALLBACK(silc_server_command_join_notify) -{ - JoinInternalContext *ctx = (JoinInternalContext *)context; - - if (ctx->channel->key && ctx->channel->key_len) { - SilcBuffer clidp; - - clidp = silc_id_payload_encode(ctx->client->id, SILC_ID_CLIENT); - - silc_server_send_notify_to_channel(ctx->server, ctx->channel, FALSE, - SILC_NOTIFY_TYPE_JOIN, 1, - clidp->data, clidp->len); -#if 0 - /* Send NEW_CHANNEL_USER packet to primary route */ - silc_server_send_new_channel_user(server, server->router->connection, - server->server_type == SILC_SERVER ? - FALSE : TRUE, - channel->id, SILC_ID_CHANNEL_LEN, - client->id, SILC_ID_CLIENT_LEN); -#endif - - /* Send USERS command reply to the joined channel so the user sees who - is currently on the channel. */ - silc_server_command_send_users(ctx->server, ctx->client->connection, - ctx->channel); - - silc_buffer_free(clidp); - silc_free(ctx); - } else { - silc_task_register(ctx->server->timeout_queue, fd, - silc_server_command_join_notify, context, - 0, 200000, SILC_TASK_TIMEOUT, SILC_TASK_PRI_LOW); - } -} - /* Assembles USERS command and executes it. This is called when client joins to a channel and we wan't to send USERS command reply to the client. */ void silc_server_command_send_users(SilcServer server, SilcSocketConnection sock, - SilcChannelEntry channel) + SilcChannelEntry channel, + int pending) { SilcServerCommandContext cmd; SilcBuffer buffer, idp; SilcPacketContext *packet = silc_packet_context_alloc(); + /* Create USERS command packet and process it. */ idp = silc_id_payload_encode(channel->id, SILC_ID_CHANNEL); buffer = silc_command_payload_encode_va(SILC_COMMAND_USERS, 0, 1, 1, idp->data, idp->len); @@ -1692,51 +1658,27 @@ void silc_server_command_send_users(SilcServer server, cmd->packet = silc_packet_context_dup(packet); cmd->pending = FALSE; - silc_server_command_users((void *)cmd); + if (pending) { + /* If this function was called from pending command then instead of + processing the command now, register a pending command callback which + will process it after we've received the automatic USERS command + reply. */ + silc_server_command_pending(server, SILC_COMMAND_USERS, 0, + silc_server_command_users, (void *)cmd); + cmd->pending = TRUE; + silc_free(buffer); + silc_free(idp); + return; + } + /* Process USERS command. */ + silc_server_command_users((void *)cmd); + silc_free(buffer); silc_free(idp); silc_packet_context_free(packet); } -/* Internal routine that is called after router has replied to server's - JOIN command it forwarded to the router. The route has joined and possibly - creaetd the channel. This function adds the client to the channel's user - list. */ - -SILC_SERVER_CMD_FUNC(add_to_channel) -{ - SilcServerCommandContext cmd = (SilcServerCommandContext)context; - SilcServer server = cmd->server; - SilcClientEntry client; - SilcChannelEntry channel; - SilcChannelClientEntry chl; - char *channel_name; - - /* Get channel name */ - channel_name = silc_argument_get_arg_type(cmd->args, 1, NULL); - - /* Get client entry */ - client = (SilcClientEntry)cmd->sock->user_data; - - /* Get channel entry */ - channel = silc_idlist_find_channel_by_name(server->local_list, - channel_name, NULL); - if (channel) { - /* Join the client to the channel by adding it to channel's user list. - Add also the channel to client entry's channels list for fast cross- - referencing. */ - chl = silc_calloc(1, sizeof(*chl)); - //chl->mode = SILC_CHANNEL_UMODE_CHANOP | SILC_CHANNEL_UMODE_CHANFO; - chl->client = client; - chl->channel = channel; - silc_list_add(channel->user_list, chl); - silc_list_add(client->channels, chl); - } - - silc_server_command_free(cmd); -} - /* Internal routine to join channel. The channel sent to this function has been either created or resolved from ID lists. This joins the sent client to the channel. */ @@ -1897,34 +1839,24 @@ static void silc_server_command_join_channel(SilcServer server, silc_server_packet_send(server, sock, SILC_PACKET_COMMAND_REPLY, 0, reply->data, reply->len, FALSE); - if (!cmd->pending) + if (!cmd->pending) { /* Send JOIN notify to locally connected clients on the channel */ silc_server_send_notify_to_channel(server, channel, FALSE, SILC_NOTIFY_TYPE_JOIN, 1, clidp->data, clidp->len); - /* Send NEW_CHANNEL_USER packet to our primary router */ - if (!cmd->pending && !server->standalone) - silc_server_send_new_channel_user(server, server->router->connection, - server->server_type == SILC_SERVER ? - FALSE : TRUE, - channel->id, SILC_ID_CHANNEL_LEN, - client->id, SILC_ID_CLIENT_LEN); + /* Send NEW_CHANNEL_USER packet to our primary router */ + if (!server->standalone) + silc_server_send_new_channel_user(server, server->router->connection, + server->server_type == SILC_SERVER ? + FALSE : TRUE, + channel->id, SILC_ID_CHANNEL_LEN, + client->id, SILC_ID_CLIENT_LEN); + } /* Send USERS command reply to the joined channel so the user sees who is currently on the channel. */ - silc_server_command_send_users(server, sock, channel); - - /* - - FAQ: - - * Kuinka USERS komento händlätään serverissä kun router lähettää sen - serverille joka on lähettäny sille clientin puolesta JOIN komennon? - - R: Serverin pitää ymmärtää USERS comman replyjä. - - */ + silc_server_command_send_users(server, sock, channel, cmd->pending); silc_buffer_free(reply); silc_buffer_free(clidp); @@ -2846,23 +2778,25 @@ SILC_SERVER_CMD_FUNC(users) SilcChannelClientEntry chl; SilcChannelID *id; SilcBuffer packet; - unsigned char *tmp; - unsigned int tmp_len; + unsigned char *channel_id; + unsigned int channel_id_len; SilcBuffer client_id_list; SilcBuffer client_mode_list; SilcBuffer idp; + unsigned char lc[4]; + unsigned int list_count = 0; unsigned short ident = silc_command_get_ident(cmd->payload); SILC_SERVER_COMMAND_CHECK_ARGC(SILC_COMMAND_USERS, cmd, 1, 2); /* Get Channel ID */ - tmp = silc_argument_get_arg_type(cmd->args, 1, &tmp_len); - if (!tmp) { + channel_id = silc_argument_get_arg_type(cmd->args, 1, &channel_id_len); + if (!channel_id) { silc_server_command_send_status_reply(cmd, SILC_COMMAND_USERS, SILC_STATUS_ERR_NO_CHANNEL_ID); goto out; } - id = silc_id_payload_parse_id(tmp, tmp_len); + id = silc_id_payload_parse_id(channel_id, channel_id_len); /* If we are server and we don't know about this channel we will send the command to our router. If we know about the channel then we also @@ -2923,19 +2857,25 @@ SILC_SERVER_CMD_FUNC(users) /* Client's mode on channel */ SILC_PUT32_MSB(chl->mode, client_mode_list->data); silc_buffer_pull(client_mode_list, 4); + + list_count++; } silc_buffer_push(client_id_list, client_id_list->data - client_id_list->head); silc_buffer_push(client_mode_list, client_mode_list->data - client_mode_list->head); + /* List count */ + SILC_PUT32_MSB(list_count, lc); + /* Send reply */ packet = silc_command_reply_payload_encode_va(SILC_COMMAND_USERS, SILC_STATUS_OK, 0, 4, - 2, tmp, tmp_len, - 3, client_id_list->data, + 2, channel_id, channel_id_len, + 3, lc, 4, + 4, client_id_list->data, client_id_list->len, - 4, client_mode_list->data, + 5, client_mode_list->data, client_mode_list->len); silc_server_packet_send(server, cmd->sock, SILC_PACKET_COMMAND_REPLY, 0, packet->data, packet->len, FALSE); diff --git a/apps/silcd/command_reply.c b/apps/silcd/command_reply.c index 073bf822..d5f3dbff 100644 --- a/apps/silcd/command_reply.c +++ b/apps/silcd/command_reply.c @@ -325,10 +325,11 @@ silc_server_command_reply_identify_save(SilcServerCommandReplyContext cmd) } } - if (nickname && client->nickname) { + if (nickname && client->nickname) silc_free(client->nickname); + + if (nickname) client->nickname = nick; - } if (username && client->username) { silc_free(client->username); @@ -573,12 +574,23 @@ SILC_SERVER_CMD_REPLY_FUNC(users) /* We don't have that client anywhere, add it. The client is added to global list since server didn't have it in the lists so it must be global. */ - silc_idlist_add_client(server->global_list, NULL, NULL, NULL, - client_id, NULL, NULL); + client = silc_idlist_add_client(server->global_list, NULL, NULL, + NULL, client_id, cmd->sock->user_data, + NULL); } else { /* We have the client already. */ silc_free(client_id); } + + if (!silc_server_client_on_channel(client, channel)) { + /* Client was not on the channel, add it. */ + SilcChannelClientEntry chl = silc_calloc(1, sizeof(*chl)); + chl->client = client; + chl->mode = mode; + chl->channel = channel; + silc_list_add(channel->user_list, chl); + silc_list_add(client->channels, chl); + } } silc_buffer_free(client_id_list); diff --git a/apps/silcd/packet_receive.c b/apps/silcd/packet_receive.c index 890e4cd3..37575a32 100644 --- a/apps/silcd/packet_receive.c +++ b/apps/silcd/packet_receive.c @@ -325,7 +325,7 @@ void silc_server_replace_id(SilcServer server, we will broadcast it. The sending socket really cannot be router or the router is buggy. If this packet is coming from router then it must have the broadcast flag set already and we won't do anything. */ - if (server->server_type == SILC_ROUTER && + if (!server->standalone && server->server_type == SILC_ROUTER && sock->type == SILC_SOCKET_TYPE_SERVER && !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) { SILC_LOG_DEBUG(("Broadcasting received Replace ID packet")); diff --git a/apps/silcd/packet_send.c b/apps/silcd/packet_send.c index 70911cf0..3d89b506 100644 --- a/apps/silcd/packet_send.c +++ b/apps/silcd/packet_send.c @@ -395,10 +395,7 @@ void silc_server_packet_send_to_channel(SilcServer server, continue; } - if (server->server_type == SILC_ROUTER && !route) - continue; - - if (server->server_type == SILC_SERVER && client->router) + if (client && client->router) continue; /* Send to locally connected client */ diff --git a/apps/silcd/server.c b/apps/silcd/server.c index c562e868..4a55bac6 100644 --- a/apps/silcd/server.c +++ b/apps/silcd/server.c @@ -1630,10 +1630,11 @@ void silc_server_free_sock_user_data(SilcServer server, /* XXX must take some info to history before freeing */ /* Send REMOVE_ID packet to routers. */ - silc_server_send_remove_id(server, server->router->connection, - server->server_type == SILC_SERVER ? - FALSE : TRUE, user_data->id, - SILC_ID_CLIENT_LEN, SILC_ID_CLIENT); + if (!server->standalone) + silc_server_send_remove_id(server, server->router->connection, + server->server_type == SILC_SERVER ? + FALSE : TRUE, user_data->id, + SILC_ID_CLIENT_LEN, SILC_ID_CLIENT); /* Free the client entry and everything in it */ silc_idlist_del_data(user_data); diff --git a/apps/silcd/testi2.conf b/apps/silcd/testi2.conf index 4007fc60..984d93b2 100644 --- a/apps/silcd/testi2.conf +++ b/apps/silcd/testi2.conf @@ -16,10 +16,10 @@ sha1::64:20 Mun huone:Mun servo:Pekka Riikonen:priikone@poseidon.pspt.fi [ServerInfo] -lassi.kuo.fi.ssh.com:10.2.1.7:Kuopio, Finland:1334 +lassi.kuo.fi.ssh.com:212.146.8.246:Kuopio, Finland:1334 [ListenPort] -10.2.1.7:10.2.1.7:1334 +212.146.8.246:212.146.8.246:1334 [Logging] infologfile:silcd2.log:10000 @@ -40,10 +40,10 @@ errorlogfile:silcd2.log:10000 [AdminConnection] [ServerConnection] -10.2.1.7:passwd:priikone:1333:1:1 +212.146.8.246:passwd:priikone:1333:1:1 [RouterConnection] -10.2.1.7:passwd:priikone:1335:1:1:0 +212.146.8.246:passwd:priikone:1335:1:1:0 [DenyConnection] [RedirectClient] diff --git a/lib/silcclient/command.c b/lib/silcclient/command.c index c543ed90..bed90995 100644 --- a/lib/silcclient/command.c +++ b/lib/silcclient/command.c @@ -1172,6 +1172,7 @@ SILC_CLIENT_CMD_FUNC(users) SilcClientCommandContext cmd = (SilcClientCommandContext)context; SilcClientConnection conn = cmd->conn; SilcIDCacheEntry id_cache = NULL; + SilcChannelEntry channel; SilcBuffer buffer, idp; char *name; @@ -1213,25 +1214,79 @@ SILC_CLIENT_CMD_FUNC(users) goto out; } - /* Send USERS command to the server */ - idp = silc_id_payload_encode(id_cache->id, SILC_ID_CHANNEL); - buffer = silc_command_payload_encode_va(SILC_COMMAND_USERS, 0, 1, - 1, idp->data, idp->len); - silc_client_packet_send(cmd->client, conn->sock, SILC_PACKET_COMMAND, NULL, - 0, NULL, NULL, buffer->data, buffer->len, TRUE); - silc_buffer_free(buffer); - silc_buffer_free(idp); + channel = (SilcChannelEntry)id_cache->context; + + if (!cmd->pending) { + /* Send USERS command to the server */ + idp = silc_id_payload_encode(id_cache->id, SILC_ID_CHANNEL); + buffer = silc_command_payload_encode_va(SILC_COMMAND_USERS, 0, 1, + 1, idp->data, idp->len); + silc_client_packet_send(cmd->client, conn->sock, SILC_PACKET_COMMAND, + NULL, 0, NULL, NULL, buffer->data, + buffer->len, TRUE); + silc_buffer_free(buffer); + silc_buffer_free(idp); + + /* Register pending callback which will recall this command callback with + same context and reprocesses the command. When reprocessing we actually + display the information on the screen. */ + silc_client_command_pending(conn, SILC_COMMAND_USERS, 0, + silc_client_command_users, context); + cmd->pending = TRUE; + return; + } + + if (cmd->pending) { + /* Pending command. Now we've resolved the information from server and + we are ready to display the information on screen. */ + int i; + SilcChannelUser chu; + + cmd->client->ops->say(cmd->client, conn, "Users on %s", + channel->channel_name); - /* Register dummy pending command that will tell the reply command - that user called this command. Server may send reply to this command - even if user did not send this command thus we want to handle things - differently when user sent the command. This is dummy and won't be - executed. */ - /* XXX this is kludge and should be removed after pending command reply - support is added. Currently only commands may be pending not command - replies. */ - silc_client_command_pending(conn, SILC_COMMAND_USERS, 0, - silc_client_command_users, NULL); + silc_list_start(channel->clients); + while ((chu = silc_list_get(channel->clients)) != SILC_LIST_END) { + SilcClientEntry e = chu->client; + char *m, tmp[80], line[80], len1; + + memset(line, 0, sizeof(line)); + memset(tmp, 0, sizeof(tmp)); + m = silc_client_chumode_char(chu->mode); + + strcat(line, " "); + strcat(line, e->nickname); + strcat(line, e->server ? "@" : ""); + + len1 = 0; + if (e->server) + len1 = strlen(e->server); + strncat(line, e->server ? e->server : "", len1 > 30 ? 30 : len1); + + len1 = strlen(line); + if (len1 >= 30) { + memset(&line[29], 0, len1 - 29); + } else { + for (i = 0; i < 30 - len1 - 1; i++) + strcat(line, " "); + } + + strcat(line, " H"); + strcat(tmp, m ? m : ""); + strcat(line, tmp); + + if (strlen(tmp) < 5) + for (i = 0; i < 5 - strlen(tmp); i++) + strcat(line, " "); + + strcat(line, e->username ? e->username : ""); + + cmd->client->ops->say(cmd->client, conn, "%s", line); + + if (m) + silc_free(m); + } + } /* Notify application */ COMMAND; diff --git a/lib/silcclient/command.h b/lib/silcclient/command.h index dfe4f586..a9cb241a 100644 --- a/lib/silcclient/command.h +++ b/lib/silcclient/command.h @@ -70,12 +70,11 @@ typedef struct { unsigned char **argv; unsigned int *argv_lens; unsigned int *argv_types; + int pending; /* Command is being re-processed when TRUE */ } *SilcClientCommandContext; /* Structure holding pending commands. If command is pending it will be executed after command reply has been executed. */ -/* XXX This support may added for commands as well and not just command - replies, if needed later. */ typedef struct SilcClientCommandPendingStruct { SilcCommand reply_cmd; SilcCommandCb callback; diff --git a/lib/silcclient/command_reply.c b/lib/silcclient/command_reply.c index 51716566..85fa37da 100644 --- a/lib/silcclient/command_reply.c +++ b/lib/silcclient/command_reply.c @@ -1103,11 +1103,9 @@ SILC_CLIENT_CMD_REPLY_FUNC(users) SILC_GET16_MSB(idp_len, client_id_list->data + 2); idp_len += 4; client_id = silc_id_payload_parse_id(client_id_list->data, idp_len); - silc_buffer_pull(client_id_list, idp_len); /* Mode */ SILC_GET32_MSB(mode, client_mode_list->data); - silc_buffer_pull(client_mode_list, 4); /* Check if we have this client cached already. */ if (!silc_idcache_find_by_id_one(conn->client_cache, (void *)client_id, @@ -1135,6 +1133,9 @@ SILC_CLIENT_CMD_REPLY_FUNC(users) silc_free(client_id); id_cache = NULL; } + + silc_buffer_pull(client_id_list, idp_len); + silc_buffer_pull(client_mode_list, 4); } /* Query the client information from server if the list included clients @@ -1171,54 +1172,7 @@ SILC_CLIENT_CMD_REPLY_FUNC(users) /* We have all the clients on the channel cached now. Create a nice output for user interface and notify application. */ - if (cmd->callback) { - /* User has called USERS command on user interface. */ - cmd->client->ops->say(cmd->client, conn, "Users on %s", - channel->channel_name); - - silc_list_start(channel->clients); - while ((chu = silc_list_get(channel->clients)) != SILC_LIST_END) { - SilcClientEntry e = chu->client; - char *m, tmp[80], line[80], len1; - - memset(line, 0, sizeof(line)); - memset(tmp, 0, sizeof(tmp)); - m = silc_client_chumode_char(chu->mode); - - strcat(line, " "); - strcat(line, e->nickname); - strcat(line, e->server ? "@" : ""); - - len1 = 0; - if (e->server) - len1 = strlen(e->server); - strncat(line, e->server ? e->server : "", len1 > 30 ? 30 : len1); - - len1 = strlen(line); - if (len1 >= 30) { - memset(&line[29], 0, len1 - 29); - } else { - for (i = 0; i < 30 - len1 - 1; i++) - strcat(line, " "); - } - - strcat(line, " H"); - strcat(tmp, m ? m : ""); - strcat(line, tmp); - - if (strlen(tmp) < 5) - for (i = 0; i < 5 - strlen(tmp); i++) - strcat(line, " "); - - strcat(line, e->username ? e->username : ""); - - cmd->client->ops->say(cmd->client, conn, "%s", line); - - if (m) - silc_free(m); - } - - } else { + if (!cmd->callback) { /* Server has sent us USERS reply even when we haven't actually sent USERS command. This is normal behaviour when joining to a channel. Display some nice information on the user interface. */ diff --git a/lib/silcclient/idlist.c b/lib/silcclient/idlist.c index a14dc63e..9638ee12 100644 --- a/lib/silcclient/idlist.c +++ b/lib/silcclient/idlist.c @@ -123,7 +123,7 @@ SilcClientEntry silc_idlist_get_client_by_id(SilcClient client, } else { SilcBuffer idp = silc_id_payload_encode(client_id, SILC_ID_CLIENT); silc_client_send_command(client, conn, SILC_COMMAND_WHOIS, 1, - 2, idp->data, idp->len); + 3, idp->data, idp->len); return NULL; } }