- if (channel_entry) {
- SILC_LOG_DEBUG(("Channel %p refcnt %d->%d", channel_entry,
- silc_atomic_get_int16(&channel_entry->internal.refcnt),
- silc_atomic_get_int16(&channel_entry->internal.refcnt)
- - 1));
- silc_client_del_channel(client, conn, channel_entry);
+ SilcIDCacheEntry id_cache;
+ SilcBool ret = TRUE;
+ SilcCipher key;
+ SilcHmac hmac;
+ char *namec;
+
+ if (!channel_entry)
+ return;
+
+ SILC_LOG_DEBUG(("Channel %p refcnt %d->%d", channel_entry,
+ silc_atomic_get_int32(&channel_entry->internal.refcnt),
+ silc_atomic_get_int32(&channel_entry->internal.refcnt)
+ - 1));
+
+ if (silc_atomic_sub_int32(&channel_entry->internal.refcnt, 1) > 0)
+ return;
+
+ SILC_LOG_DEBUG(("Deleting channel %p", channel_entry));
+
+ silc_mutex_lock(conn->internal->lock);
+ if (silc_idcache_find_by_context(conn->internal->channel_cache, channel_entry,
+ &id_cache)) {
+ namec = id_cache->name;
+ ret = silc_idcache_del_by_context(conn->internal->channel_cache,
+ channel_entry, NULL);
+ silc_free(namec);
+ }
+ silc_mutex_unlock(conn->internal->lock);
+
+ if (!ret)
+ return;
+
+ silc_client_empty_channel(client, conn, channel_entry);
+ silc_client_del_channel_private_keys(client, conn, channel_entry);
+ silc_hash_table_free(channel_entry->user_list);
+ silc_free(channel_entry->channel_name);
+ silc_free(channel_entry->topic);
+ if (channel_entry->founder_key)
+ silc_pkcs_public_key_free(channel_entry->founder_key);
+ if (channel_entry->internal.send_key)
+ silc_cipher_free(channel_entry->internal.send_key);
+ if (channel_entry->internal.receive_key)
+ silc_cipher_free(channel_entry->internal.receive_key);
+ if (channel_entry->internal.hmac)
+ silc_hmac_free(channel_entry->internal.hmac);
+ if (channel_entry->internal.old_channel_keys) {
+ silc_dlist_start(channel_entry->internal.old_channel_keys);
+ while ((key = silc_dlist_get(channel_entry->internal.old_channel_keys)))
+ silc_cipher_free(key);
+ silc_dlist_uninit(channel_entry->internal.old_channel_keys);
+ }
+ if (channel_entry->internal.old_hmacs) {
+ silc_dlist_start(channel_entry->internal.old_hmacs);
+ while ((hmac = silc_dlist_get(channel_entry->internal.old_hmacs)))
+ silc_hmac_free(hmac);
+ silc_dlist_uninit(channel_entry->internal.old_hmacs);