ctx->users));
if (ctx->users < 1) {
if (ctx->payload)
- silc_command_free_payload(ctx->payload);
+ silc_command_payload_free(ctx->payload);
if (ctx->packet)
silc_packet_context_free(ctx->packet);
if (ctx->sock)
SilcClientEntry entry;
SilcCommandStatus status;
uint16 ident = silc_command_get_ident(cmd->payload);
- char nh[128], uh[128];
+ char nh[256], uh[256];
unsigned char idle[4], mode[4];
SilcSocketConnection hsock;
if (entry->data.registered == FALSE) {
if (clients_count == 1) {
- SilcBuffer idp = silc_id_payload_encode(entry->id, SILC_ID_CLIENT);
- silc_server_command_send_status_data(cmd, SILC_COMMAND_WHOIS,
- SILC_STATUS_ERR_NO_SUCH_CLIENT_ID,
- 2, idp->data, idp->len);
- silc_buffer_free(idp);
+ if (entry->nickname) {
+ silc_server_command_send_status_data(cmd, SILC_COMMAND_WHOIS,
+ SILC_STATUS_ERR_NO_SUCH_NICK,
+ 3, entry->nickname,
+ strlen(entry->nickname));
+ } else {
+ SilcBuffer idp = silc_id_payload_encode(entry->id, SILC_ID_CLIENT);
+ silc_server_command_send_status_data(cmd, SILC_COMMAND_WHOIS,
+ SILC_STATUS_ERR_NO_SUCH_CLIENT_ID,
+ 2, idp->data, idp->len);
+ silc_buffer_free(idp);
+ }
}
continue;
}
silc_server_send_notify_nick_change(server, server->router->connection,
server->server_type == SILC_SERVER ?
FALSE : TRUE, client->id,
- new_id, SILC_ID_CLIENT_LEN);
+ new_id);
/* Remove old cache entry */
- silc_idcache_del_by_id(server->local_list->clients, SILC_ID_CLIENT,
- client->id);
+ silc_idcache_del_by_context(server->local_list->clients, client);
oidp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
/* Free old ID */
- if (client->id) {
- memset(client->id, 0, SILC_ID_CLIENT_LEN);
+ if (client->id)
silc_free(client->id);
- }
/* Save the nickname as this client is our local client */
if (client->nickname)
/* Update client cache */
silc_idcache_add(server->local_list->clients, client->nickname,
- strlen(client->nickname), SILC_ID_CLIENT, client->id,
- (void *)client, TRUE, FALSE);
+ client->id, (void *)client, FALSE);
nidp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
memset(usercount, 0, sizeof(usercount));
} else {
topic = entry->topic;
- users = silc_list_count(entry->user_list);
+ users = silc_hash_table_count(entry->user_list);
SILC_PUT32_MSB(users, usercount);
}
memset(usercount, 0, sizeof(usercount));
} else {
topic = entry->topic;
- users = silc_list_count(entry->user_list);
+ users = silc_hash_table_count(entry->user_list);
SILC_PUT32_MSB(users, usercount);
}
goto out;
}
- /* See whether has rights to change topic */
- silc_list_start(channel->user_list);
- while ((chl = silc_list_get(channel->user_list)) != SILC_LIST_END)
- if (chl->client == client)
- break;
+ /* See whether the client is on channel and has rights to change topic */
+ if (!silc_hash_table_find(channel->user_list, client, NULL,
+ (void *)&chl)) {
+ silc_server_command_send_status_reply(cmd, SILC_COMMAND_TOPIC,
+ SILC_STATUS_ERR_NOT_ON_CHANNEL);
+ goto out;
+ }
if (chl->mode == SILC_CHANNEL_UMODE_NONE) {
if (channel->mode & SILC_CHANNEL_MODE_TOPIC) {
silc_server_send_notify_topic_set(server, server->router->connection,
server->server_type == SILC_ROUTER ?
TRUE : FALSE, channel, client->id,
- SILC_ID_CLIENT_LEN, channel->topic);
+ channel->topic);
idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
/* Check whether the channel is invite-only channel. If yes then the
sender of this command must be at least channel operator. */
if (channel->mode & SILC_CHANNEL_MODE_INVITE) {
- silc_list_start(channel->user_list);
- while ((chl = silc_list_get(channel->user_list)) != SILC_LIST_END)
- if (chl->client == sender) {
- if (chl->mode == SILC_CHANNEL_UMODE_NONE) {
- silc_server_command_send_status_reply(cmd, SILC_COMMAND_INVITE,
- SILC_STATUS_ERR_NO_CHANNEL_PRIV);
- goto out;
- }
- break;
- }
+ silc_hash_table_find(channel->user_list, sender, NULL, (void *)&chl);
+ if (chl->mode == SILC_CHANNEL_UMODE_NONE) {
+ silc_server_command_send_status_reply(cmd, SILC_COMMAND_INVITE,
+ SILC_STATUS_ERR_NO_CHANNEL_PRIV);
+ goto out;
+ }
}
/* Get destination client ID */
/* Get route to the client */
dest_sock = silc_server_get_client_route(server, NULL, 0, dest_id, &idata);
+ if (!dest_sock) {
+ silc_server_command_send_status_reply(cmd, SILC_COMMAND_INVITE,
+ SILC_STATUS_ERR_NO_SUCH_CLIENT_ID);
+ goto out;
+ }
memset(invite, 0, sizeof(invite));
strncat(invite, dest->nickname, strlen(dest->nickname));
silc_server_send_notify_invite(server, server->router->connection,
server->server_type == SILC_ROUTER ?
TRUE : FALSE, channel,
- sender->id, SILC_ID_CLIENT_LEN,
- add, del);
+ sender->id, add, del);
/* Send command reply */
tmp = silc_argument_get_arg_type(cmd->args, 1, &len);
- packet = silc_command_reply_payload_encode_va(SILC_COMMAND_INVITE,
- SILC_STATUS_OK, ident, 2,
- 2, tmp, len,
- 3, channel->invite_list,
- channel->invite_list ?
- strlen(channel->invite_list) :
- 0);
+
+ if (add || del)
+ packet =
+ silc_command_reply_payload_encode_va(SILC_COMMAND_INVITE,
+ SILC_STATUS_OK, ident, 2,
+ 2, tmp, len,
+ 3, channel->invite_list,
+ channel->invite_list ?
+ strlen(channel->invite_list) : 0);
+ else
+ packet =
+ silc_command_reply_payload_encode_va(SILC_COMMAND_INVITE,
+ SILC_STATUS_OK, ident, 1,
+ 2, tmp, len);
silc_server_packet_send(server, cmd->sock, SILC_PACKET_COMMAND_REPLY, 0,
packet->data, packet->len, FALSE);
silc_buffer_free(packet);
}
}
+ if (remote_client->data.registered == FALSE) {
+ silc_server_command_send_status_reply(cmd, SILC_COMMAND_KILL,
+ SILC_STATUS_ERR_NO_SUCH_CLIENT_ID);
+ goto out;
+ }
+
/* Get comment */
comment = silc_argument_get_arg_type(cmd->args, 2, &tmp_len2);
if (tmp_len2 > 128)
/* Send KILLED notify to primary route */
if (!server->standalone)
silc_server_send_notify_killed(server, server->router->connection, TRUE,
- remote_client->id, SILC_ID_CLIENT_LEN,
- comment);
+ remote_client->id, comment);
/* Send KILLED notify to the client directly */
silc_server_send_notify_killed(server, remote_client->connection ?
remote_client->connection :
remote_client->router->connection, FALSE,
- remote_client->id, SILC_ID_CLIENT_LEN,
- comment);
+ remote_client->id, comment);
/* Remove the client from all channels. This generates new keys to the
channels as well. */
server_name = entry->server_name;
/* Send the reply */
- packet = silc_command_reply_payload_encode_va(SILC_COMMAND_INFO,
- SILC_STATUS_OK, ident, 3,
- 2, idp->data, idp->len,
- 3, server_name,
- strlen(server_name),
- 4, server_info,
- strlen(server_info));
+ if (server_info)
+ packet = silc_command_reply_payload_encode_va(SILC_COMMAND_INFO,
+ SILC_STATUS_OK, ident, 3,
+ 2, idp->data, idp->len,
+ 3, server_name,
+ strlen(server_name),
+ 4, server_info,
+ strlen(server_info));
+ else
+ packet = silc_command_reply_payload_encode_va(SILC_COMMAND_INFO,
+ SILC_STATUS_OK, ident, 2,
+ 2, idp->data, idp->len,
+ 3, server_name,
+ strlen(server_name));
silc_server_packet_send(server, cmd->sock, SILC_PACKET_COMMAND_REPLY, 0,
packet->data, packet->len, FALSE);
if (!id)
goto out;
- if (!SILC_ID_SERVER_COMPARE(id, server->id)) {
+ if (SILC_ID_SERVER_COMPARE(id, server->id)) {
/* Send our reply */
silc_server_command_send_status_reply(cmd, SILC_COMMAND_PING,
SILC_STATUS_OK);
/* Check user count limit if set. */
if (channel->mode & SILC_CHANNEL_MODE_ULIMIT) {
- if (silc_list_count(channel->user_list) + 1 >
+ if (silc_hash_table_count(channel->user_list) + 1 >
channel->user_limit) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_JOIN,
SILC_STATUS_ERR_CHANNEL_IS_FULL);
}
/* Generate new channel key as protocol dictates */
- if ((!created && silc_list_count(channel->user_list) > 0) ||
+ if ((!created && silc_hash_table_count(channel->user_list) > 0) ||
!channel->channel_key)
silc_server_create_channel_key(server, channel, 0);
chl->mode = umode;
chl->client = client;
chl->channel = channel;
- silc_list_add(channel->user_list, chl);
- silc_list_add(client->channels, chl);
+ silc_hash_table_add(channel->user_list, client, chl);
+ silc_hash_table_add(client->channels, channel, chl);
/* Get users on the channel */
silc_server_get_users_on_channel(server, channel, &user_list, &mode_list,
if (!server->standalone)
silc_server_send_notify_join(server, server->router->connection,
server->server_type == SILC_ROUTER ?
- TRUE : FALSE, channel, client->id,
- SILC_ID_CLIENT_LEN);
+ TRUE : FALSE, channel, client->id);
}
silc_buffer_free(reply);
be same as the client's ID. */
if (cmd->sock->type == SILC_SOCKET_TYPE_CLIENT) {
SilcClientEntry entry = (SilcClientEntry)cmd->sock->user_data;
- if (SILC_ID_CLIENT_COMPARE(entry->id, client_id)) {
+ if (!SILC_ID_CLIENT_COMPARE(entry->id, client_id)) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_JOIN,
SILC_STATUS_ERR_NOT_ENOUGH_PARAMS);
goto out;
/* If the channel does not have global users and is also empty it means the
channel was created globally (by our router) and the client will be the
channel founder and operator. */
- if (!channel->global_users && silc_list_count(channel->user_list) == 0) {
+ if (!channel->global_users && !silc_hash_table_count(channel->user_list)) {
umode = (SILC_CHANNEL_UMODE_CHANOP | SILC_CHANNEL_UMODE_CHANFO);
created = TRUE; /* Created globally by our router */
}
/* Send UMODE change to primary router */
if (!server->standalone)
silc_server_send_notify_umode(server, server->router->connection, TRUE,
- client->id, SILC_ID_CLIENT_LEN,
- client->mode);
+ client->id, client->mode);
/* Send command reply to sender */
packet = silc_command_reply_payload_encode_va(SILC_COMMAND_UMODE,
}
/* Get entry to the channel user list */
- silc_list_start(channel->user_list);
- while ((chl = silc_list_get(channel->user_list)) != SILC_LIST_END)
- if (chl->client == client)
- break;
+ silc_hash_table_find(channel->user_list, client, NULL, (void *)&chl);
/* Check that client has rights to change any requested channel modes */
if (!silc_server_check_cmode_rights(channel, chl, mode_mask)) {
server->server_type == SILC_ROUTER ?
TRUE : FALSE, channel,
mode_mask, client->id, SILC_ID_CLIENT,
- SILC_ID_CLIENT_LEN,
cipher, hmac);
/* Send command reply to sender */
}
/* Check that client has rights to change other's rights */
- silc_list_start(channel->user_list);
- while ((chl = silc_list_get(channel->user_list)) != SILC_LIST_END) {
- if (chl->client == client) {
- sender_mask = chl->mode;
- break;
- }
- }
+ silc_hash_table_find(channel->user_list, client, NULL, (void *)&chl);
+ sender_mask = chl->mode;
/* Get the target client's channel mode mask */
tmp_mask = silc_argument_get_arg_type(cmd->args, 2, NULL);
}
/* Get entry to the channel user list */
- silc_list_start(channel->user_list);
- while ((chl = silc_list_get(channel->user_list)) != SILC_LIST_END)
- if (chl->client == target_client)
- break;
+ silc_hash_table_find(channel->user_list, target_client, NULL,
+ (void *)&chl);
}
/*
server->server_type == SILC_ROUTER ?
TRUE : FALSE, channel,
target_mask, client->id,
- SILC_ID_CLIENT_LEN,
- target_client->id,
- SILC_ID_CLIENT_LEN);
+ SILC_ID_CLIENT,
+ target_client->id);
}
/* Send command reply to sender */
}
/* Check that the kicker is channel operator or channel founder */
- silc_list_start(channel->user_list);
- while ((chl = silc_list_get(channel->user_list)) != SILC_LIST_END) {
- if (chl->client == client) {
- if (chl->mode == SILC_CHANNEL_UMODE_NONE) {
- silc_server_command_send_status_reply(cmd, SILC_COMMAND_KICK,
- SILC_STATUS_ERR_NO_CHANNEL_PRIV);
- goto out;
- }
- break;
- }
+ silc_hash_table_find(channel->user_list, client, NULL, (void *)&chl);
+ if (chl->mode == SILC_CHANNEL_UMODE_NONE) {
+ silc_server_command_send_status_reply(cmd, SILC_COMMAND_KICK,
+ SILC_STATUS_ERR_NO_CHANNEL_PRIV);
+ goto out;
}
/* Get target Client ID */
/* Check that the target client is not channel founder. Channel founder
cannot be kicked from the channel. */
- silc_list_start(channel->user_list);
- while ((chl = silc_list_get(channel->user_list)) != SILC_LIST_END) {
- if (chl->client == target_client) {
- if (chl->mode & SILC_CHANNEL_UMODE_CHANFO) {
- silc_server_command_send_status_reply(cmd, SILC_COMMAND_KICK,
- SILC_STATUS_ERR_NO_CHANNEL_FOPRIV);
- goto out;
- }
- break;
- }
+ silc_hash_table_find(channel->user_list, target_client, NULL, (void *)&chl);
+ if (chl->mode & SILC_CHANNEL_UMODE_CHANFO) {
+ silc_server_command_send_status_reply(cmd, SILC_COMMAND_KICK,
+ SILC_STATUS_ERR_NO_CHANNEL_FOPRIV);
+ goto out;
}
/* Check whether target client is on the channel */
silc_server_send_notify_kicked(server, server->router->connection,
server->server_type == SILC_ROUTER ?
TRUE : FALSE, channel,
- target_client->id, SILC_ID_CLIENT_LEN,
- comment);
+ target_client->id, comment);
if (!(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) {
/* Re-generate channel key */
/* Send UMODE change to primary router */
if (!server->standalone)
silc_server_send_notify_umode(server, server->router->connection, TRUE,
- client->id, SILC_ID_CLIENT_LEN,
- client->mode);
+ client->id, client->mode);
/* Send reply to the sender */
silc_server_command_send_status_reply(cmd, SILC_COMMAND_OPER,
/* Send UMODE change to primary router */
if (!server->standalone)
silc_server_send_notify_umode(server, server->router->connection, TRUE,
- client->id, SILC_ID_CLIENT_LEN,
- client->mode);
+ client->id, client->mode);
/* Send reply to the sender */
silc_server_command_send_status_reply(cmd, SILC_COMMAND_SILCOPER,
}
/* Get entry to the channel user list */
- silc_list_start(channel->user_list);
- while ((chl = silc_list_get(channel->user_list)) != SILC_LIST_END)
- if (chl->client == client)
- break;
+ silc_hash_table_find(channel->user_list, client, NULL, (void *)&chl);
/* The client must be at least channel operator. */
if (!(chl->mode & SILC_CHANNEL_UMODE_CHANOP)) {
if (!server->standalone)
silc_server_send_notify_leave(server, server->router->connection,
server->server_type == SILC_ROUTER ?
- TRUE : FALSE, channel, id_entry->id,
- SILC_ID_CLIENT_LEN);
+ TRUE : FALSE, channel, id_entry->id);
silc_server_command_send_status_reply(cmd, SILC_COMMAND_LEAVE,
SILC_STATUS_OK);
FALSE : !server->standalone);
}
- silc_free(id);
-
out:
if (id)
silc_free(id);
SilcBuffer pk;
SilcIdType id_type;
+ SILC_LOG_DEBUG(("Start"));
+
tmp = silc_argument_get_arg_type(cmd->args, 1, &tmp_len);
if (!tmp) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_GETKEY,
would be locally connected client so send the command further. */
client = silc_idlist_find_client_by_id(server->local_list,
client_id, NULL);
+ if (!client)
+ client = silc_idlist_find_client_by_id(server->global_list,
+ client_id, NULL);
if ((!client && !cmd->pending && !server->standalone) ||
- (client && !client->connection)) {
+ (client && !client->connection && !cmd->pending &&
+ !server->standalone) ||
+ (client && !client->data.public_key && !cmd->pending &&
+ !server->standalone)) {
SilcBuffer tmpbuf;
uint16 old_ident;
SilcSocketConnection dest_sock;
would be locally connected server so send the command further. */
server_entry = silc_idlist_find_server_by_id(server->local_list,
server_id, NULL);
+ if (!server_entry)
+ server_entry = silc_idlist_find_server_by_id(server->global_list,
+ server_id, NULL);
if ((!server_entry && !cmd->pending && !server->standalone) ||
- (server_entry && !server_entry->connection)) {
+ (server_entry && !server_entry->connection && !cmd->pending &&
+ !server->standalone) ||
+ (server_entry && !server_entry->data.public_key && !cmd->pending &&
+ !server->standalone)) {
SilcBuffer tmpbuf;
uint16 old_ident;