X-Git-Url: http://git.silcnet.org/gitweb/?a=blobdiff_plain;f=apps%2Fsilc%2Fcommand.c;fp=apps%2Fsilc%2Fcommand.c;h=0000000000000000000000000000000000000000;hb=318d79b391bf6288e3e28c840217a7097f3d0392;hp=c64f44f932ed4719a1fc0be59b7130d1f76bccab;hpb=89b07a460a554eb5173fe07f09b8c51c31d53e29;p=silc.git diff --git a/apps/silc/command.c b/apps/silc/command.c deleted file mode 100644 index c64f44f9..00000000 --- a/apps/silc/command.c +++ /dev/null @@ -1,937 +0,0 @@ -/* - - command.c - - Author: Pekka Riikonen - - Copyright (C) 1997 - 2000 Pekka Riikonen - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - -*/ -/* - * $Id$ - * $Log$ - * Revision 1.11 2000/07/19 09:19:05 priikone - * Enhancements to AWAY command. - * - * Revision 1.10 2000/07/19 07:06:33 priikone - * Added AWAY command. - * - * Revision 1.9 2000/07/12 05:56:32 priikone - * Major rewrite of ID Cache system. Support added for the new - * ID cache system. - * - * Revision 1.8 2000/07/10 05:39:11 priikone - * Added INFO and VERSION commands. Minor changes to SERVER command - * to show current servers when giving without arguments. - * - * Revision 1.7 2000/07/07 06:54:44 priikone - * Fixed channel joining bug, do not allow joining twice on the - * same channel. - * - * Revision 1.6 2000/07/06 07:14:36 priikone - * Fixes to NAMES command handling. - * Fixes when leaving from channel. - * - * Revision 1.5 2000/07/05 06:12:05 priikone - * Global cosmetic changes. - * - * Revision 1.4 2000/07/04 08:28:03 priikone - * Added INVITE, PING and NAMES command. - * - * Revision 1.3 2000/07/03 05:49:49 priikone - * Implemented LEAVE command. Minor bug fixes. - * - * Revision 1.2 2000/06/27 19:38:40 priikone - * Added missing goto flag. - * - * Revision 1.1.1.1 2000/06/27 11:36:56 priikone - * Imported from internal CVS/Added Log headers. - * - * - */ - -#include "clientincludes.h" - -/* Client command list. */ -SilcClientCommand silc_command_list[] = -{ - SILC_CLIENT_CMD(whois, WHOIS, "WHOIS", SILC_CF_LAG | SILC_CF_REG, 3), - SILC_CLIENT_CMD(whowas, WHOWAS, "WHOWAS", SILC_CF_LAG | SILC_CF_REG, 3), - SILC_CLIENT_CMD(identify, IDENTIFY, "IDENTIFY", - SILC_CF_LAG | SILC_CF_REG, 3), - SILC_CLIENT_CMD(nick, NICK, "NICK", SILC_CF_LAG | SILC_CF_REG, 2), - SILC_CLIENT_CMD(list, LIST, "LIST", SILC_CF_LAG | SILC_CF_REG, 2), - SILC_CLIENT_CMD(topic, TOPIC, "TOPIC", SILC_CF_LAG | SILC_CF_REG, 2), - SILC_CLIENT_CMD(invite, INVITE, "INVITE", SILC_CF_LAG | SILC_CF_REG, 3), - SILC_CLIENT_CMD(quit, QUIT, "QUIT", SILC_CF_LAG | SILC_CF_REG, 1), - SILC_CLIENT_CMD(kill, KILL, "KILL", - SILC_CF_LAG | SILC_CF_REG | SILC_CF_OPER, 2), - SILC_CLIENT_CMD(info, INFO, "INFO", SILC_CF_LAG | SILC_CF_REG, 2), - SILC_CLIENT_CMD(connect, CONNECT, "CONNECT", - SILC_CF_LAG | SILC_CF_REG | SILC_CF_OPER, 2), - SILC_CLIENT_CMD(ping, PING, "PING", SILC_CF_LAG | SILC_CF_REG, 2), - SILC_CLIENT_CMD(oper, OPER, "OPER", - SILC_CF_LAG | SILC_CF_REG | SILC_CF_OPER, 2), - SILC_CLIENT_CMD(join, JOIN, "JOIN", SILC_CF_LAG | SILC_CF_REG, 2), - SILC_CLIENT_CMD(motd, MOTD, "MOTD", SILC_CF_LAG | SILC_CF_REG, 2), - 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, 2), - SILC_CLIENT_CMD(kick, KICK, "KICK", SILC_CF_LAG | SILC_CF_REG, 2), - SILC_CLIENT_CMD(restart, RESTART, "RESTART", - SILC_CF_LAG | SILC_CF_REG | SILC_CF_OPER, 2), - SILC_CLIENT_CMD(close, CLOSE, "CLOSE", - SILC_CF_LAG | SILC_CF_REG | SILC_CF_OPER, 2), - SILC_CLIENT_CMD(die, DIE, "DIE", - SILC_CF_LAG | SILC_CF_REG | SILC_CF_OPER, 2), - SILC_CLIENT_CMD(silcoper, SILCOPER, "SILOPER", - SILC_CF_LAG | SILC_CF_REG | SILC_CF_SILC_OPER, 2), - SILC_CLIENT_CMD(leave, LEAVE, "LEAVE", SILC_CF_LAG | SILC_CF_REG, 2), - SILC_CLIENT_CMD(names, NAMES, "NAMES", SILC_CF_LAG | SILC_CF_REG, 2), - - /* - * Local. Client specific commands - */ - SILC_CLIENT_CMD(help, HELP, "HELP", SILC_CF_NONE, 2), - SILC_CLIENT_CMD(clear, CLEAR, "CLEAR", SILC_CF_NONE, 1), - SILC_CLIENT_CMD(version, VERSION, "VERSION", SILC_CF_NONE, 1), - SILC_CLIENT_CMD(server, SERVER, "SERVER", SILC_CF_NONE, 2), - SILC_CLIENT_CMD(msg, MSG, "MSG", SILC_CF_NONE, 3), - SILC_CLIENT_CMD(away, AWAY, "AWAY", SILC_CF_NONE, 2), - - { NULL, 0, NULL, 0}, -}; - -#define SILC_NOT_CONNECTED(x) \ - silc_say((x), "You are not connected to a server, use /SERVER to connect"); - -/* List of pending commands. */ -SilcClientCommandPending *silc_command_pending = NULL; - -/* Add new pending command to the list of pending commands. Currently - pending commands are executed from command replies, thus we can - execute any command after receiving some specific command reply. - - The argument `reply_cmd' is the command reply from where the callback - function is to be called, thus, it IS NOT the command to be executed. - - XXX: If needed in the future this support may be extended for - commands as well, when any command could be executed after executing - some specific command. */ - -void silc_client_command_pending(SilcCommand reply_cmd, - SilcClientCommandCallback callback, - void *context) -{ - SilcClientCommandPending *reply, *r; - - reply = silc_calloc(1, sizeof(*reply)); - reply->reply_cmd = reply_cmd; - reply->context = context; - reply->callback = callback; - - if (silc_command_pending == NULL) { - silc_command_pending = reply; - return; - } - - for (r = silc_command_pending; r; r = r->next) { - if (r->next == NULL) { - r->next = reply; - break; - } - } -} - -/* Deletes pending command by reply command type. */ - -void silc_client_command_pending_del(SilcCommand reply_cmd) -{ - SilcClientCommandPending *r, *tmp; - - if (silc_command_pending) { - if (silc_command_pending->reply_cmd == reply_cmd) { - silc_free(silc_command_pending); - silc_command_pending = NULL; - return; - } - - for (r = silc_command_pending; r; r = r->next) { - if (r->next && r->next->reply_cmd == reply_cmd) { - tmp = r->next; - r->next = r->next->next; - silc_free(tmp); - break; - } - } - } -} - -/* Free command context and its internals */ - -static void silc_client_command_free(SilcClientCommandContext cmd) -{ - int i; - - if (cmd) { - for (i = 0; i < cmd->argc; i++) - silc_free(cmd->argv[i]); - silc_free(cmd); - } -} - -/* Command WHOIS. This command is used to query information about - specific user. */ - -SILC_CLIENT_CMD_FUNC(whois) -{ - SilcClientCommandContext cmd = (SilcClientCommandContext)context; - SilcBuffer buffer; - - if (cmd->argc < 2 || cmd->argc > 3) { - silc_say(cmd->client, "Usage: /WHOIS [@] []"); - goto out; - } - - if (!cmd->client->current_win->sock) { - SILC_NOT_CONNECTED(cmd->client); - goto out; - } - - buffer = silc_command_encode_payload(SILC_COMMAND_WHOIS, - cmd->argc - 1, ++cmd->argv, - ++cmd->argv_lens, ++cmd->argv_types); - silc_client_packet_send(cmd->client, cmd->client->current_win->sock, - SILC_PACKET_COMMAND, NULL, 0, NULL, NULL, - buffer->data, buffer->len, TRUE); - silc_buffer_free(buffer); - cmd->argv--; - cmd->argv_lens--; - cmd->argv_types--; - - out: - silc_client_command_free(cmd); -} - -SILC_CLIENT_CMD_FUNC(whowas) -{ -} - -/* Command IDENTIFY. This command is used to query information about - specific user, especially ID's. */ - -SILC_CLIENT_CMD_FUNC(identify) -{ - SilcClientCommandContext cmd = (SilcClientCommandContext)context; - SilcBuffer buffer; - - if (cmd->argc < 2 || cmd->argc > 3) { - silc_say(cmd->client, "Usage: /IDENTIFY [@] []"); - goto out; - } - - if (!cmd->client->current_win->sock) { - SILC_NOT_CONNECTED(cmd->client); - goto out; - } - - buffer = silc_command_encode_payload(SILC_COMMAND_IDENTIFY, - cmd->argc - 1, ++cmd->argv, - ++cmd->argv_lens, ++cmd->argv_types); - silc_client_packet_send(cmd->client, cmd->client->current_win->sock, - SILC_PACKET_COMMAND, NULL, 0, NULL, NULL, - buffer->data, buffer->len, TRUE); - silc_buffer_free(buffer); - cmd->argv--; - cmd->argv_lens--; - cmd->argv_types--; - - out: - silc_client_command_free(cmd); -} - -/* Command NICK. Shows current nickname/sets new nickname on current - window. */ - -SILC_CLIENT_CMD_FUNC(nick) -{ - SilcClientCommandContext cmd = (SilcClientCommandContext)context; - SilcClientWindow win = NULL; - SilcBuffer buffer; - - if (!cmd->sock) { - SILC_NOT_CONNECTED(cmd->client); - goto out; - } - - /* Show current nickname */ - if (cmd->argc < 2) { - if (cmd->sock) { - silc_say(cmd->client, "Your nickname is %s on server %s", - win->nickname, win->remote_host); - } else { - silc_say(cmd->client, "Your nickname is %s", win->nickname); - } - goto out; - } - - win = (SilcClientWindow)cmd->sock->user_data; - - /* Set new nickname */ - buffer = silc_command_encode_payload(SILC_COMMAND_NICK, - cmd->argc - 1, ++cmd->argv, - ++cmd->argv_lens, ++cmd->argv_types); - silc_client_packet_send(cmd->client, cmd->sock, - SILC_PACKET_COMMAND, NULL, 0, NULL, NULL, - buffer->data, buffer->len, TRUE); - silc_buffer_free(buffer); - cmd->argv--; - cmd->argv_lens--; - cmd->argv_types--; - if (win->nickname) - silc_free(win->nickname); - win->nickname = strdup(cmd->argv[1]); - - out: - silc_client_command_free(cmd); -} - -/* Command SERVER. Connects to remote SILC server. This is local command. */ - -SILC_CLIENT_CMD_FUNC(server) -{ - SilcClientCommandContext cmd = (SilcClientCommandContext)context; - SilcClient client = cmd->client; - int i = 0, len, port; - char *hostname; - - if (cmd->argc < 2) { - /* Show current servers */ - - if (!cmd->client->current_win->sock) { - silc_say(cmd->client, "You are not connected to any server"); - silc_say(cmd->client, "Usage: /SERVER [[:]]"); - goto out; - } - - silc_say(client, "Current server: %s on %d %s", - client->current_win->remote_host, - client->current_win->remote_port, - client->windows[i]->remote_info ? - client->windows[i]->remote_info : ""); - - silc_say(client, "Server list:"); - for (i = 0; i < client->windows_count; i++) { - silc_say(client, " [%d] %s on %d %s", i + 1, - client->windows[i]->remote_host, - client->windows[i]->remote_port, - client->windows[i]->remote_info ? - client->windows[i]->remote_info : ""); - } - - goto out; - } - - /* See if port is included and then extract it */ - if (strchr(cmd->argv[1], ':')) { - len = strcspn(cmd->argv[1], ":"); - hostname = silc_calloc(len + 1, sizeof(char)); - memcpy(hostname, cmd->argv[1], len); - port = atoi(cmd->argv[1] + 1 + len); - } else { - hostname = cmd->argv[1]; - port = 706; - } - - /* Connect asynchronously to not to block user interface */ - silc_client_connect_to_server(cmd->client, port, hostname); - - out: - silc_client_command_free(cmd); -} - -SILC_CLIENT_CMD_FUNC(list) -{ -} - -SILC_CLIENT_CMD_FUNC(topic) -{ -} - -/* Command INVITE. Invites specific client to join a channel. */ - -SILC_CLIENT_CMD_FUNC(invite) -{ - SilcClientCommandContext cmd = (SilcClientCommandContext)context; - SilcClient client = cmd->client; - SilcClientWindow win = NULL; - SilcClientEntry client_entry; - SilcChannelEntry channel_entry; - SilcBuffer buffer; - unsigned int num = 0; - char *nickname = NULL, *server = NULL; - unsigned char *client_id, *channel_id; - - if (cmd->argc != 3) { - silc_say(cmd->client, "Usage: /INVITE [@] "); - goto out; - } - - if (!cmd->client->current_win->sock) { - SILC_NOT_CONNECTED(cmd->client); - goto out; - } - - win = (SilcClientWindow)cmd->sock->user_data; - - /* Parse the typed nickname. */ - if (!silc_client_parse_nickname(cmd->argv[1], &nickname, &server, &num)) { - silc_say(cmd->client, "Bad nickname"); - goto out; - } - - /* Find client entry */ - client_entry = silc_idlist_get_client(client, win, nickname, server, num); - if (!client_entry) { - /* Client entry not found, it was requested thus mark this to be - pending command. */ - silc_client_command_pending(SILC_COMMAND_IDENTIFY, - silc_client_command_invite, context); - return; - } - - client_id = silc_id_id2str(client_entry->id, SILC_ID_CLIENT); - - /* Find channel entry */ - channel_entry = silc_idlist_get_channel(client, win, cmd->argv[2]); - if (!channel_entry) { - silc_say(cmd->client, "You are not on that channel"); - silc_free(client_id); - goto out; - } - - channel_id = silc_id_id2str(channel_entry->id, SILC_ID_CHANNEL); - - buffer = silc_command_encode_payload_va(SILC_COMMAND_INVITE, 2, - 1, client_id, SILC_ID_CLIENT_LEN, - 2, channel_id, SILC_ID_CHANNEL_LEN); - silc_client_packet_send(cmd->client, win->sock, SILC_PACKET_COMMAND, NULL, - 0, NULL, NULL, buffer->data, buffer->len, TRUE); - silc_buffer_free(buffer); - - silc_say(cmd->client, "Inviting %s to channel %s", cmd->argv[1], - cmd->argv[2]); - - out: - silc_client_command_free(cmd); -} - -/* Command QUIT. Closes connection with current server. */ - -SILC_CLIENT_CMD_FUNC(quit) -{ - SilcClientCommandContext cmd = (SilcClientCommandContext)context; - SilcBuffer buffer; - - if (!cmd->client->current_win->sock) { - SILC_NOT_CONNECTED(cmd->client); - goto out; - } - - buffer = silc_command_encode_payload(SILC_COMMAND_QUIT, cmd->argc - 1, - ++cmd->argv, ++cmd->argv_lens, - ++cmd->argv_types); - silc_client_packet_send(cmd->client, cmd->sock, SILC_PACKET_COMMAND, NULL, - 0, NULL, NULL, buffer->data, buffer->len, TRUE); - silc_buffer_free(buffer); - cmd->argv--; - cmd->argv_lens--; - cmd->argv_types--; - - /* Close connection */ - silc_client_close_connection(cmd->client, cmd->sock); - cmd->client->screen->bottom_line->connection = NULL; - silc_screen_print_bottom_line(cmd->client->screen, 0); - - out: - silc_client_command_free(cmd); -} - -SILC_CLIENT_CMD_FUNC(kill) -{ -} - -/* Command INFO. Request information about specific server. If specific - server is not provided the current server is used. */ - -SILC_CLIENT_CMD_FUNC(info) -{ - SilcClientCommandContext cmd = (SilcClientCommandContext)context; - SilcClientWindow win = NULL; - SilcBuffer buffer; - char *name; - - if (!cmd->sock) { - SILC_NOT_CONNECTED(cmd->client); - goto out; - } - - win = (SilcClientWindow)cmd->sock->user_data; - - if (cmd->argc < 2) - name = strdup(win->remote_host); - else - name = strdup(cmd->argv[1]); - - /* Send the command */ - buffer = silc_command_encode_payload_va(SILC_COMMAND_INFO, 1, - 1, name, strlen(name)); - silc_client_packet_send(cmd->client, win->sock, SILC_PACKET_COMMAND, NULL, - 0, NULL, NULL, buffer->data, buffer->len, TRUE); - silc_buffer_free(buffer); - - out: - silc_client_command_free(cmd); -} - -SILC_CLIENT_CMD_FUNC(connect) -{ -} - -/* Command PING. Sends ping to server. This is used to test the - communication channel. */ - -SILC_CLIENT_CMD_FUNC(ping) -{ - SilcClientCommandContext cmd = (SilcClientCommandContext)context; - SilcClientWindow win = NULL; - SilcBuffer buffer; - void *id; - int i; - char *name = NULL; - - if (!cmd->sock) { - SILC_NOT_CONNECTED(cmd->client); - goto out; - } - - win = (SilcClientWindow)cmd->sock->user_data; - - if (cmd->argc == 1 || !strcmp(cmd->argv[1], win->remote_host)) - name = strdup(win->remote_host); - - id = silc_id_str2id(win->remote_id_data, SILC_ID_SERVER); - - /* Send the command */ - buffer = silc_command_encode_payload_va(SILC_COMMAND_PING, 1, - 1, win->remote_id_data, - SILC_ID_SERVER_LEN); - silc_client_packet_send(cmd->client, win->sock, SILC_PACKET_COMMAND, NULL, - 0, NULL, NULL, buffer->data, buffer->len, TRUE); - silc_buffer_free(buffer); - - /* Start counting time */ - for (i = 0; i < win->ping_count; i++) { - if (win->ping[i].dest_id == NULL) { - win->ping[i].start_time = time(NULL); - win->ping[i].dest_id = id; - win->ping[i].dest_name = name; - win->ping_count++; - break; - } - } - if (i >= win->ping_count) { - i = win->ping_count; - win->ping = silc_realloc(win->ping, sizeof(*win->ping) * (i + 1)); - win->ping[i].start_time = time(NULL); - win->ping[i].dest_id = id; - win->ping[i].dest_name = name; - win->ping_count++; - } - - out: - silc_client_command_free(cmd); -} - -SILC_CLIENT_CMD_FUNC(oper) -{ -} - -SILC_CLIENT_CMD_FUNC(trace) -{ -} - -SILC_CLIENT_CMD_FUNC(notice) -{ -} - -/* Command JOIN. Joins to a channel. */ - -SILC_CLIENT_CMD_FUNC(join) -{ - SilcClientCommandContext cmd = (SilcClientCommandContext)context; - SilcClientWindow win = NULL; - SilcIDCacheEntry id_cache = NULL; - SilcBuffer buffer; - - if (cmd->argc < 2) { - /* Show channels currently joined to */ - if (!cmd->client->current_win->sock) { - silc_say(cmd->client, "No current channel for this window"); - SILC_NOT_CONNECTED(cmd->client); - goto out; - - } - - goto out; - } - - if (!cmd->client->current_win->sock) { - SILC_NOT_CONNECTED(cmd->client); - goto out; - } - - win = (SilcClientWindow)cmd->sock->user_data; - - /* See if we have joined to the requested channel already */ - if (silc_idcache_find_by_data_one(win->channel_cache, cmd->argv[1], - &id_cache)) { - silc_say(cmd->client, "You are talking to channel %s", cmd->argv[1]); - win->current_channel = (SilcChannelEntry)id_cache->context; - cmd->client->screen->bottom_line->channel = cmd->argv[1]; - silc_screen_print_bottom_line(cmd->client->screen, 0); - goto out; - } - - /* Send JOIN command to the server */ - buffer = silc_command_encode_payload(SILC_COMMAND_JOIN, - cmd->argc - 1, ++cmd->argv, - ++cmd->argv_lens, ++cmd->argv_types); - silc_client_packet_send(cmd->client, win->sock, SILC_PACKET_COMMAND, NULL, - 0, NULL, NULL, buffer->data, buffer->len, TRUE); - silc_buffer_free(buffer); - cmd->argv--; - cmd->argv_lens--; - cmd->argv_types--; - - out: - silc_client_command_free(cmd); -} - -SILC_CLIENT_CMD_FUNC(motd) -{ -} - -SILC_CLIENT_CMD_FUNC(umode) -{ -} - -SILC_CLIENT_CMD_FUNC(cmode) -{ -} - -SILC_CLIENT_CMD_FUNC(kick) -{ -} - -SILC_CLIENT_CMD_FUNC(restart) -{ -} - -SILC_CLIENT_CMD_FUNC(close) -{ -} - -SILC_CLIENT_CMD_FUNC(die) -{ -} - -SILC_CLIENT_CMD_FUNC(silcoper) -{ -} - -/* LEAVE command. Leaves a channel. Client removes itself from a channel. */ - -SILC_CLIENT_CMD_FUNC(leave) -{ - SilcClientCommandContext cmd = (SilcClientCommandContext)context; - SilcClientWindow win = NULL; - SilcIDCacheEntry id_cache = NULL; - SilcChannelEntry channel; - SilcBuffer buffer; - unsigned char *id_string; - char *name; - - if (cmd->argc != 2) { - silc_say(cmd->client, "Usage: /LEAVE "); - goto out; - } - - if (!cmd->client->current_win->sock) { - SILC_NOT_CONNECTED(cmd->client); - goto out; - } - - win = (SilcClientWindow)cmd->sock->user_data; - - if (cmd->argv[1][0] == '*') { - if (!win->current_channel) { - silc_say(cmd->client, "You are not on any chanenl"); - goto out; - } - name = win->current_channel->channel_name; - } else { - name = cmd->argv[1]; - } - - if (!win->current_channel) { - silc_say(cmd->client, "You are not on that channel"); - goto out; - } - - /* Get the Channel ID of the channel */ - if (!silc_idcache_find_by_data_one(win->channel_cache, name, &id_cache)) { - silc_say(cmd->client, "You are not on that channel"); - goto out; - } - - channel = (SilcChannelEntry)id_cache->context; - - /* Send LEAVE command to the server */ - id_string = silc_id_id2str(id_cache->id, SILC_ID_CHANNEL); - buffer = silc_command_encode_payload_va(SILC_COMMAND_LEAVE, 1, - 1, id_string, SILC_ID_CHANNEL_LEN); - silc_client_packet_send(cmd->client, win->sock, SILC_PACKET_COMMAND, NULL, - 0, NULL, NULL, buffer->data, buffer->len, TRUE); - silc_buffer_free(buffer); - - /* We won't talk anymore on this channel */ - silc_say(cmd->client, "You have left channel %s", name); - - if (!strncmp(win->current_channel->channel_name, name, strlen(name))) { - cmd->client->screen->bottom_line->channel = NULL; - silc_screen_print_bottom_line(cmd->client->screen, 0); - win->current_channel = NULL; - } - - silc_idcache_del_by_id(win->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); - silc_free(id_string); - - out: - silc_client_command_free(cmd); -} - -/* Command NAMES. Requests the names of the clients joined on requested - channel. */ - -SILC_CLIENT_CMD_FUNC(names) -{ - SilcClientCommandContext cmd = (SilcClientCommandContext)context; - SilcClientWindow win = NULL; - SilcIDCacheEntry id_cache = NULL; - SilcBuffer buffer; - char *name; - unsigned char *id_string; - - if (cmd->argc != 2) { - silc_say(cmd->client, "Usage: /NAMES "); - goto out; - } - - if (!cmd->client->current_win->sock) { - SILC_NOT_CONNECTED(cmd->client); - goto out; - } - - win = (SilcClientWindow)cmd->sock->user_data; - - if (cmd->argv[1][0] == '*') - name = win->current_channel->channel_name; - else - name = cmd->argv[1]; - - /* Get the Channel ID of the channel */ - if (!silc_idcache_find_by_data_one(win->channel_cache, name, &id_cache)) { - /* XXX should resolve the channel ID; LIST command */ - silc_say(cmd->client, "You are not on that channel", name); - goto out; - } - - /* Send NAMES command to the server */ - id_string = silc_id_id2str(id_cache->id, SILC_ID_CHANNEL); - buffer = silc_command_encode_payload_va(SILC_COMMAND_NAMES, 1, - 1, id_string, SILC_ID_CHANNEL_LEN); - silc_client_packet_send(cmd->client, win->sock, SILC_PACKET_COMMAND, NULL, - 0, NULL, NULL, buffer->data, buffer->len, TRUE); - silc_buffer_free(buffer); - silc_free(id_string); - - /* Register dummy pending command that will tell the reply command - that user called this command. Server may send reply to this command - even if user did not send this command thus we want to handle things - differently when user sent the command. This is dummy and won't be - execute. */ - /* XXX this is kludge and should be removed after pending command reply - support is added. Currently only commands may be pending not command - replies. */ - silc_client_command_pending(SILC_COMMAND_NAMES, - silc_client_command_names, NULL); - - out: - silc_client_command_free(cmd); -} - -/* - * Local commands - */ - -/* HELP command. This is local command and shows help on SILC */ - -SILC_CLIENT_CMD_FUNC(help) -{ - -} - -/* CLEAR command. This is local command and clears current output window */ - -SILC_CLIENT_CMD_FUNC(clear) -{ - SilcClientCommandContext cmd = (SilcClientCommandContext)context; - SilcClient client = cmd->client; - - assert(client->current_win != NULL); - wclear((WINDOW *)client->current_win->screen); - wrefresh((WINDOW *)client->current_win->screen); - - silc_client_command_free(cmd); -} - -/* VERSION command. This is local command and shows version of the client */ - -SILC_CLIENT_CMD_FUNC(version) -{ - SilcClientCommandContext cmd = (SilcClientCommandContext)context; - SilcClient client = cmd->client; - extern char *silc_version; - extern char *silc_name; - extern char *silc_fullname; - - silc_say(client, "%s (%s) version %s", silc_name, silc_fullname, - silc_version); - - silc_client_command_free(cmd); -} - -/* Command MSG. Sends private message to user or list of users. Note that - private messages are not really commands, they are message packets, - however, on user interface it is convenient to show them as commands - as that is the common way of sending private messages (like in IRC). */ -/* XXX supports only one destination */ - -SILC_CLIENT_CMD_FUNC(msg) -{ - SilcClientCommandContext cmd = (SilcClientCommandContext)context; - SilcClientWindow win = NULL; - SilcClient client = cmd->client; - SilcClientEntry client_entry = NULL; - unsigned int num = 0; - char *nickname = NULL, *server = NULL; - - if (cmd->argc < 3) { - silc_say(cmd->client, "Usage: /MSG "); - goto out; - } - - if (!cmd->client->current_win->sock) { - SILC_NOT_CONNECTED(cmd->client); - goto out; - } - - win = (SilcClientWindow)cmd->sock->user_data; - - /* Parse the typed nickname. */ - if (!silc_client_parse_nickname(cmd->argv[1], &nickname, &server, &num)) { - silc_say(cmd->client, "Bad nickname"); - goto out; - } - - /* Find client entry */ - client_entry = silc_idlist_get_client(client, win, nickname, server, num); - if (!client_entry) { - /* Client entry not found, it was requested thus mark this to be - pending command. */ - silc_client_command_pending(SILC_COMMAND_IDENTIFY, - silc_client_command_msg, context); - return; - } - - /* Display the message for our eyes. */ - silc_print(client, "-> *%s* %s", cmd->argv[1], cmd->argv[2]); - - /* Send the private message */ - silc_client_packet_send_private_message(client, cmd->sock, client_entry, - cmd->argv[2], cmd->argv_lens[2], - TRUE); - - out: - silc_client_command_free(cmd); -} - -/* Local command AWAY. Client replies with away message to whomever sends - private message to the client if the away message is set. If this is - given without arguments the away message is removed. */ - -SILC_CLIENT_CMD_FUNC(away) -{ - SilcClientCommandContext cmd = (SilcClientCommandContext)context; - SilcClientWindow win = NULL; - SilcClient client = cmd->client; - - if (!cmd->client->current_win->sock) { - SILC_NOT_CONNECTED(cmd->client); - goto out; - } - - win = (SilcClientWindow)cmd->sock->user_data; - - if (cmd->argc == 1) { - if (win->away) { - silc_free(win->away->away); - silc_free(win->away); - win->away = NULL; - client->screen->bottom_line->away = FALSE; - - silc_say(client, "Away message removed"); - silc_screen_print_bottom_line(cmd->client->screen, 0); - } - } else { - - if (win->away) - silc_free(win->away->away); - else - win->away = silc_calloc(1, sizeof(*win->away)); - - client->screen->bottom_line->away = TRUE; - win->away->away = strdup(cmd->argv[1]); - - silc_say(client, "Away message set: %s", win->away->away); - silc_screen_print_bottom_line(cmd->client->screen, 0); - } - - out: - silc_client_command_free(cmd); -}