+Sat Feb 24 16:03:45 EET 2001 Pekka Riikonen <priikone@poseidon.pspt.fi>
+
+ * Added SILC_NOTIFY_TYPE_KICKED to indicate that the client
+ or some other client was kicked from the channel.
+
+ Implemented the handling of the notify type to both client
+ and server.
+
+ Implemented silc_server_send_notify_kicked to send the KICKED
+ notify. It is used to send it to the server's primary router.
+
+ * Implemented the KICK command into server and client.
+
+ * Added `query' argument to the silc_idlist_get_client function
+ to indicate whether to query the client from server or not if
+ it was not found.
+
+ * Added new command status type SILC_STATUS_ERR_NO_CHANNEL_FOPRIV
+ to indicate that the client is not channel founder.
+
Sat Feb 24 00:00:55 EET 2001 Pekka Riikonen <priikone@poseidon.pspt.fi>
* Removed the rng context from SilcPacketContext structure and
handling multiple same nicknames with this command is
still missing.
+ /KICK <channel> <nickname>[@<server>] [<comment>]
+
+ Kicks client from channel. You have to be at least channel
+ operator to be able to kick client from channel. Note:
+ you cannot kick channel founder even if you are channel
+ operator.
+
/PING [<server>]
Pings server. Only locally connected server may be
case SILC_NOTIFY_TYPE_CHANNEL_CHANGE:
break;
+ case SILC_NOTIFY_TYPE_KICKED:
+ client_entry = va_arg(vp, SilcClientEntry);
+ tmp = va_arg(vp, char *);
+ channel_entry = va_arg(vp, SilcChannelEntry);
+
+ if (client_entry == conn->local_entry) {
+ snprintf(message, sizeof(message),
+ "You have been kicked off channel %s %s%s%s",
+ conn->current_channel->channel_name,
+ tmp ? "(" : "", tmp ? tmp : "", tmp ? ")" : "");
+ } else {
+ snprintf(message, sizeof(message),
+ "%s%s%s has been kicked off channel %s %s%s%s",
+ client_entry->nickname,
+ client_entry->server ? "@" : "",
+ client_entry->server ? client_entry->server : "",
+ conn->current_channel->channel_name,
+ tmp ? "(" : "", tmp ? tmp : "", tmp ? ")" : "");
+ }
+ break;
+
default:
break;
}
/*
* $Id$
* $Log$
+ * Revision 1.6 2001/02/24 15:50:23 priikone
+ * implemented KICK command
+ *
* Revision 1.5 2001/02/19 13:47:30 priikone
* updates.
*
}
/* Find client entry */
- client_entry = silc_idlist_get_client(client, conn, nickname, server, num);
+ client_entry = silc_idlist_get_client(client, conn, nickname, server, num,
+ TRUE);
if (!client_entry) {
/* Client entry not found, it was requested thus mark this to be
pending command. */
if (!tmp) {
if (!(channel->mode & SILC_CHANNEL_MODE_ULIMIT)) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_CMODE,
- SILC_STATUS_ERR_NOT_ENOUGH_PARAMS);
+ SILC_STATUS_ERR_NOT_ENOUGH_PARAMS);
goto out;
}
} else {
tmp = silc_argument_get_arg_type(cmd->args, 4, NULL);
if (!tmp) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_CMODE,
- SILC_STATUS_ERR_NOT_ENOUGH_PARAMS);
+ SILC_STATUS_ERR_NOT_ENOUGH_PARAMS);
goto out;
}
tmp = silc_argument_get_arg_type(cmd->args, 5, NULL);
if (!tmp) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_CMODE,
- SILC_STATUS_ERR_NOT_ENOUGH_PARAMS);
+ SILC_STATUS_ERR_NOT_ENOUGH_PARAMS);
goto out;
}
tmp = silc_argument_get_arg_type(cmd->args, 6, NULL);
if (!tmp) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_CMODE,
- SILC_STATUS_ERR_NOT_ENOUGH_PARAMS);
+ SILC_STATUS_ERR_NOT_ENOUGH_PARAMS);
goto out;
}
tmp_id = silc_argument_get_arg_type(cmd->args, 3, &tmp_len);
if (!tmp_id) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
- SILC_STATUS_ERR_NO_CHANNEL_ID);
+ SILC_STATUS_ERR_NO_CLIENT_ID);
goto out;
}
client_id = silc_id_payload_parse_id(tmp_id, tmp_len);
if (!client_id) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
- SILC_STATUS_ERR_NO_CHANNEL_ID);
+ SILC_STATUS_ERR_NO_CLIENT_ID);
goto out;
}
SILC_SERVER_CMD_FUNC(kick)
{
+ SilcServerCommandContext cmd = (SilcServerCommandContext)context;
+ SilcServer server = cmd->server;
+ SilcClientEntry client = (SilcClientEntry)cmd->sock->user_data;
+ SilcClientEntry target_client;
+ SilcChannelID *channel_id;
+ SilcClientID *client_id;
+ SilcChannelEntry channel;
+ SilcChannelClientEntry chl;
+ SilcBuffer idp;
+ unsigned int tmp_len;
+ unsigned char *tmp, *comment;
+
+ SILC_SERVER_COMMAND_CHECK_ARGC(SILC_COMMAND_LEAVE, cmd, 1, 3);
+
+ /* Get Channel ID */
+ tmp = silc_argument_get_arg_type(cmd->args, 1, &tmp_len);
+ if (!tmp) {
+ silc_server_command_send_status_reply(cmd, SILC_COMMAND_KICK,
+ SILC_STATUS_ERR_NO_CHANNEL_ID);
+ goto out;
+ }
+ channel_id = silc_id_payload_parse_id(tmp, tmp_len);
+ if (!channel_id) {
+ silc_server_command_send_status_reply(cmd, SILC_COMMAND_KICK,
+ SILC_STATUS_ERR_NO_CHANNEL_ID);
+ goto out;
+ }
+
+ /* Get channel entry */
+ channel = silc_idlist_find_channel_by_id(server->local_list,
+ channel_id, NULL);
+ if (!channel) {
+ silc_server_command_send_status_reply(cmd, SILC_COMMAND_KICK,
+ SILC_STATUS_ERR_NO_SUCH_CHANNEL);
+ goto out;
+ }
+
+ /* Check whether sender is on the channel */
+ if (!silc_server_client_on_channel(client, channel)) {
+ silc_server_command_send_status_reply(cmd, SILC_COMMAND_KICK,
+ SILC_STATUS_ERR_NOT_ON_CHANNEL);
+ goto out;
+ }
+
+ /* 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;
+ }
+ }
+
+ /* Get target Client ID */
+ tmp = silc_argument_get_arg_type(cmd->args, 2, &tmp_len);
+ if (!tmp) {
+ silc_server_command_send_status_reply(cmd, SILC_COMMAND_KICK,
+ SILC_STATUS_ERR_NO_CLIENT_ID);
+ goto out;
+ }
+ client_id = silc_id_payload_parse_id(tmp, tmp_len);
+ if (!client_id) {
+ silc_server_command_send_status_reply(cmd, SILC_COMMAND_KICK,
+ SILC_STATUS_ERR_NO_CLIENT_ID);
+ goto out;
+ }
+
+ /* Get target client's entry */
+ target_client = silc_idlist_find_client_by_id(server->local_list,
+ client_id, NULL);
+ if (!target_client) {
+ target_client = silc_idlist_find_client_by_id(server->global_list,
+ client_id, NULL);
+ }
+
+ /* 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;
+ }
+ }
+
+ /* Check whether target client is on the channel */
+ if (!silc_server_client_on_channel(target_client, channel)) {
+ silc_server_command_send_status_reply(cmd, SILC_COMMAND_KICK,
+ SILC_STATUS_ERR_USER_NOT_ON_CHANNEL);
+ goto out;
+ }
+
+ /* Get comment */
+ tmp_len = 0;
+ comment = silc_argument_get_arg_type(cmd->args, 3, &tmp_len);
+ if (tmp_len > 128)
+ comment = NULL;
+
+ /* Send command reply to sender */
+ silc_server_command_send_status_reply(cmd, SILC_COMMAND_KICK,
+ SILC_STATUS_OK);
+
+ /* Send KICKED notify to local clients on the channel */
+ idp = silc_id_payload_encode(target_client->id, SILC_ID_CLIENT);
+ silc_server_send_notify_to_channel(server, NULL, channel, FALSE,
+ SILC_NOTIFY_TYPE_KICKED,
+ comment ? 2 : 1,
+ idp->data, idp->len,
+ comment, comment ? strlen(comment) : 0);
+ silc_buffer_free(idp);
+
+ /* Remove the client from the channel. If the channel does not exist
+ after removing the client then the client kicked itself of the channel
+ and we don't have to send anything after that. */
+ if (!silc_server_remove_from_one_channel(server, NULL, channel,
+ target_client, FALSE))
+ goto out;
+
+ /* Send KICKED notify to primary route */
+ if (!server->standalone)
+ 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);
+
+ /* Re-generate channel key */
+ silc_server_create_channel_key(server, channel, 0);
+
+ /* Send the channel key to the channel. The key of course is not sent
+ to the client who joined the channel. */
+ silc_server_send_channel_key(server, target_client->connection, channel,
+ server->server_type == SILC_ROUTER ?
+ FALSE : server->standalone);
+
+ out:
+ silc_server_command_free(cmd);
}
SILC_SERVER_CMD_FUNC(restart)
SILC_LOG_DEBUG(("SERVER SIGNOFF notify (not-impl XXX)"));
break;
+ case SILC_NOTIFY_TYPE_KICKED:
+ /*
+ * Distribute the notify to local clients on the channel
+ */
+
+ SILC_LOG_DEBUG(("KICKED notify"));
+
+ channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
+ packet->dst_id_type);
+ if (!channel_id)
+ goto out;
+
+ /* Get channel entry */
+ channel = silc_idlist_find_channel_by_id(server->local_list,
+ channel_id, NULL);
+ if (!channel) {
+ channel = silc_idlist_find_channel_by_id(server->global_list,
+ channel_id, NULL);
+ if (!channel) {
+ silc_free(channel_id);
+ goto out;
+ }
+ }
+ silc_free(channel_id);
+
+ /* Get client ID */
+ tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
+ if (!tmp)
+ goto out;
+ client_id = silc_id_payload_parse_id(tmp, tmp_len);
+ if (!client_id)
+ goto out;
+
+ /* Send to channel */
+ silc_server_packet_send_to_channel(server, sock, channel, packet->type,
+ FALSE, packet->buffer->data,
+ packet->buffer->len, FALSE);
+
+ /* If the the client is not in local list we check global list */
+ 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) {
+ silc_free(client_id);
+ goto out;
+ }
+ }
+
+ /* Remove the client from channel */
+ silc_server_remove_from_one_channel(server, sock, channel, client, FALSE);
+
+ break;
+
/* Ignore rest of the notify types for now */
case SILC_NOTIFY_TYPE_NONE:
case SILC_NOTIFY_TYPE_MOTD:
silc_buffer_free(idp);
}
+/* Send KICKED notify type. This tells that the `client_id' on `channel'
+ was kicked off the channel. The `comment' may indicate the reason
+ for the kicking. This function is used only between server and router
+ traffic. */
+
+void silc_server_send_notify_kicked(SilcServer server,
+ SilcSocketConnection sock,
+ int broadcast,
+ SilcChannelEntry channel,
+ SilcClientID *client_id,
+ unsigned int client_id_len,
+ char *comment)
+{
+ SilcBuffer idp;
+
+ idp = silc_id_payload_encode((void *)client_id, SILC_ID_CLIENT);
+ silc_server_send_notify_dest(server, sock, broadcast, (void *)channel->id,
+ SILC_ID_CHANNEL, SILC_NOTIFY_TYPE_KICKED,
+ comment ? 2 : 1, idp->data, idp->len,
+ comment, comment ? strlen(comment) : 0);
+ silc_buffer_free(idp);
+}
+
/* Sends notify message destined to specific entity. */
void silc_server_send_notify_dest(SilcServer server,
}
/* Sends notify message to a channel. The notify message sent is
- distributed to all clients on the channel. If `router_notify' is TRUE
+ distributed to all clients on the channel. If `route_notify' is TRUE
then the notify may be routed to primary route or to some other routers.
If FALSE it is assured that the notify is sent only locally. If `sender'
is provided then the packet is not sent to that connection since it
SilcClientID *client_id,
unsigned int client_id_len,
char *topic);
+void silc_server_send_notify_kicked(SilcServer server,
+ SilcSocketConnection sock,
+ int broadcast,
+ SilcChannelEntry channel,
+ SilcClientID *client_id,
+ unsigned int client_id_len,
+ char *comment);
void silc_server_send_notify_dest(SilcServer server,
SilcSocketConnection sock,
int broadcast,
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.42.253:Kuopio, Finland:1334
[ListenPort]
-10.2.1.7:10.2.1.7:1334
+212.146.42.253:212.146.42.253:1334
[Logging]
infologfile:silcd2.log:10000
[AdminConnection]
[ServerConnection]
-10.2.1.7:passwd:priikone:1333:1:1
+212.146.42.253:passwd:priikone:1333:1:1
[RouterConnection]
-10.2.1.7:passwd:priikone:1335:1:1:0
+212.146.42.253:passwd:priikone:1335:1:1:0
[DenyConnection]
[RedirectClient]
Sent when client has joined to a channel. The server must distribute
this type only to the local clients on the channel and then send
- it to its primary router. The router or server receiving the packet
+ it to its primary router. The router or server receiving the packet
distributes this type to the local clients on the channel and
broadcast it to the network.
Sent when client has left a channel. The server must distribute
this type only to the local clients on the channel and then send
- it to its primary router. The router or server receiving the packet
+ it to its primary router. The router or server receiving the packet
distributes this type to the local clients on the channel and
broadcast it to the network.
Sent when client signoffs from SILC network. The server must
distribute this type only to the local clients on the channel and
- then send it to its primary router. The router or server receiving
+ then send it to its primary router. The router or server receiving
the packet distributes this type to the local clients on the channel
and broadcast it to the network.
The <Server ID> is the server's ID.
+
+12 SILC_NOTIFY_TYPE_KICKED
+
+ Sent when a client has been kicked from a channel. This is sent
+ also to the client who was kicked from the channel. The client
+ who was kicked from the channel must be removed from the channel.
+ This notify type is always destined to the channel. The router or
+ server receiving the packet distributes this type to the local
+ clients on the channel and broadcast it to the network.
+
+ Max Arguments: 2
+ Arguments: (1) <Client ID> (2) [<comment>]
+
+ The <Client ID> is the client who was kicked from the channel.
+ The kicker may have set the <comment> to indicate the reason for
+ the kicking.
+
.in 3
Notify types starting from 16384 are reserved for private notify
19 SILC_COMMAND_KICK
Max Arguments: 3
- Arguments: (1) <channel> (2) <Client ID>
+ Arguments: (1) <Channel ID> (2) <Client ID>
(3) [<comment>]
This command is used by channel operators to remove a client from
"Permission denied. You are not channel operator". Command may
be executed only by channel operator.
- 40 SILC_STATUS_ERR_NO_SERVER_PRIV
+ 40 SILC_STATUS_ERR_NO_CHANNEL_FOPRIV
+
+ "Permission denied. You are not channel founder". Command may
+ be executed only by channel operator.
+
+ 41 SILC_STATUS_ERR_NO_SERVER_PRIV
"Permission denied. You are not server operator". Command may
be executed only by server operator.
- 41 SILC_STATUS_ERR_NO_ROUTER_PRIV
+ 42 SILC_STATUS_ERR_NO_ROUTER_PRIV
"Permission denied. You are not SILC operator". Command may be
executed only by router (SILC) operator.
- 42 SILC_STATUS_ERR_BAD_NICKNAME
+ 43 SILC_STATUS_ERR_BAD_NICKNAME
"Bad nickname". Nickname requested contained illegal characters
or were malformed.
- 43 SILC_STATUS_ERR_BAD_CHANNEL
+ 44 SILC_STATUS_ERR_BAD_CHANNEL
"Bad channel name". Channel requested contained illegal characters
or were malformed.
- 44 SILC_STATUS_ERR_AUTH_FAILED
+ 45 SILC_STATUS_ERR_AUTH_FAILED
"Authentication failed". The authentication data sent as
argument were wrong and thus authentication failed.
/* Notify application */
client->ops->notify(client, conn, type, channel, channel);
break;
+
+ case SILC_NOTIFY_TYPE_KICKED:
+ /*
+ * A client (maybe me) was kicked from a channel
+ */
+
+ /* Get Client ID */
+ tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
+ if (!tmp)
+ goto out;
+
+ client_id = silc_id_payload_parse_id(tmp, tmp_len);
+ if (!client_id)
+ goto out;
+
+ /* Find Client entry */
+ client_entry =
+ silc_idlist_get_client_by_id(client, conn, client_id);
+ if (!client_entry)
+ goto out;
+
+ /* Get channel entry */
+ channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
+ SILC_ID_CHANNEL);
+ if (!channel_id)
+ goto out;
+ if (!silc_idcache_find_by_id_one(conn->channel_cache, (void *)channel_id,
+ SILC_ID_CHANNEL, &id_cache))
+ break;
+
+ channel = (SilcChannelEntry)id_cache->context;
+
+ /* Get comment */
+ tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
+
+ /* Notify application. The channel entry is sent last as this notify
+ is for channel but application don't know it from the arguments
+ sent by server. */
+ client->ops->notify(client, conn, type, client_entry, tmp, channel);
+
+ /* If I was kicked from channel, remove the channel */
+ if (client_entry == conn->local_entry) {
+ if (conn->current_channel == channel)
+ conn->current_channel = NULL;
+ silc_idcache_del_by_id(conn->channel_cache,
+ SILC_ID_CHANNEL, channel->id);
+ silc_free(channel->channel_name);
+ silc_free(channel->id);
+ silc_free(channel->key);
+ silc_cipher_free(channel->channel_key);
+ silc_free(channel);
+ }
+ break;
default:
break;
SILC_CLIENT_CMD(umode, UMODE, "UMODE", SILC_CF_LAG | SILC_CF_REG, 2),
SILC_CLIENT_CMD(cmode, CMODE, "CMODE", SILC_CF_LAG | SILC_CF_REG, 4),
SILC_CLIENT_CMD(cumode, CUMODE, "CUMODE", SILC_CF_LAG | SILC_CF_REG, 5),
- SILC_CLIENT_CMD(kick, KICK, "KICK", SILC_CF_LAG | SILC_CF_REG, 2),
+ SILC_CLIENT_CMD(kick, KICK, "KICK", SILC_CF_LAG | SILC_CF_REG, 4),
SILC_CLIENT_CMD(restart, RESTART, "RESTART",
SILC_CF_LAG | SILC_CF_REG | SILC_CF_OPER, 2),
SILC_CLIENT_CMD(close, CLOSE, "CLOSE",
}
/* Find client entry */
- client_entry = silc_idlist_get_client(client, conn, nickname, server, num);
+ client_entry = silc_idlist_get_client(client, conn, nickname, server, num,
+ TRUE);
if (!client_entry) {
if (nickname)
silc_free(nickname);
/* Find client entry */
client_entry = silc_idlist_get_client(cmd->client, conn,
- nickname, server, num);
+ nickname, server, num, TRUE);
if (!client_entry) {
/* Client entry not found, it was requested thus mark this to be
pending command. */
{
SilcClientCommandContext cmd = (SilcClientCommandContext)context;
SilcClientConnection conn = cmd->conn;
+ SilcIDCacheEntry id_cache = NULL;
+ SilcChannelEntry channel;
+ SilcBuffer buffer, idp, idp2;
+ SilcClientEntry target;
+ char *name;
+ unsigned int num = 0;
+ char *nickname = NULL, *server = NULL;
+
+ if (!cmd->conn) {
+ SILC_NOT_CONNECTED(cmd->client, cmd->conn);
+ COMMAND_ERROR;
+ goto out;
+ }
+
+ if (cmd->argc < 3) {
+ cmd->client->ops->say(cmd->client, conn,
+ "Usage: /KICK <channel> <client> [<comment>]");
+ COMMAND_ERROR;
+ goto out;
+ }
+
+ if (cmd->argv[1][0] == '*') {
+ if (!conn->current_channel) {
+ cmd->client->ops->say(cmd->client, conn, "You are not on any channel");
+ COMMAND_ERROR;
+ goto out;
+ }
+ name = conn->current_channel->channel_name;
+ } else {
+ name = cmd->argv[1];
+ }
+
+ if (!conn->current_channel) {
+ cmd->client->ops->say(cmd->client, conn, "You are not on that channel");
+ COMMAND_ERROR;
+ goto out;
+ }
+ /* Get the Channel ID of the channel */
+ if (!silc_idcache_find_by_data_one(conn->channel_cache, name, &id_cache)) {
+ cmd->client->ops->say(cmd->client, conn, "You are not on that channel");
+ COMMAND_ERROR;
+ goto out;
+ }
+
+ channel = (SilcChannelEntry)id_cache->context;
+
+ /* Parse the typed nickname. */
+ if (!silc_parse_nickname(cmd->argv[2], &nickname, &server, &num)) {
+ cmd->client->ops->say(cmd->client, conn, "Bad nickname");
+ COMMAND_ERROR;
+ goto out;
+ }
+
+ /* Get the target client */
+ target = silc_idlist_get_client(cmd->client, conn, nickname,
+ server, num, FALSE);
+ if (!target) {
+ cmd->client->ops->say(cmd->client, conn, "No such client: %s",
+ cmd->argv[2]);
+ COMMAND_ERROR;
+ goto out;
+ }
+
+ /* Send KICK command to the server */
+ idp = silc_id_payload_encode(id_cache->id, SILC_ID_CHANNEL);
+ idp2 = silc_id_payload_encode(target->id, SILC_ID_CLIENT);
+ if (cmd->argc == 3)
+ buffer = silc_command_payload_encode_va(SILC_COMMAND_KICK, 0, 2,
+ 1, idp->data, idp->len,
+ 2, idp2->data, idp2->len);
+ else
+ buffer = silc_command_payload_encode_va(SILC_COMMAND_KICK, 0, 3,
+ 1, idp->data, idp->len,
+ 2, idp2->data, idp2->len,
+ 3, cmd->argv[3],
+ strlen(cmd->argv[3]));
+ 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);
+ silc_buffer_free(idp2);
+
+ /* Notify application */
+ COMMAND;
+
+ out:
+ silc_client_command_free(cmd);
}
SILC_CLIENT_CMD_FUNC(restart)
{ STAT(UNKNOWN_MODE), "Unknown mode" },
{ STAT(NOT_YOU), "Cannot change mode for other users" },
{ STAT(NO_CHANNEL_PRIV), "Permission denied. You are not channel operator" },
+ { STAT(NO_CHANNEL_FOPRIV),"Permission denied. You are not channel founder" },
{ STAT(NO_SERVER_PRIV), "Permission denied. You are not server operator" },
{ STAT(NO_ROUTER_PRIV), "Permission denied. You are not SILC operator" },
{ STAT(BAD_NICKNAME), "Bad nickname" },
SILC_CLIENT_CMD_REPLY_FUNC(kick)
{
+ SilcClientCommandReplyContext cmd = (SilcClientCommandReplyContext)context;
+ SilcClientConnection conn = (SilcClientConnection)cmd->sock->user_data;
+ SilcCommandStatus status;
+ unsigned char *tmp;
+
+ 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,
+ "%s", silc_client_command_status_message(status));
+ COMMAND_REPLY_ERROR;
+ goto out;
+ }
+
+ /* Notify application */
+ COMMAND_REPLY((ARGS));
+
+ /* Execute any pending command callbacks */
+ SILC_CLIENT_PENDING_EXEC(cmd, SILC_COMMAND_KICK);
+
+ out:
+ SILC_CLIENT_PENDING_DESTRUCTOR(cmd, SILC_COMMAND_KICK);
+ silc_client_command_reply_free(cmd);
}
SILC_CLIENT_CMD_REPLY_FUNC(restart)
SilcClientConnection conn,
char *nickname,
char *server,
- unsigned int num)
+ unsigned int num,
+ int query)
{
SilcIDCacheEntry id_cache;
SilcIDCacheList list = NULL;
/* Find ID from cache */
if (!silc_idcache_find_by_data_loose(conn->client_cache, nickname, &list)) {
- SilcClientCommandContext ctx;
- char ident[512];
-
identify:
- SILC_LOG_DEBUG(("Requesting Client ID from server"));
-
- /* No ID found. Do query from the server. The query is done by
- sending simple IDENTIFY command to the server. */
- ctx = silc_client_command_alloc();
- ctx->client = client;
- ctx->conn = conn;
- ctx->command = silc_client_command_find("IDENTIFY");
- memset(ident, 0, sizeof(ident));
- snprintf(ident, sizeof(ident), "IDENTIFY %s", nickname);
- silc_parse_command_line(ident, &ctx->argv, &ctx->argv_lens,
- &ctx->argv_types, &ctx->argc, 2);
- ctx->command->cb(ctx);
-
- if (list)
- silc_idcache_list_free(list);
-
+ if (query) {
+ SilcClientCommandContext ctx;
+ char ident[512];
+
+ SILC_LOG_DEBUG(("Requesting Client ID from server"));
+
+ /* No ID found. Do query from the server. The query is done by
+ sending simple IDENTIFY command to the server. */
+ ctx = silc_client_command_alloc();
+ ctx->client = client;
+ ctx->conn = conn;
+ ctx->command = silc_client_command_find("IDENTIFY");
+ memset(ident, 0, sizeof(ident));
+ snprintf(ident, sizeof(ident), "IDENTIFY %s", nickname);
+ silc_parse_command_line(ident, &ctx->argv, &ctx->argv_lens,
+ &ctx->argv_types, &ctx->argc, 2);
+ ctx->command->cb(ctx);
+
+ if (list)
+ silc_idcache_list_free(list);
+
+ return NULL;
+ }
return NULL;
}
SilcClientConnection conn,
char *nickname,
char *server,
- unsigned int num);
+ unsigned int num,
+ int query);
SilcClientEntry silc_idlist_get_client_by_id(SilcClient client,
SilcClientConnection conn,
SilcClientID *client_id);
int len = silc_id_get_len(type);
void *new = silc_calloc(1, len);
memcpy(new, id, len);
+ return new;
}
#define SILC_STATUS_ERR_UNKNOWN_MODE 37
#define SILC_STATUS_ERR_NOT_YOU 38
#define SILC_STATUS_ERR_NO_CHANNEL_PRIV 39
-#define SILC_STATUS_ERR_NO_SERVER_PRIV 40
-#define SILC_STATUS_ERR_NO_ROUTER_PRIV 41
-#define SILC_STATUS_ERR_BAD_NICKNAME 42
-#define SILC_STATUS_ERR_BAD_CHANNEL 43
-#define SILC_STATUS_ERR_AUTH_FAILED 44
+#define SILC_STATUS_ERR_NO_CHANNEL_FOPRIV 40
+#define SILC_STATUS_ERR_NO_SERVER_PRIV 41
+#define SILC_STATUS_ERR_NO_ROUTER_PRIV 42
+#define SILC_STATUS_ERR_BAD_NICKNAME 43
+#define SILC_STATUS_ERR_BAD_CHANNEL 44
+#define SILC_STATUS_ERR_AUTH_FAILED 45
/* Prototypes */
SilcCommandPayload silc_command_payload_parse(SilcBuffer buffer);
#define SILC_NOTIFY_TYPE_MOTD 9 /* message of the day */
#define SILC_NOTIFY_TYPE_CHANNEL_CHANGE 10 /* Channel's ID has changed */
#define SILC_NOTIFY_TYPE_SERVER_SIGNOFF 11 /* Server quitting SILC */
+#define SILC_NOTIFY_TYPE_KICKED 12 /* Kicked from channel */
/* Prototypes */
SilcNotifyPayload silc_notify_payload_parse(SilcBuffer buffer);