/* Replace the old ID */
switch(old_id_type) {
case SILC_ID_CLIENT:
- SILC_LOG_DEBUG(("Old Client ID id(%s)",
- silc_id_render(id, SILC_ID_CLIENT)));
- SILC_LOG_DEBUG(("New Client ID id(%s)",
- silc_id_render(id2, SILC_ID_CLIENT)));
- if (silc_idlist_replace_client_id(server->local_list, id, id2) == NULL)
- if (server->server_type == SILC_ROUTER)
- silc_idlist_replace_client_id(server->global_list, id, id2);
- break;
+ {
+ SilcBuffer nidp, oidp;
+ SilcClientEntry client = NULL;
+
+ SILC_LOG_DEBUG(("Old Client ID id(%s)",
+ silc_id_render(id, SILC_ID_CLIENT)));
+ SILC_LOG_DEBUG(("New Client ID id(%s)",
+ silc_id_render(id2, SILC_ID_CLIENT)));
+
+ if ((client = silc_idlist_replace_client_id(server->local_list,
+ id, id2)) == NULL)
+ if (server->server_type == SILC_ROUTER)
+ client = silc_idlist_replace_client_id(server->global_list, id, id2);
+
+ if (client) {
+ oidp = silc_id_payload_encode(id, SILC_ID_CLIENT);
+ nidp = silc_id_payload_encode(id2, SILC_ID_CLIENT);
+
+ /* Send the NICK_CHANGE notify type to local clients on the channels
+ this client is joined to. */
+ silc_server_send_notify_on_channels(server, client,
+ SILC_NOTIFY_TYPE_NICK_CHANGE, 2,
+ oidp->data, oidp->len,
+ nidp->data, nidp->len);
+
+ silc_buffer_free(nidp);
+ silc_buffer_free(oidp);
+ }
+ break;
+ }
case SILC_ID_SERVER:
SILC_LOG_DEBUG(("Old Server ID id(%s)",
SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
("Welcome to the SILC Network %s@%s",
username, sock->hostname));
+ SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
+ ("Your host is %s, running version %s",
+ server->config->server_info->server_name,
+ server_version));
if (server->server_type == SILC_ROUTER) {
SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
("There are %d clients on %d servers in SILC "
"Network", server->stat.clients,
- server->stat.servers));
+ server->stat.servers + 1));
SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
("There are %d clients on %d server in our cell",
server->stat.cell_clients,
("%d operators online",
server->stat.my_server_ops));
}
- SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
- ("Your host is %s, running version %s",
- server->config->server_info->server_name,
- server_version));
SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
("Your connection is secured with %s cipher, "
"key length %d bits",
SilcNotifyType type;
SilcArgumentPayload args;
SilcChannelID *channel_id;
- SilcClientID *client_id;
+ SilcClientID *client_id, *client_id2;
SilcChannelEntry channel;
SilcClientEntry client;
unsigned char *tmp;
if (!client) {
client = silc_idlist_find_client_by_id(server->local_list,
client_id, NULL);
- if (!client)
+ if (!client) {
+ silc_free(client_id);
goto out;
+ }
}
silc_free(client_id);
silc_idlist_del_client(server->global_list, client);
break;
- /* Ignore rest notify types for now */
- case SILC_NOTIFY_TYPE_NONE:
- case SILC_NOTIFY_TYPE_INVITE:
+ case SILC_NOTIFY_TYPE_NICK_CHANGE:
+ {
+ /*
+ * Distribute the notify to local clients on the channel
+ */
+ unsigned char *id, *id2;
+
+ SILC_LOG_DEBUG(("NICK CHANGE notify"));
+
+ /* Get old client ID */
+ id = silc_argument_get_arg_type(args, 1, &tmp_len);
+ if (!id)
+ goto out;
+ client_id = silc_id_payload_parse_id(id, tmp_len);
+
+ /* Get new client ID */
+ id2 = silc_argument_get_arg_type(args, 2, &tmp_len);
+ if (!id2)
+ goto out;
+ client_id2 = silc_id_payload_parse_id(id2, tmp_len);
+
+ SILC_LOG_DEBUG(("Old Client ID id(%s)",
+ silc_id_render(client_id, SILC_ID_CLIENT)));
+ SILC_LOG_DEBUG(("New Client ID id(%s)",
+ silc_id_render(client_id2, SILC_ID_CLIENT)));
+
+ /* Replace the Client ID */
+ client = silc_idlist_replace_client_id(server->global_list, client_id,
+ client_id2);
+ if (!client)
+ client = silc_idlist_replace_client_id(server->local_list, client_id,
+ client_id2);
+
+ if (client)
+ /* Send the NICK_CHANGE notify type to local clients on the channels
+ this client is joined to. */
+ silc_server_send_notify_on_channels(server, client,
+ SILC_NOTIFY_TYPE_NICK_CHANGE, 2,
+ id, tmp_len,
+ id2, tmp_len);
+
+ silc_free(client_id);
+ if (!client)
+ silc_free(client_id2);
+ break;
+ }
case SILC_NOTIFY_TYPE_TOPIC_SET:
+ /*
+ * Distribute the notify to local clients on the channel
+ */
+ SILC_LOG_DEBUG(("TOPIC SET notify (not-impl XXX)"));
+ break;
+
case SILC_NOTIFY_TYPE_CMODE_CHANGE:
+ /*
+ * Distribute the notify to local clients on the channel
+ */
+ SILC_LOG_DEBUG(("CMODE CHANGE notify (not-impl XXX)"));
+ break;
+
case SILC_NOTIFY_TYPE_CUMODE_CHANGE:
+ /*
+ * Distribute the notify to local clients on the channel
+ */
+ SILC_LOG_DEBUG(("CUMODE CHANGE notify (not-impl XXX)"));
+ break;
+
+ /* Ignore rest notify types for now */
+ case SILC_NOTIFY_TYPE_NONE:
+ case SILC_NOTIFY_TYPE_INVITE:
case SILC_NOTIFY_TYPE_MOTD:
default:
break;
out:
silc_id_payload_free(idp);
}
+
+/* Processes received SET_MODE packet. The packet is used to distribute
+ the information about changed channel's or client's channel modes. */
+
+void silc_server_set_mode(SilcServer server,
+ SilcSocketConnection sock,
+ SilcPacketContext *packet)
+{
+ SilcSetModePayload payload = NULL;
+ SilcArgumentPayload args = NULL;
+ unsigned short mode_type;
+ unsigned int mode_mask;
+ unsigned char *tmp, *tmp2;
+ unsigned int tmp_len, tmp_len2;
+ unsigned char mode[4];
+ SilcClientID *client_id;
+ SilcChannelID *channel_id = NULL;
+ SilcClientEntry client;
+ SilcChannelEntry channel;
+ SilcChannelClientEntry chl;
+
+ if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
+ packet->src_id_type == SILC_ID_CLIENT)
+ return;
+
+ SILC_LOG_DEBUG(("Start"));
+
+ /* If we are router and this packet is not already broadcast packet
+ we will broadcast it. The sending socket really cannot be router or
+ the router is buggy. If this packet is coming from router then it must
+ have the broadcast flag set already and we won't do anything. */
+ if (!server->standalone && server->server_type == SILC_ROUTER &&
+ sock->type == SILC_SOCKET_TYPE_SERVER &&
+ !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
+ SILC_LOG_DEBUG(("Broadcasting received Set Mode packet"));
+ silc_server_packet_send(server, server->router->connection, packet->type,
+ packet->flags | SILC_PACKET_FLAG_BROADCAST,
+ packet->buffer->data, packet->buffer->len, FALSE);
+ }
+
+ /* Parse Set Mode payload */
+ payload = silc_set_mode_payload_parse(packet->buffer);
+ if (!payload)
+ return;
+
+ mode_type = silc_set_mode_get_type(payload);
+ args = silc_set_mode_get_args(payload);
+ if (!args)
+ goto out;
+
+ mode_mask = silc_set_mode_get_mode(payload);
+ SILC_PUT32_MSB(mode_mask, mode);
+
+ switch (mode_type) {
+ case SILC_MODE_TYPE_CHANNEL:
+ /* Get Channel ID */
+ tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
+ if (!tmp)
+ goto out;
+ channel_id = silc_id_payload_parse_id(tmp, tmp_len);
+ if (!channel_id)
+ goto out;
+
+ /* Get channel entry */
+ channel = silc_idlist_find_channel_by_id(server->local_list,
+ channel_id, NULL);
+ if (!channel) {
+ channel = silc_idlist_find_channel_by_id(server->global_list,
+ channel_id, NULL);
+ if (!channel)
+ goto out;
+ }
+
+ /* Get Client ID payload */
+ tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
+ if (!tmp)
+ goto out;
+
+ /* Send CMODE_CHANGE notify to local channel */
+ silc_server_send_notify_to_channel(server, sock, channel, FALSE,
+ SILC_NOTIFY_TYPE_CMODE_CHANGE,
+ 2, tmp, tmp_len,
+ mode, sizeof(mode));
+
+ /* Change the mode */
+ channel->mode = mode_mask;
+ break;
+
+ case SILC_MODE_TYPE_UCHANNEL:
+ /* Get Channel ID */
+ tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
+ if (!tmp)
+ goto out;
+ channel_id = silc_id_payload_parse_id(tmp, tmp_len);
+ if (!channel_id)
+ goto out;
+
+ /* Get channel entry */
+ channel = silc_idlist_find_channel_by_id(server->local_list,
+ channel_id, NULL);
+ if (!channel) {
+ channel = silc_idlist_find_channel_by_id(server->global_list,
+ channel_id, NULL);
+ if (!channel)
+ goto out;
+ }
+
+ /* Get Client ID payload */
+ tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
+ if (!tmp)
+ goto out;
+
+ /* Get target Client ID */
+ tmp2 = silc_argument_get_arg_type(args, 3, &tmp_len2);
+ if (!tmp2)
+ goto out;
+ client_id = silc_id_payload_parse_id(tmp2, tmp_len2);
+ if (!client_id)
+ goto out;
+
+ /* Get target client entry */
+ client = silc_idlist_find_client_by_id(server->global_list,
+ client_id, NULL);
+ if (!client) {
+ client = silc_idlist_find_client_by_id(server->local_list,
+ client_id, NULL);
+ if (!client) {
+ silc_free(client_id);
+ goto out;
+ }
+ }
+ silc_free(client_id);
+
+ /* Send CUMODE_CHANGE notify to local channel */
+ silc_server_send_notify_to_channel(server, sock, channel, FALSE,
+ SILC_NOTIFY_TYPE_CUMODE_CHANGE, 2,
+ tmp, tmp_len,
+ mode, sizeof(mode),
+ tmp2, tmp_len2);
+
+ /* Get entry to the channel user list */
+ silc_list_start(channel->user_list);
+ while ((chl = silc_list_get(channel->user_list)) != SILC_LIST_END)
+ if (chl->client == client) {
+ /* Change the mode */
+ chl->mode = mode_mask;
+ break;
+ }
+
+ break;
+
+ default:
+ break;
+ }
+
+ out:
+ if (channel_id)
+ silc_free(channel_id);
+ if (args)
+ silc_argument_payload_free(args);
+ if (payload)
+ silc_set_mode_payload_free(payload);
+}