}
if (cmd->argc < 2 || cmd->argc > 3) {
- cmd->client->ops->say(cmd->client, conn, SILC_CLIENT_MESSAGE_INFO,
- "Usage: /IDENTIFY <nickname>[@<server>] [<count>]");
COMMAND_ERROR;
goto out;
}
SilcClientEntry client_entry = NULL;
SilcChannelEntry channel;
SilcBuffer buffer, clidp, chidp;
- uint32 num = 0, type = 0;
- char *nickname = NULL, *server = NULL, *name;
+ uint32 type = 0;
+ char *nickname = NULL, *name;
char *invite = NULL;
if (!cmd->conn) {
/* Parse the typed nickname. */
if (cmd->argc == 3) {
if (cmd->argv[2][0] != '+' && cmd->argv[2][0] != '-') {
- if (!silc_parse_nickname(cmd->argv[2], &nickname, &server, &num)) {
- cmd->client->ops->say(cmd->client, conn, SILC_CLIENT_MESSAGE_INFO,
- "Bad nickname");
- COMMAND_ERROR;
- goto out;
- }
-
+ if (client->params->nickname_parse)
+ client->params->nickname_parse(cmd->argv[2], &nickname);
+ else
+ nickname = strdup(cmd->argv[2]);
+
/* Find client entry */
client_entry = silc_idlist_get_client(client, conn, nickname,
- server, num, TRUE);
+ cmd->argv[2], TRUE);
if (!client_entry) {
- if (nickname)
- silc_free(nickname);
- if (server)
- silc_free(server);
-
if (cmd->pending) {
COMMAND_ERROR;
goto out;
}
+ silc_free(nickname);
/* Client entry not found, it was requested thus mark this to be
pending command. */
COMMAND;
out:
- if (nickname)
- silc_free(nickname);
- if (server)
- silc_free(server);
+ silc_free(nickname);
silc_client_command_free(cmd);
}
q->client = cmd->client;
q->conn = cmd->conn;
+ /* Sleep for a while */
+ sleep(2);
+
/* We quit the connection with little timeout */
silc_schedule_task_add(cmd->client->schedule, cmd->conn->sock->sock,
silc_client_command_quit_cb, (void *)q,
silc_client_command_free(cmd);
}
+/* Timeout callback to remove the killed client from cache */
+
+SILC_TASK_CALLBACK(silc_client_command_kill_remove_later)
+{
+ SilcClientCommandContext cmd = (SilcClientCommandContext)context;
+ SilcClient client = cmd->client;
+ SilcClientConnection conn = cmd->conn;
+ SilcClientEntry target;
+ char *nickname = NULL;
+
+ /* Parse the typed nickname. */
+ if (client->params->nickname_parse)
+ client->params->nickname_parse(cmd->argv[1], &nickname);
+ else
+ nickname = strdup(cmd->argv[1]);
+
+ /* Get the target client */
+ target = silc_idlist_get_client(cmd->client, conn, nickname,
+ cmd->argv[1], FALSE);
+ if (target) {
+ silc_client_remove_from_channels(client, conn, target);
+ silc_client_del_client(client, conn, target);
+ }
+
+ silc_free(nickname);
+ silc_client_command_free(cmd);
+}
+
+/* Kill command's pending command callback to actually remove the killed
+ client from our local cache. */
+
+SILC_CLIENT_CMD_FUNC(kill_remove)
+{
+ SilcClientCommandContext cmd = (SilcClientCommandContext)context;
+ SilcClientCommandReplyContext reply =
+ (SilcClientCommandReplyContext)context2;
+ SilcCommandStatus status;
+
+ SILC_GET16_MSB(status, silc_argument_get_arg_type(reply->args, 1, NULL));
+ if (status == SILC_STATUS_OK) {
+ /* Remove with timeout */
+ silc_schedule_task_add(cmd->client->schedule, cmd->conn->sock->sock,
+ silc_client_command_kill_remove_later, context,
+ 1, 0, SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
+ return;
+ }
+
+ silc_client_command_free(cmd);
+}
+
/* Command KILL. Router operator can use this command to remove an client
fromthe SILC Network. */
SILC_CLIENT_CMD_FUNC(kill)
{
SilcClientCommandContext cmd = (SilcClientCommandContext)context;
+ SilcClient client = cmd->client;
SilcClientConnection conn = cmd->conn;
SilcBuffer buffer, idp;
SilcClientEntry target;
- uint32 num = 0;
- char *nickname = NULL, *server = NULL;
+ char *nickname = NULL;
if (!cmd->conn) {
SILC_NOT_CONNECTED(cmd->client, cmd->conn);
}
/* Parse the typed nickname. */
- if (!silc_parse_nickname(cmd->argv[1], &nickname, &server, &num)) {
- cmd->client->ops->say(cmd->client, conn, SILC_CLIENT_MESSAGE_INFO,
- "Bad nickname");
- COMMAND_ERROR;
- goto out;
- }
+ if (client->params->nickname_parse)
+ client->params->nickname_parse(cmd->argv[1], &nickname);
+ else
+ nickname = strdup(cmd->argv[1]);
/* Get the target client */
target = silc_idlist_get_client(cmd->client, conn, nickname,
- server, num, TRUE);
+ cmd->argv[1], TRUE);
if (!target) {
- silc_free(nickname);
- if (server)
- silc_free(server);
-
if (cmd->pending) {
COMMAND_ERROR;
goto out;
}
+ silc_free(nickname);
+
/* Client entry not found, it was requested thus mark this to be
pending command. */
silc_client_command_pending(conn, SILC_COMMAND_IDENTIFY,
/* Send the KILL command to the server */
idp = silc_id_payload_encode(target->id, SILC_ID_CLIENT);
if (cmd->argc == 2)
- buffer = silc_command_payload_encode_va(SILC_COMMAND_KILL, 0, 1,
+ buffer = silc_command_payload_encode_va(SILC_COMMAND_KILL,
+ ++conn->cmd_ident, 1,
1, idp->data, idp->len);
else
- buffer = silc_command_payload_encode_va(SILC_COMMAND_KILL, 0, 2,
+ buffer = silc_command_payload_encode_va(SILC_COMMAND_KILL,
+ ++conn->cmd_ident, 2,
1, idp->data, idp->len,
2, cmd->argv[2],
strlen(cmd->argv[2]));
/* Notify application */
COMMAND;
+ /* Register a pending callback that will actually remove the killed
+ client from our cache. */
+ silc_client_command_pending(conn, SILC_COMMAND_KILL, conn->cmd_ident,
+ NULL, silc_client_command_kill_remove,
+ silc_client_command_dup(cmd));
+
out:
- if (nickname)
- silc_free(nickname);
- if (server)
- silc_free(server);
+ silc_free(nickname);
silc_client_command_free(cmd);
}
/* See if we have joined to the requested channel already */
if (silc_idcache_find_by_name_one(conn->channel_cache, cmd->argv[1],
- &id_cache))
- goto out;
+ &id_cache)) {
+ SilcChannelEntry channel = (SilcChannelEntry)id_cache->context;
+ if (channel->on_channel)
+ goto out;
+ }
idp = silc_id_payload_encode(conn->local_id, SILC_ID_CLIENT);
SILC_CLIENT_CMD_FUNC(cumode)
{
SilcClientCommandContext cmd = (SilcClientCommandContext)context;
+ SilcClient client = cmd->client;
SilcClientConnection conn = cmd->conn;
SilcChannelEntry channel;
SilcChannelUser chu;
SilcBuffer buffer, clidp, chidp, auth = NULL;
unsigned char *name, *cp, modebuf[4];
uint32 mode = 0, add, len;
- char *nickname = NULL, *server = NULL;
- uint32 num = 0;
+ char *nickname = NULL;
int i;
if (!cmd->conn) {
}
/* Parse the typed nickname. */
- if (!silc_parse_nickname(cmd->argv[3], &nickname, &server, &num)) {
- cmd->client->ops->say(cmd->client, conn, SILC_CLIENT_MESSAGE_INFO, "Bad nickname");
- COMMAND_ERROR;
- goto out;
- }
+ if (client->params->nickname_parse)
+ client->params->nickname_parse(cmd->argv[3], &nickname);
+ else
+ nickname = strdup(cmd->argv[3]);
/* Find client entry */
- client_entry = silc_idlist_get_client(cmd->client, conn,
- nickname, server, num, TRUE);
+ client_entry = silc_idlist_get_client(cmd->client, conn, nickname,
+ cmd->argv[3], TRUE);
if (!client_entry) {
if (cmd->pending) {
COMMAND_ERROR;
goto out;
}
+ silc_free(nickname);
+
/* Client entry not found, it was requested thus mark this to be
pending command. */
silc_client_command_pending(conn, SILC_COMMAND_IDENTIFY,
}
/* Get the current mode */
+ silc_list_start(channel->clients);
while ((chu = silc_list_get(channel->clients)) != SILC_LIST_END) {
if (chu->client == client_entry) {
mode = chu->mode;
/* Send the command packet. We support sending only one mode at once
that requires an argument. */
- buffer = silc_command_payload_encode_va(SILC_COMMAND_CUMODE, 0, 4,
+ buffer = silc_command_payload_encode_va(SILC_COMMAND_CUMODE, 0,
+ auth ? 4 : 3,
1, chidp->data, chidp->len,
2, modebuf, 4,
3, clidp->data, clidp->len,
COMMAND;
out:
- if (nickname)
- silc_free(nickname);
- if (server)
- silc_free(server);
+ silc_free(nickname);
silc_client_command_free(cmd);
}
SILC_CLIENT_CMD_FUNC(kick)
{
SilcClientCommandContext cmd = (SilcClientCommandContext)context;
+ SilcClient client = cmd->client;
SilcClientConnection conn = cmd->conn;
SilcIDCacheEntry id_cache = NULL;
SilcChannelEntry channel;
SilcBuffer buffer, idp, idp2;
SilcClientEntry target;
char *name;
- uint32 num = 0;
- char *nickname = NULL, *server = NULL;
+ char *nickname = NULL;
if (!cmd->conn) {
SILC_NOT_CONNECTED(cmd->client, cmd->conn);
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, SILC_CLIENT_MESSAGE_INFO,
- "Bad nickname");
- COMMAND_ERROR;
- goto out;
- }
+ if (client->params->nickname_parse)
+ client->params->nickname_parse(cmd->argv[2], &nickname);
+ else
+ nickname = strdup(cmd->argv[2]);
/* Get the target client */
target = silc_idlist_get_client(cmd->client, conn, nickname,
- server, num, FALSE);
+ cmd->argv[2], FALSE);
if (!target) {
cmd->client->ops->say(cmd->client, conn, SILC_CLIENT_MESSAGE_INFO,
"No such client: %s",
COMMAND;
out:
- if (nickname)
- silc_free(nickname);
- if (server)
- silc_free(server);
+ silc_free(nickname);
silc_client_command_free(cmd);
}
SilcClientConnection conn = cmd->conn;
SilcBuffer buffer, auth;
- if (cmd->argc == 3) {
- /* Pulic key auth XXX TODO */
- auth = NULL;
+ if (cmd->argc >= 3) {
+ /* Encode the public key authentication payload */
+ auth = silc_auth_public_key_auth_generate(cmd->client->public_key,
+ cmd->client->private_key,
+ conn->hash,
+ conn->local_id,
+ SILC_ID_CLIENT);
} else {
- /* Encode the authentication payload */
+ /* Encode the password authentication payload */
auth = silc_auth_payload_encode(SILC_AUTH_PASSWORD, NULL, 0,
data, data_len);
}
{
SilcClientCommandContext cmd = (SilcClientCommandContext)context;
SilcClientConnection conn = cmd->conn;
- unsigned char *auth_data;
- uint32 auth_data_len = 0;
if (!cmd->conn) {
SILC_NOT_CONNECTED(cmd->client, cmd->conn);
if (cmd->argc < 2) {
cmd->client->ops->say(cmd->client, conn, SILC_CLIENT_MESSAGE_INFO,
- "Usage: /OPER <username> [<public key>]");
+ "Usage: /OPER <username> [-pubkey]");
COMMAND_ERROR;
goto out;
}
- if (cmd->argc == 3) {
- /* XXX Get public key */
- auth_data = NULL;
- COMMAND_ERROR;
- goto out;
- } else {
+ if (cmd->argc < 3) {
/* Get passphrase */
cmd->client->ops->ask_passphrase(cmd->client, conn,
silc_client_command_oper_send,
return;
}
- silc_client_command_oper_send(auth_data, auth_data_len, context);
-
- memset(auth_data, 0, auth_data_len);
- silc_free(auth_data);
-
- /* Notify application */
- COMMAND;
+ silc_client_command_oper_send(NULL, 0, context);
out:
silc_client_command_free(cmd);
SilcClientConnection conn = cmd->conn;
SilcBuffer buffer, auth;
- if (cmd->argc == 3) {
- /* Pulic key auth XXX TODO */
- auth = NULL;
+ if (cmd->argc >= 3) {
+ /* Encode the public key authentication payload */
+ auth = silc_auth_public_key_auth_generate(cmd->client->public_key,
+ cmd->client->private_key,
+ conn->hash,
+ conn->local_id,
+ SILC_ID_CLIENT);
} else {
- /* Encode the authentication payload */
+ /* Encode the password authentication payload */
auth = silc_auth_payload_encode(SILC_AUTH_PASSWORD, NULL, 0,
data, data_len);
}
{
SilcClientCommandContext cmd = (SilcClientCommandContext)context;
SilcClientConnection conn = cmd->conn;
- unsigned char *auth_data;
- uint32 auth_data_len = 0;
if (!cmd->conn) {
SILC_NOT_CONNECTED(cmd->client, cmd->conn);
if (cmd->argc < 2) {
cmd->client->ops->say(cmd->client, conn, SILC_CLIENT_MESSAGE_INFO,
- "Usage: /SILCOPER <username> [<public key>]");
+ "Usage: /SILCOPER <username> [-pubkey]");
COMMAND_ERROR;
goto out;
}
- if (cmd->argc == 3) {
- /* XXX Get public key */
- auth_data = NULL;
- COMMAND_ERROR;
- goto out;
- } else {
+ if (cmd->argc < 3) {
/* Get passphrase */
cmd->client->ops->ask_passphrase(cmd->client, conn,
silc_client_command_silcoper_send,
return;
}
- silc_client_command_silcoper_send(auth_data, auth_data_len, context);
-
- memset(auth_data, 0, auth_data_len);
- silc_free(auth_data);
-
- /* Notify application */
- COMMAND;
+ silc_client_command_silcoper_send(NULL, 0, context);
out:
silc_client_command_free(cmd);
}
channel = (SilcChannelEntry)id_cache->context;
+ channel->on_channel = FALSE;
/* Send LEAVE command to the server */
idp = silc_id_payload_encode(id_cache->id, SILC_ID_CHANNEL);
SilcClient client = cmd->client;
SilcClientEntry client_entry = NULL;
SilcServerEntry server_entry = NULL;
- uint32 num = 0;
- char *nickname = NULL, *server = NULL;
+ char *nickname = NULL;
SilcBuffer idp, buffer;
if (!cmd->conn) {
goto out;
}
- /* Parse the typed nickname. */
- if (!silc_parse_nickname(cmd->argv[1], &nickname, &server, &num)) {
- client->ops->say(client, conn, SILC_CLIENT_MESSAGE_INFO, "Bad nickname");
- COMMAND_ERROR;
- goto out;
+ if (cmd->pending) {
+ SilcClientCommandReplyContext reply =
+ (SilcClientCommandReplyContext)context2;
+ SilcCommandStatus status;
+ unsigned char *tmp = silc_argument_get_arg_type(reply->args, 1, NULL);
+ SILC_GET16_MSB(status, tmp);
+
+ if (status == SILC_STATUS_ERR_NO_SUCH_NICK ||
+ status == SILC_STATUS_ERR_NO_SUCH_SERVER) {
+ cmd->client->ops->say(cmd->client, conn, SILC_CLIENT_MESSAGE_ERROR,
+ "%s",
+ silc_client_command_status_message(status));
+ COMMAND_ERROR;
+ goto out;
+ }
}
+ /* Parse the typed nickname. */
+ if (client->params->nickname_parse)
+ client->params->nickname_parse(cmd->argv[1], &nickname);
+ else
+ nickname = strdup(cmd->argv[1]);
+
/* Find client entry */
- client_entry = silc_idlist_get_client(client, conn, nickname, server, num,
+ client_entry = silc_idlist_get_client(client, conn, nickname, cmd->argv[1],
FALSE);
if (!client_entry) {
/* Check whether user requested server actually */
- server_entry = silc_client_get_server(client, conn, nickname);
+ server_entry = silc_client_get_server(client, conn, cmd->argv[1]);
- if (!server_entry) {
+ if (!server_entry && !cmd->pending) {
/* No. what ever user wants we don't have it, so resolve it. We
will try to resolve both client and server, one of them is
bound to be wrong. */
/* This will send the IDENTIFY command */
- silc_idlist_get_client(client, conn, nickname, server, num, TRUE);
+ silc_idlist_get_client(client, conn, nickname, cmd->argv[1], TRUE);
silc_client_command_pending(conn, SILC_COMMAND_IDENTIFY,
conn->cmd_ident,
silc_client_command_destructor,
silc_client_command_getkey,
silc_client_command_dup(cmd));
- /* This sends the INFO command to resolve the server. */
- silc_client_send_command(client, conn, SILC_COMMAND_INFO,
+ /* This sends the IDENTIFY command to resolve the server. */
+ silc_client_send_command(client, conn, SILC_COMMAND_IDENTIFY,
++conn->cmd_ident, 1,
- 1, nickname, strlen(nickname));
+ 2, cmd->argv[1], cmd->argv_lens[1]);
silc_client_command_pending(conn, SILC_COMMAND_IDENTIFY,
- conn->cmd_ident,
- silc_client_command_destructor,
+ conn->cmd_ident, NULL,
silc_client_command_getkey,
silc_client_command_dup(cmd));
cmd->pending = 1;
+ silc_free(nickname);
return;
}
COMMAND;
out:
+ silc_free(nickname);
silc_client_command_free(cmd);
}