Author: Pekka Riikonen <priikone@silcnet.org>
- Copyright (C) 1997 - 2003 Pekka Riikonen
+ Copyright (C) 1997 - 2005 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
important packets sent by the server. They tell different things to the
client such as nick changes, mode changes etc. */
-#include "silcincludes.h"
+#include "silc.h"
#include "silcclient.h"
#include "client_internal.h"
if (!client_entry)
goto out;
- /* Remove from all channels */
- silc_client_remove_from_channels(client, conn, client_entry);
-
- /* Remove from cache */
- silc_idcache_del_by_context(conn->internal->client_cache, client_entry);
-
/* Get signoff message */
tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
if (tmp_len > 128)
/* Notify application */
client->internal->ops->notify(client, conn, type, client_entry, tmp);
+ /* Remove from all channels */
+ silc_client_remove_from_channels(client, conn, client_entry);
+
+ /* Remove from cache */
+ silc_idcache_del_by_context(conn->internal->client_cache, client_entry);
+
/* Free data */
silc_client_del_client_entry(client, conn, client_entry);
break;
goto out;
}
+ if (tmp) {
+ silc_free(channel->topic);
+ channel->topic = silc_memdup(tmp, strlen(tmp));
+ }
+
/* Notify application. The channel entry is sent last as this notify
is for channel but application don't know it from the arguments
sent by server. */
ID changes. Check whether the hashes in the Client ID match, if
they do nickname didn't change. */
if (SILC_ID_COMPARE_HASH(client_entry->id, client_id) &&
- !strcmp(tmp, client_entry->nickname)) {
+ silc_utf8_strcasecmp(tmp, client_entry->nickname)) {
/* Nickname didn't change. Update only Client ID. */
+
+ /* Normalize nickname */
+ tmp = silc_identifier_check(tmp, strlen(tmp),
+ SILC_STRING_UTF8, 128, NULL);
+ if (!tmp)
+ goto out;
+
silc_idcache_del_by_context(conn->internal->client_cache,
client_entry);
silc_free(client_entry->id);
client_entry->id = silc_id_dup(client_id, SILC_ID_CLIENT);
- silc_idcache_add(conn->internal->client_cache, strdup(tmp),
+ silc_idcache_add(conn->internal->client_cache, tmp,
client_entry->id, client_entry, 0, NULL);
/* Notify application */
/* Get the hmac */
hmac = silc_argument_get_arg_type(args, 4, &tmp_len);
if (hmac) {
- unsigned char hash[32];
+ unsigned char hash[SILC_HASH_MAXLEN];
if (channel->hmac)
silc_hmac_free(channel->hmac);
founder_key = NULL;
}
+ /* Get user limit */
+ tmp = silc_argument_get_arg_type(args, 8, &tmp_len);
+ if (tmp && tmp_len == 4)
+ SILC_GET32_MSB(channel->user_limit, tmp);
+ if (!(channel->mode & SILC_CHANNEL_MODE_ULIMIT))
+ channel->user_limit = 0;
+
/* Get the channel public key that was added or removed */
tmp = silc_argument_get_arg_type(args, 7, &tmp_len);
if (tmp)
/* Get comment */
tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
+ /* Remove kicked client from channel */
+ if (client_entry != conn->local_entry) {
+ chu = silc_client_on_channel(channel, client_entry);
+ if (chu) {
+ silc_hash_table_del(client_entry->channels, channel);
+ silc_hash_table_del(channel->user_list, client_entry);
+ silc_free(chu);
+ }
+ }
+
/* Notify application. The channel entry is sent last as this notify
is for channel but application don't know it from the arguments
sent by server. */
client->internal->ops->notify(client, conn, type, client_entry, tmp,
client_entry2, channel);
- /* Remove kicked client from channel */
+ /* Remove kicked client (us) from channel */
if (client_entry == conn->local_entry) {
/* If I was kicked from channel, remove the channel */
if (conn->current_channel == channel)
conn->current_channel = NULL;
silc_client_del_channel(client, conn, channel);
} else {
- chu = silc_client_on_channel(channel, client_entry);
- if (chu) {
- silc_hash_table_del(client_entry->channels, channel);
- silc_hash_table_del(channel->user_list, client_entry);
- silc_free(chu);
- }
-
if (!silc_hash_table_count(client_entry->channels)) {
SilcClientNotifyResolve res = silc_calloc(1, sizeof(*res));
res->context = client;
* Received notify about some client we are watching
*/
SilcNotifyType notify = 0;
- bool del_client = FALSE;
+ SilcBool del_client = FALSE;
+ unsigned char *pk;
+ SilcUInt32 pk_len;
+ SilcPublicKey public_key = NULL;
SILC_LOG_DEBUG(("Notify: WATCH"));
/* If same nick, the client was new to us and has become "present"
to network. Send NULL as nick to application. */
- if (tmp_nick && !strcmp(tmp, tmp_nick))
+ if (tmp_nick && silc_utf8_strcasecmp(tmp, tmp_nick))
tmp = NULL;
silc_free(tmp_nick);
}
+ /* Get public key, if present */
+ pk = silc_argument_get_arg_type(args, 5, &pk_len);
+ if (pk && !client_entry->public_key) {
+ if (silc_pkcs_public_key_payload_decode(pk, pk_len, &public_key)) {
+ client_entry->public_key = public_key;
+ public_key = NULL;
+ }
+ }
+
/* Notify application. */
client->internal->ops->notify(client, conn, type, client_entry,
- tmp, mode, notify);
+ tmp, mode, notify,
+ client_entry->public_key);
client_entry->mode = mode;
silc_client_notify_del_client_cb, res,
1, 0, SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
}
+
+ silc_pkcs_public_key_free(public_key);
}
break;