SilcBuffer packet;
va_list ap;
+ assert(client && conn);
+
va_start(ap, argc);
packet = silc_command_payload_encode_vap(command, ident, argc, ap);
{
SilcClientCommand cmd;
+ assert(client);
+
silc_list_start(client->internal->commands);
while ((cmd = silc_list_get(client->internal->commands)) != SILC_LIST_END) {
- if (cmd->name && !strcmp(cmd->name, name))
+ if (cmd->name && !strcasecmp(cmd->name, name))
return cmd;
}
return NULL;
}
-/* Calls the command (executes it). Application can call this after
- it has allocated the SilcClientCommandContext with the function
- silc_client_command_alloc and found the command from the client
- library by calling silc_client_command_find. This will execute
- the command. */
+/* Executes a command */
-void silc_client_command_call(SilcClientCommand command,
- SilcClientCommandContext cmd)
+bool silc_client_command_call(SilcClient client,
+ SilcClientConnection conn,
+ const char *command_line, ...)
{
- (*command->command)((void *)cmd, NULL);
+ va_list va;
+ SilcUInt32 argc = 0;
+ unsigned char **argv = NULL;
+ SilcUInt32 *argv_lens = NULL, *argv_types = NULL;
+ SilcClientCommand cmd;
+ SilcClientCommandContext ctx;
+ char *arg;
+
+ assert(client);
+
+ /* Parse arguments */
+ va_start(va, command_line);
+ if (command_line) {
+ char *command_name;
+
+ /* Get command name */
+ command_name = silc_memdup(command_line, strcspn(command_line, " "));
+ if (!command_name)
+ return FALSE;
+
+ /* Find command by name */
+ cmd = silc_client_command_find(client, command_name);
+ if (!cmd) {
+ silc_free(command_name);
+ return FALSE;
+ }
+
+ /* Parse command line */
+ silc_parse_command_line((char *)command_line, &argv, &argv_lens,
+ &argv_types, &argc, cmd->max_args);
+
+ silc_free(command_name);
+ } else {
+ arg = va_arg(va, char *);
+ if (!arg)
+ return FALSE;
+
+ /* Find command by name */
+ cmd = silc_client_command_find(client, arg);
+ if (!cmd)
+ return FALSE;
+
+ while (arg) {
+ argv = silc_realloc(argv, sizeof(*argv) * (argc + 1));
+ argv_lens = silc_realloc(argv_lens, sizeof(*argv_lens) * (argc + 1));
+ argv_types = silc_realloc(argv_types, sizeof(*argv_types) * (argc + 1));
+ argv[argc] = silc_memdup(arg, strlen(arg));
+ argv_lens[argc] = strlen(arg);
+ argv_types[argc] = argc + 1;
+ argc++;
+ arg = va_arg(va, char *);
+ }
+ }
+
+ /* Allocate command context. */
+ ctx = silc_client_command_alloc();
+ ctx->client = client;
+ ctx->conn = conn;
+ ctx->command = cmd;
+ ctx->argc = argc;
+ ctx->argv = argv;
+ ctx->argv_lens = argv_lens;
+ ctx->argv_types = argv_types;
+
+ /* Call the command */
+ cmd->command(ctx, NULL);
+
+ va_end(va);
+
+ return TRUE;
}
/* Add new pending command to be executed when reply to a command has been
{
SilcClientCommandPending *reply;
+ assert(conn);
reply = silc_calloc(1, sizeof(*reply));
reply->reply_cmd = reply_cmd;
reply->ident = ident;
reply->context = context;
reply->callback = callback;
- silc_dlist_add(conn->pending_commands, reply);
+ silc_dlist_add(conn->internal->pending_commands, reply);
}
/* Deletes pending command by reply command type. */
{
SilcClientCommandPending *r;
- if (!conn->pending_commands)
+ if (!conn->internal->pending_commands)
return;
- silc_dlist_start(conn->pending_commands);
- while ((r = silc_dlist_get(conn->pending_commands)) != SILC_LIST_END) {
+ silc_dlist_start(conn->internal->pending_commands);
+ while ((r = silc_dlist_get(conn->internal->pending_commands))
+ != SILC_LIST_END) {
if ((r->reply_cmd == reply_cmd || (r->reply_cmd == SILC_COMMAND_NONE &&
r->reply_check))
&& r->ident == ident) {
- silc_dlist_del(conn->pending_commands, r);
+ silc_dlist_del(conn->internal->pending_commands, r);
silc_free(r);
}
}
SilcClientCommandPendingCallbacks callbacks = NULL;
int i = 0;
- silc_dlist_start(conn->pending_commands);
- while ((r = silc_dlist_get(conn->pending_commands)) != SILC_LIST_END) {
+ silc_dlist_start(conn->internal->pending_commands);
+ while ((r = silc_dlist_get(conn->internal->pending_commands))
+ != SILC_LIST_END) {
if ((r->reply_cmd == command || r->reply_cmd == SILC_COMMAND_NONE)
&& r->ident == ident) {
callbacks = silc_realloc(callbacks, sizeof(*callbacks) * (i + 1));
name = cmd->argv[1];
/* Get the Channel ID of the channel */
- if (silc_idcache_find_by_name_one(conn->channel_cache, name, &id_cache)) {
+ if (silc_idcache_find_by_name_one(conn->internal->channel_cache,
+ name, &id_cache)) {
channel = (SilcChannelEntry)id_cache->context;
idp = silc_id_payload_encode(id_cache->id, SILC_ID_CHANNEL);
}
}
/* Get the Channel ID of the channel */
- if (!silc_idcache_find_by_name_one(conn->channel_cache, name, &id_cache)) {
+ if (!silc_idcache_find_by_name_one(conn->internal->channel_cache,
+ name, &id_cache)) {
COMMAND_ERROR(SILC_STATUS_ERR_NOT_ON_CHANNEL);
goto out;
}
SilcClientCommandContext cmd = (SilcClientCommandContext)context;
SilcClient client = cmd->client;
SilcClientConnection conn = cmd->conn;
- SilcBuffer buffer, idp;
+ SilcBuffer buffer, idp, auth = NULL;
SilcClientEntry target;
- char *nickname = NULL;
+ char *nickname = NULL, *comment = NULL;
if (!cmd->conn) {
SILC_NOT_CONNECTED(cmd->client, cmd->conn);
if (cmd->argc < 2) {
SAY(cmd->client, conn, SILC_CLIENT_MESSAGE_INFO,
- "Usage: /KILL <nickname> [<comment>]");
+ "Usage: /KILL <nickname> [<comment>] [-pubkey]");
COMMAND_ERROR(SILC_STATUS_ERR_NOT_ENOUGH_PARAMS);
goto out;
}
goto out;
}
+ if (cmd->argc >= 3) {
+ if (strcasecmp(cmd->argv[2], "-pubkey"))
+ comment = cmd->argv[2];
+
+ if (!strcasecmp(cmd->argv[2], "-pubkey") ||
+ (cmd->argc >= 4 && !strcasecmp(cmd->argv[3], "-pubkey"))) {
+ /* Encode the public key authentication payload */
+ auth = silc_auth_public_key_auth_generate(cmd->client->public_key,
+ cmd->client->private_key,
+ cmd->client->rng,
+ client->sha1hash,
+ target->id, SILC_ID_CLIENT);
+ }
+ }
+
/* 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,
- ++conn->cmd_ident, 1,
- 1, idp->data, idp->len);
- else
- 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]));
+ buffer =
+ silc_command_payload_encode_va(SILC_COMMAND_KILL,
+ ++conn->cmd_ident, 3,
+ 1, idp->data, idp->len,
+ 2, comment, comment ? strlen(comment) : 0,
+ 3, auth ? auth->data : NULL,
+ auth ? auth->len : 0);
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(auth);
/* Notify application */
COMMAND(SILC_STATUS_OK);
{
SilcClientCommandContext cmd = (SilcClientCommandContext)context;
SilcClientConnection conn = cmd->conn;
- SilcBuffer buffer;
+ SilcBuffer buffer, idp;
void *id;
int i;
goto out;
}
+ idp = silc_id_payload_encode(conn->remote_id, SILC_ID_SERVER);
+
/* Send the command */
buffer = silc_command_payload_encode_va(SILC_COMMAND_PING, 0, 1,
- 1, conn->remote_id_data,
- silc_id_get_len(conn->remote_id,
- SILC_ID_SERVER));
+ 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);
id = silc_id_str2id(conn->remote_id_data, conn->remote_id_data_len,
SILC_ID_SERVER);
}
/* Start counting time */
- for (i = 0; i < conn->ping_count; i++) {
- if (conn->ping[i].dest_id == NULL) {
- conn->ping[i].start_time = time(NULL);
- conn->ping[i].dest_id = id;
- conn->ping[i].dest_name = strdup(conn->remote_host);
+ for (i = 0; i < conn->internal->ping_count; i++) {
+ if (conn->internal->ping[i].dest_id == NULL) {
+ conn->internal->ping[i].start_time = time(NULL);
+ conn->internal->ping[i].dest_id = id;
+ conn->internal->ping[i].dest_name = strdup(conn->remote_host);
break;
}
}
- if (i >= conn->ping_count) {
- i = conn->ping_count;
- conn->ping = silc_realloc(conn->ping, sizeof(*conn->ping) * (i + 1));
- conn->ping[i].start_time = time(NULL);
- conn->ping[i].dest_id = id;
- conn->ping[i].dest_name = strdup(conn->remote_host);
- conn->ping_count++;
+ if (i >= conn->internal->ping_count) {
+ i = conn->internal->ping_count;
+ conn->internal->ping =
+ silc_realloc(conn->internal->ping,
+ sizeof(*conn->internal->ping) * (i + 1));
+ conn->internal->ping[i].start_time = time(NULL);
+ conn->internal->ping[i].dest_id = id;
+ conn->internal->ping[i].dest_name = strdup(conn->remote_host);
+ conn->internal->ping_count++;
}
/* Notify application */
}
/* Get the Channel ID of the channel */
- if (!silc_idcache_find_by_name_one(conn->channel_cache, name, &id_cache)) {
+ if (!silc_idcache_find_by_name_one(conn->internal->channel_cache,
+ name, &id_cache)) {
COMMAND_ERROR(SILC_STATUS_ERR_NOT_ON_CHANNEL);
goto out;
}
/* Encode the public key authentication payload */
auth = silc_auth_public_key_auth_generate(cmd->client->public_key,
cmd->client->private_key,
- cmd->client->rng, conn->hash,
+ cmd->client->rng,
+ conn->internal->hash,
conn->local_id,
SILC_ID_CLIENT);
} else {
/* Encode the public key authentication payload */
auth = silc_auth_public_key_auth_generate(cmd->client->public_key,
cmd->client->private_key,
- cmd->client->rng, conn->hash,
+ cmd->client->rng,
+ conn->internal->hash,
conn->local_id,
SILC_ID_CLIENT);
} else {
SILC_CLIENT_CMD(topic, TOPIC, "TOPIC", 3);
SILC_CLIENT_CMD(invite, INVITE, "INVITE", 3);
SILC_CLIENT_CMD(quit, QUIT, "QUIT", 2);
- SILC_CLIENT_CMD(kill, KILL, "KILL", 3);
+ SILC_CLIENT_CMD(kill, KILL, "KILL", 4);
SILC_CLIENT_CMD(info, INFO, "INFO", 2);
SILC_CLIENT_CMD(stats, STATS, "STATS", 0);
SILC_CLIENT_CMD(ping, PING, "PING", 2);