SilcServerCommandContext cmd = (SilcServerCommandContext)context;
SilcServer server = cmd->server;
SilcBuffer packet, idp;
+ unsigned char *tmp;
+ unsigned int tmp_len;
char *dest_server, *server_info = NULL, *server_name;
unsigned short ident = silc_command_get_ident(cmd->payload);
SilcServerEntry entry = NULL;
+ SilcServerID *server_id = NULL;
- SILC_SERVER_COMMAND_CHECK_ARGC(SILC_COMMAND_INFO, cmd, 1, 1);
+ SILC_SERVER_COMMAND_CHECK_ARGC(SILC_COMMAND_INFO, cmd, 0, 2);
/* Get server name */
dest_server = silc_argument_get_arg_type(cmd->args, 1, NULL);
- if (!dest_server) {
- silc_server_command_send_status_reply(cmd, SILC_COMMAND_INFO,
- SILC_STATUS_ERR_NO_SUCH_SERVER);
- goto out;
+
+ /* Get Server ID */
+ tmp = silc_argument_get_arg_type(cmd->args, 2, &tmp_len);
+ if (tmp) {
+ server_id = silc_id_payload_parse_id(tmp, tmp_len);
+ if (!server_id) {
+ silc_server_command_send_status_reply(cmd, SILC_COMMAND_INFO,
+ SILC_STATUS_ERR_NO_SERVER_ID);
+ goto out;
+ }
}
- if (!strncasecmp(dest_server, server->server_name, strlen(dest_server))) {
+ if (server_id) {
+ /* Check whether we have this server cached */
+ entry = silc_idlist_find_server_by_id(server->local_list,
+ server_id, NULL);
+ if (!entry) {
+ entry = silc_idlist_find_server_by_id(server->global_list,
+ server_id, NULL);
+ if (!entry && server->server_type == SILC_ROUTER) {
+ silc_server_command_send_status_reply(cmd, SILC_COMMAND_INFO,
+ SILC_STATUS_ERR_NO_SUCH_SERVER);
+ goto out;
+ }
+ }
+ }
+
+ if ((!dest_server && !server_id) ||
+ (dest_server && !cmd->pending &&
+ !strncasecmp(dest_server, server->server_name, strlen(dest_server)))) {
/* Send our reply */
char info_string[256];
entry = server->id_entry;
} else {
/* Check whether we have this server cached */
- entry = silc_idlist_find_server_by_name(server->global_list,
- dest_server, NULL);
- if (!entry) {
- entry = silc_idlist_find_server_by_name(server->local_list,
+ if (!entry && dest_server) {
+ entry = silc_idlist_find_server_by_name(server->global_list,
dest_server, NULL);
+ if (!entry) {
+ entry = silc_idlist_find_server_by_name(server->local_list,
+ dest_server, NULL);
+ }
}
- if (server->server_type == SILC_ROUTER && entry && !entry->server_info) {
+ if (!cmd->pending &&
+ server->server_type == SILC_ROUTER && entry && !entry->server_info) {
/* Send to the server */
SilcBuffer tmpbuf;
unsigned short old_ident;
}
}
+ if (server_id)
+ silc_free(server_id);
+
if (!entry) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_INFO,
SILC_STATUS_ERR_NO_SUCH_SERVER);
idp = silc_id_payload_encode(entry->id, SILC_ID_SERVER);
if (!server_info)
server_info = entry->server_info;
- server_name = dest_server;
+ server_name = entry->server_name;
/* Send the reply */
packet = silc_command_reply_payload_encode_va(SILC_COMMAND_INFO,
silc_server_send_notify_cmode(server, server->router->connection,
server->server_type == SILC_ROUTER ?
TRUE : FALSE, channel,
- mode_mask, client->id, SILC_ID_CLIENT_LEN,
+ mode_mask, client->id, SILC_ID_CLIENT,
+ SILC_ID_CLIENT_LEN,
cipher, hmac);
/* Send command reply to sender */
SilcNotifyType type;
SilcArgumentPayload args;
+ SilcIDPayload idp;
SilcClientID *client_id = NULL;
SilcChannelID *channel_id = NULL;
SilcClientEntry client_entry;
if (!tmp)
goto out;
- client_id = silc_id_payload_parse_id(tmp, tmp_len);
- if (!client_id)
+ idp = silc_id_payload_parse_data(tmp, tmp_len);
+ if (!idp)
goto out;
/* Find Client entry */
- client_entry =
- silc_client_get_client_by_id(client, conn, client_id);
- if (!client_entry)
- goto out;
+ if (silc_id_payload_get_type(idp) == SILC_ID_CLIENT) {
+ client_id = silc_id_payload_parse_id(tmp, tmp_len);
+ if (!client_id) {
+ silc_id_payload_free(idp);
+ goto out;
+ }
+
+ client_entry = silc_client_get_client_by_id(client, conn, client_id);
+ if (!client_entry) {
+ silc_id_payload_free(idp);
+ goto out;
+ }
+ } else {
+ client_entry = NULL;
+ }
+
+ silc_id_payload_free(idp);
/* Get the mode */
tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
channel = (SilcChannelEntry)id_cache->context;
/* Free the old ID */
- silc_free(channel_id);
silc_free(channel->id);
/* Get the new ID */