X-Git-Url: http://git.silcnet.org/gitweb/?p=silc.git;a=blobdiff_plain;f=lib%2Fsilcclient%2Fclient_notify.c;h=eb1f97edb9d95bcb1bae370c21cbeba5946468a0;hp=b5387ef345cc9b4befeb792eb3edce620bcf1491;hb=c257b555225193e54d85daf541d29578b3c93882;hpb=f658940d02cf2fd893296b6a7825b42502573668 diff --git a/lib/silcclient/client_notify.c b/lib/silcclient/client_notify.c index b5387ef3..eb1f97ed 100644 --- a/lib/silcclient/client_notify.c +++ b/lib/silcclient/client_notify.c @@ -4,7 +4,7 @@ Author: Pekka Riikonen - 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 @@ -444,12 +444,6 @@ void silc_client_notify_by_server(SilcClient client, 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) @@ -458,6 +452,12 @@ void silc_client_notify_by_server(SilcClient client, /* 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; @@ -556,6 +556,11 @@ void silc_client_notify_by_server(SilcClient client, 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. */ @@ -627,13 +632,20 @@ void silc_client_notify_by_server(SilcClient client, 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 */ @@ -839,6 +851,13 @@ void silc_client_notify_by_server(SilcClient client, 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) @@ -1118,26 +1137,29 @@ void silc_client_notify_by_server(SilcClient client, /* 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; @@ -1348,6 +1370,9 @@ void silc_client_notify_by_server(SilcClient client, */ SilcNotifyType notify = 0; bool del_client = FALSE; + unsigned char *pk; + SilcUInt32 pk_len; + SilcPublicKey public_key = NULL; SILC_LOG_DEBUG(("Notify: WATCH")); @@ -1393,15 +1418,25 @@ void silc_client_notify_by_server(SilcClient client, /* 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; @@ -1425,6 +1460,8 @@ void silc_client_notify_by_server(SilcClient client, silc_client_notify_del_client_cb, res, 1, 0, SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL); } + + silc_pkcs_public_key_free(public_key); } break;