+Sun Feb 25 20:47:29 EET 2001 Pekka Riikonen <priikone@poseidon.pspt.fi>
+
+ * Implemented CONNECT and SHUTDOWN commands in the client.
+
Sat Feb 24 23:45:49 EET 2001 Pekka Riikonen <priikone@poseidon.pspt.fi>
* DIE command was renamed to SHUTDOWN. Updated the both code
server operator to be able to do this.
- /CLOSE <server>
+ /CLOSE <server> [<port>]
Closes connection to the <server>. You must be server
operator to be able to do this.
/* Check whether client has the permissions. */
if (client->mode == SILC_UMODE_NONE) {
- silc_server_command_send_status_reply(cmd, SILC_COMMAND_CLOSE,
+ silc_server_command_send_status_reply(cmd, SILC_COMMAND_CONNECT,
SILC_STATUS_ERR_NO_SERVER_PRIV);
goto out;
}
if (server->server_type == SILC_ROUTER &&
client->mode & SILC_UMODE_SERVER_OPERATOR) {
- silc_server_command_send_status_reply(cmd, SILC_COMMAND_CLOSE,
+ silc_server_command_send_status_reply(cmd, SILC_COMMAND_CONNECT,
SILC_STATUS_ERR_NO_ROUTER_PRIV);
goto out;
}
/* Get the remote server */
tmp = silc_argument_get_arg_type(cmd->args, 1, &tmp_len);
if (!tmp) {
- silc_server_command_send_status_reply(cmd, SILC_COMMAND_CLOSE,
+ silc_server_command_send_status_reply(cmd, SILC_COMMAND_CONNECT,
SILC_STATUS_ERR_NOT_ENOUGH_PARAMS);
goto out;
}
silc_server_create_connection(server, tmp, port);
/* Send reply to the sender */
- silc_server_command_send_status_reply(cmd, SILC_COMMAND_INVITE,
+ silc_server_command_send_status_reply(cmd, SILC_COMMAND_CONNECT,
SILC_STATUS_OK);
out:
SilcServerCommandContext cmd = (SilcServerCommandContext)context;
SilcServer server = cmd->server;
SilcClientEntry client = (SilcClientEntry)cmd->sock->user_data;
- SilcServerID *server_id;
SilcServerEntry server_entry;
unsigned char *tmp;
unsigned int tmp_len;
+ unsigned char *name;
+ unsigned int port = SILC_PORT;
SILC_SERVER_COMMAND_CHECK_ARGC(SILC_COMMAND_CLOSE, cmd, 0, 0);
goto out;
}
- /* Get the server ID */
- tmp = silc_argument_get_arg_type(cmd->args, 1, &tmp_len);
- if (!tmp) {
- silc_server_command_send_status_reply(cmd, SILC_COMMAND_CLOSE,
- SILC_STATUS_ERR_NO_SERVER_ID);
- goto out;
- }
- server_id = silc_id_payload_parse_id(tmp, tmp_len);
- if (!server_id) {
+ /* Get the remote server */
+ name = silc_argument_get_arg_type(cmd->args, 1, &tmp_len);
+ if (!name) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_CLOSE,
- SILC_STATUS_ERR_NO_SERVER_ID);
+ SILC_STATUS_ERR_NOT_ENOUGH_PARAMS);
goto out;
}
- /* Check that the server ID is valid and that I have an active
- connection to it. Check only local list as it holds the local
- connections. */
- server_entry = silc_idlist_find_server_by_id(server->local_list,
- server_id, NULL);
+ /* Get port */
+ tmp = silc_argument_get_arg_type(cmd->args, 2, &tmp_len);
+ if (tmp)
+ SILC_GET32_MSB(port, tmp);
+
+ server_entry = silc_idlist_find_server_by_conn(server->local_list,
+ name, port, NULL);
if (!server_entry) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_CLOSE,
SILC_STATUS_ERR_NO_SERVER_ID);
"Closed by operator");
/* Send reply to the sender */
- silc_server_command_send_status_reply(cmd, SILC_COMMAND_INVITE,
+ silc_server_command_send_status_reply(cmd, SILC_COMMAND_CLOSE,
SILC_STATUS_OK);
out:
silc_server_stop(server);
/* Send reply to the sender */
- silc_server_command_send_status_reply(cmd, SILC_COMMAND_INVITE,
+ silc_server_command_send_status_reply(cmd, SILC_COMMAND_SHUTDOWN,
SILC_STATUS_OK);
out:
return server;
}
+/* Find server by name */
+
+SilcServerEntry
+silc_idlist_find_server_by_name(SilcIDList id_list, char *name,
+ SilcIDCacheEntry *ret_entry)
+{
+ SilcIDCacheEntry id_cache = NULL;
+ SilcServerEntry server;
+
+ SILC_LOG_DEBUG(("Server by name `%s'", name));
+
+ if (!silc_idcache_find_by_data_one(id_list->servers, name, &id_cache))
+ return NULL;
+
+ server = (SilcServerEntry)id_cache->context;
+
+ if (ret_entry)
+ *ret_entry = id_cache;
+
+ return server;
+}
+
+/* Find server by connection parameters, hostname and port */
+
+SilcServerEntry
+silc_idlist_find_server_by_conn(SilcIDList id_list, char *hostname,
+ int port, SilcIDCacheEntry *ret_entry)
+{
+ SilcIDCacheList list = NULL;
+ SilcIDCacheEntry id_cache = NULL;
+ SilcServerEntry server = NULL;
+ SilcSocketConnection sock;
+
+ SILC_LOG_DEBUG(("Server by hostname %s and port %d", hostname, port));
+
+ if (!silc_idcache_find_by_id(id_list->servers, SILC_ID_CACHE_ANY,
+ SILC_ID_SERVER, &list))
+ return NULL;
+
+ if (!silc_idcache_list_first(list, &id_cache)) {
+ silc_idcache_list_free(list);
+ return NULL;
+ }
+
+ while (id_cache) {
+ server = (SilcServerEntry)id_cache->context;
+ sock = (SilcSocketConnection)server->connection;
+
+ if (sock && (!strcmp(sock->hostname, hostname) ||
+ !strcmp(sock->ip, hostname)) && sock->port == port)
+ break;
+
+ id_cache = NULL;
+ server = NULL;
+
+ if (!silc_idcache_list_next(list, &id_cache))
+ break;
+ }
+
+ silc_idcache_list_free(list);
+
+ if (ret_entry)
+ *ret_entry = id_cache;
+
+ SILC_LOG_DEBUG(("Found"));
+
+ return server;
+}
+
/* Replaces old Server ID with new one */
SilcServerEntry
silc_idlist_find_server_by_id(SilcIDList id_list, SilcServerID *id,
SilcIDCacheEntry *ret_entry);
SilcServerEntry
+silc_idlist_find_server_by_name(SilcIDList id_list, char *name,
+ SilcIDCacheEntry *ret_entry);
+SilcServerEntry
+silc_idlist_find_server_by_conn(SilcIDList id_list, char *hostname,
+ int port, SilcIDCacheEntry *ret_entry);
+SilcServerEntry
silc_idlist_replace_server_id(SilcIDList id_list, SilcServerID *old_id,
SilcServerID *new_id);
void silc_idlist_del_server(SilcIDList id_list, SilcServerEntry entry);
/* General definitions */
+/* SILC port */
+#define SILC_PORT 768;
+
/* Server and router. Used internally by the code. */
#define SILC_SERVER 0
#define SILC_ROUTER 1
21 SILC_COMMAND_CLOSE
- Max Arguments: 1
- Arguments: (1) <Server ID>
+ Max Arguments: 2
+ Arguments: (1) <remote server/router> (2) [<port>]
This command is used only by operator to close connection to a
- remote site. The <Server ID> argument is the ID of the remote
- site and must be valid.
+ remote site.
Reply messages to the command:
silc_client_command_free(cmd);
}
-SILC_CLIENT_CMD_FUNC(trace)
-{
-}
-
SILC_CLIENT_CMD_FUNC(notice)
{
}
SILC_CLIENT_CMD_FUNC(restart)
{
}
+
+/* CLOSE command. Close server connection to the remote server */
SILC_CLIENT_CMD_FUNC(close)
{
+ SilcClientCommandContext cmd = (SilcClientCommandContext)context;
+ SilcClientConnection conn = cmd->conn;
+ SilcBuffer buffer;
+ unsigned char port[4];
+
+ if (!cmd->conn) {
+ SILC_NOT_CONNECTED(cmd->client, cmd->conn);
+ COMMAND_ERROR;
+ goto out;
+ }
+
+ if (cmd->argc < 2) {
+ cmd->client->ops->say(cmd->client, conn,
+ "Usage: /CLOSE <server> [<port>]");
+ COMMAND_ERROR;
+ goto out;
+ }
+
+ if (cmd->argc == 3)
+ SILC_PUT32_MSB(atoi(cmd->argv[2]), port);
+
+ if (cmd->argc == 3)
+ buffer = silc_command_payload_encode_va(SILC_COMMAND_CLOSE, 0, 2,
+ 1, cmd->argv[1],
+ strlen(cmd->argv[1]),
+ 2, port, 4);
+ else
+ buffer = silc_command_payload_encode_va(SILC_COMMAND_CLOSE, 0, 1,
+ 1, cmd->argv[1],
+ strlen(cmd->argv[1]));
+ silc_client_packet_send(cmd->client, conn->sock, SILC_PACKET_COMMAND, NULL,
+ 0, NULL, NULL, buffer->data, buffer->len, TRUE);
+ silc_buffer_free(buffer);
+
+ /* Notify application */
+ COMMAND;
+
+ out:
+ silc_client_command_free(cmd);
}
/* SHUTDOWN command. Shutdowns the server. */
SILC_CLIENT_CMD_REPLY_FUNC(connect)
{
+ 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_CONNECT);
+
+ out:
+ SILC_CLIENT_PENDING_DESTRUCTOR(cmd, SILC_COMMAND_CONNECT);
+ silc_client_command_reply_free(cmd);
}
SILC_CLIENT_CMD_REPLY_FUNC(restart)
{
+ 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_RESTART);
+
+ out:
+ SILC_CLIENT_PENDING_DESTRUCTOR(cmd, SILC_COMMAND_RESTART);
+ silc_client_command_reply_free(cmd);
}
SILC_CLIENT_CMD_REPLY_FUNC(close)
{
+ 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_CLOSE);
+
+ out:
+ SILC_CLIENT_PENDING_DESTRUCTOR(cmd, SILC_COMMAND_CLOSE);
+ silc_client_command_reply_free(cmd);
}
SILC_CLIENT_CMD_REPLY_FUNC(shutdown)
{
+ 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_SHUTDOWN);
+
+ out:
+ SILC_CLIENT_PENDING_DESTRUCTOR(cmd, SILC_COMMAND_SHUTDOWN);
+ silc_client_command_reply_free(cmd);
}
/* Reply to LEAVE command. */
SILC_CLIENT_CMD_REPLY_FUNC(list);
SILC_CLIENT_CMD_REPLY_FUNC(topic);
SILC_CLIENT_CMD_REPLY_FUNC(invite);
-SILC_CLIENT_CMD_REPLY_FUNC(quit);
SILC_CLIENT_CMD_REPLY_FUNC(kill);
SILC_CLIENT_CMD_REPLY_FUNC(info);
SILC_CLIENT_CMD_REPLY_FUNC(links);
SILC_CLIENT_CMD_REPLY_FUNC(kick);
SILC_CLIENT_CMD_REPLY_FUNC(restart);
SILC_CLIENT_CMD_REPLY_FUNC(close);
-SILC_CLIENT_CMD_REPLY_FUNC(die);
+SILC_CLIENT_CMD_REPLY_FUNC(shutdown);
SILC_CLIENT_CMD_REPLY_FUNC(silcoper);
SILC_CLIENT_CMD_REPLY_FUNC(leave);
SILC_CLIENT_CMD_REPLY_FUNC(users);