Author: Pekka Riikonen <priikone@silcnet.org>
- Copyright (C) 1997 - 2005, 2007 Pekka Riikonen
+ Copyright (C) 1997 - 2007 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
else
silc_schedule_task_add_timeout(server->schedule,
silc_server_command_process_timeout,
- timeout, 0, 1);
+ timeout, 0, 0);
return;
}
{
SilcServerCommandContext cmd = (SilcServerCommandContext)context;
SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_WHOIS, cmd, 1, 256);
- silc_server_query_command(cmd->server, SILC_COMMAND_WHOIS, cmd);
+ silc_server_query_command(cmd->server, SILC_COMMAND_WHOIS, cmd, NULL);
silc_server_command_free(cmd);
}
{
SilcServerCommandContext cmd = (SilcServerCommandContext)context;
SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_WHOWAS, cmd, 1, 2);
- silc_server_query_command(cmd->server, SILC_COMMAND_WHOWAS, cmd);
+ silc_server_query_command(cmd->server, SILC_COMMAND_WHOWAS, cmd, NULL);
silc_server_command_free(cmd);
}
{
SilcServerCommandContext cmd = (SilcServerCommandContext)context;
SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_IDENTIFY, cmd, 1, 256);
- silc_server_query_command(cmd->server, SILC_COMMAND_IDENTIFY, cmd);
+ silc_server_query_command(cmd->server, SILC_COMMAND_IDENTIFY, cmd, NULL);
silc_server_command_free(cmd);
}
/* Truncate over long nicks */
if (nick_len > 128) {
- nick[128] = '\0';
nick_len = 128;
+ nick[nick_len - 1] = '\0';
}
/* Check for valid nickname string. This is cached, original is saved
oidp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
- /* Remove old cache entry */
- silc_idcache_del_by_context(server->local_list->clients, client, NULL);
-
- silc_free(client->id);
- client->id = new_id;
-
+ /* Update client entry */
+ silc_idcache_update_by_context(server->local_list->clients, client,
+ new_id, nickc, TRUE);
+ silc_free(new_id);
silc_free(client->nickname);
client->nickname = strdup(nick);
- /* Update client cache */
- silc_idcache_add(server->local_list->clients, nickc,
- client->id, (void *)client);
-
nidp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
/* Send NICK_CHANGE notify to the client's channels */
SilcServerCommandContext cmd = (SilcServerCommandContext)context;
SilcServer server = cmd->server;
SilcID id;
+ SilcChannelID *channel_id = NULL;
SilcChannelEntry *lchannels = NULL, *gchannels = NULL;
SilcUInt32 lch_count = 0, gch_count = 0;
}
/* Get Channel ID */
- if (!silc_argument_get_decoded(cmd->args, 1, SILC_ARGUMENT_ID, &id, NULL)) {
- silc_server_command_send_status_reply(cmd, SILC_COMMAND_LIST,
- SILC_STATUS_ERR_NO_CHANNEL_ID, 0);
- goto out;
- }
+ if (silc_argument_get_decoded(cmd->args, 1, SILC_ARGUMENT_ID, &id, NULL))
+ channel_id = SILC_ID_GET_ID(id);
/* Get the channels from local list */
- lchannels = silc_idlist_get_channels(server->local_list, SILC_ID_GET_ID(id),
+ lchannels = silc_idlist_get_channels(server->local_list, channel_id,
&lch_count);
/* Get the channels from global list */
- gchannels = silc_idlist_get_channels(server->global_list, SILC_ID_GET_ID(id),
+ gchannels = silc_idlist_get_channels(server->global_list, channel_id,
&gch_count);
/* Send the reply */
if (client) {
/* Free all client specific data, such as client entry and entires
on channels this client may be on. */
- silc_server_free_client_data(server, q->sock, client,
- TRUE, q->signoff);
- silc_packet_set_context(q->sock, NULL);
+ silc_server_free_sock_user_data(server, q->sock, q->signoff);
+ silc_server_close_connection(server, q->sock);
}
silc_packet_stream_unref(q->sock);
comment = silc_argument_get_arg_type(cmd->args, 2, &tmp_len2);
if (comment && tmp_len2 > 128) {
tmp_len2 = 128;
- comment[127] = '\0';
+ comment[tmp_len2 - 1] = '\0';
}
/* If authentication data is provided then verify that killing is
goto out;
}
+ SILC_LOG_DEBUG(("id %s", silc_id_render(SILC_ID_GET_ID(id),
+ id.type)));
+
/* The ID must be ours */
if (!SILC_ID_SERVER_COMPARE(server->id, SILC_ID_GET_ID(id))) {
tmp = silc_argument_get_arg_type(cmd->args, 1, &tmp_len);
if (!channel)
return;
- silc_socket_stream_get_info(sock, NULL, &hostname, &ip, NULL);
+ silc_socket_stream_get_info(silc_packet_stream_get_stream(sock),
+ NULL, &hostname, &ip, NULL);
/* Get the client entry */
if (idata->conn_type == SILC_CONN_CLIENT) {
/* Server side of command JOIN. Joins client into requested channel. If
the channel does not exist it will be created. */
+/* Ways of creating channel with dynamic connections:
+
+ 1. If channels are not local (no local_channels in silcd.conf) then
+ /join silc, will create connection to default router if it is
+ specified in the silcd.conf. If it isn't, it creates local channel.
+
+ 2. If channels are not local then /join silc@silcnet.org, will create
+ connection to default if it is specified in the silcd.conf and if it
+ isn't or join fails it creates connection to silcnet.org and sends
+ the JOIN command to that server/router.
+
+ 3. If channels are local (local_channels set in silcd.conf) then
+ /join silc, will create local channel. No connections are created
+ to anywhere.
+
+ 4. If channels are local then /join silc@silcnet.org will create
+ connection to default router if it is specified in the silcd.conf and
+ if it isn't, or join fails it creates connection to silcnet.org and
+ send the JOIN command to that server/router.
+
+ 5. If we create connection to a remote that already has a channel that
+ we also have as a local channel, should we merge those channels?
+ Should I announce my local channels when I connect to router? Should
+ I keep local channels local, unless I say /join localch@silcnet.org
+ in which case the local channel 'localch' becomes global?
+
+ 6. After we have connection established to router, depending on the
+ local_channels setting /join silc will join locally or globally.
+ /join silc@silcnet.org would always join globally.
+*/
+
SILC_SERVER_CMD_FUNC(join)
{
SilcServerCommandContext cmd = (SilcServerCommandContext)context;
unsigned char *auth, *cauth;
SilcUInt32 tmp_len, auth_len, cauth_len;
char *tmp, *channel_name, *channel_namec = NULL, *cipher, *hmac;
+ char parsed[256 + 1], serv[256 + 1];
SilcChannelEntry channel;
SilcUInt32 umode = 0;
SilcBool created = FALSE, create_key = TRUE;
/* Truncate over long channel names */
if (tmp_len > 256) {
- tmp[tmp_len - 1] = '\0';
tmp_len = 256;
+ tmp[tmp_len - 1] = '\0';
}
- channel_name = tmp;
+
+ /* Parse server name from the channel name */
+ silc_parse_userfqdn(channel_name, parsed, sizeof(parsed), serv,
+ sizeof(serv));
+ channel_name = parsed;
/* Check for valid channel name. This is cached, the original is saved
in the channel context. */
- channel_namec = silc_channel_name_check(tmp, tmp_len, SILC_STRING_UTF8, 256,
- NULL);
+ channel_namec = silc_channel_name_check(channel_name, strlen(channel_name),
+ SILC_STRING_UTF8, 256, NULL);
if (!channel_namec) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_JOIN,
SILC_STATUS_ERR_BAD_CHANNEL, 0);
SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_OPER, cmd, 1, 2);
- silc_socket_stream_get_info(cmd->sock, NULL, &hostname, &ip, NULL);
+ silc_socket_stream_get_info(silc_packet_stream_get_stream(cmd->sock),
+ NULL, &hostname, &ip, NULL);
/* Get the username */
username = silc_argument_get_arg_type(cmd->args, 1, &tmp_len);
}
if (add_nick && add_nick_len > 128) {
- add_nick[128] = '\0';
add_nick_len = 128;
+ add_nick[add_nick_len - 1] = '\0';
}
if (del_nick && del_nick_len > 128) {
- del_nick[128] = '\0';
del_nick_len = 128;
+ del_nick[del_nick_len - 1] = '\0';
}
/* Add new nickname to be watched in our cell */
SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_SILCOPER, cmd, 1, 2);
- silc_socket_stream_get_info(cmd->sock, NULL, &hostname, &ip, NULL);
+ silc_socket_stream_get_info(silc_packet_stream_get_stream(cmd->sock),
+ NULL, &hostname, &ip, NULL);
if (server->server_type != SILC_ROUTER) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_SILCOPER,
SILC_STR_END);
silc_hash_table_list(channel->ban_list, &htl);
while (silc_hash_table_get(&htl, (void *)&type, (void *)&tmp2))
- list = silc_argument_payload_encode_one(list, tmp2->data, silc_buffer_len(tmp2),
- type);
+ list = silc_argument_payload_encode_one(list, tmp2->data,
+ silc_buffer_len(tmp2), type);
silc_hash_table_list_reset(&htl);
}
+ tmp_id = silc_argument_get_arg_type(cmd->args, 1, &id_len);
+
/* Send BAN notify type to local servers (but not clients) and to
network. */
if (atype && tmp && len2) {
if (server->server_type == SILC_ROUTER)
silc_server_send_notify_to_channel(server, NULL, channel, FALSE, FALSE,
SILC_NOTIFY_TYPE_BAN, 3,
- id, id_len,
+ tmp_id, id_len,
atype, 1,
tmp ? blist.data : NULL,
tmp ? silc_buffer_len(&blist) : 0);
/* Send the reply back to the client */
silc_server_send_command_reply(server, cmd->sock, SILC_COMMAND_BAN,
SILC_STATUS_OK, 0, ident, 2,
- 2, id, id_len,
+ 2, tmp_id, id_len,
3, list ? list->data : NULL,
list ? silc_buffer_len(list) : 0);
silc_buffer_free(list);
SILC_GET32_MSB(port, tmp);
/* Create the connection. It is done with timeout and is async. */
- silc_server_create_connection(server, FALSE, host, port, NULL, NULL);
+ silc_server_create_connection(server, FALSE, FALSE, host, port, NULL, NULL);
/* Send reply to the sender */
silc_server_command_send_status_reply(cmd, SILC_COMMAND_PRIV_CONNECT,