Added connection authentication request support.
[silc.git] / lib / silcclient / client_channel.c
index 34d51c64881a98940bf474ed3f466030c7396e09..e7753b9400e8c99fec30b2043739ea3bd89c9c49 100644 (file)
@@ -4,7 +4,7 @@
 
   Author: Pekka Riikonen <priikone@silcnet.org>
 
-  Copyright (C) 1997 - 2004, 2006 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
@@ -166,7 +166,7 @@ SILC_FSM_STATE(silc_client_channel_message)
   if (silc_unlikely(packet->dst_id_type != SILC_ID_CHANNEL)) {
     /** Invalid packet */
     silc_fsm_next(fsm, silc_client_channel_message_error);
-    return SILC_FSM_CONTINUE;
+    SILC_FSM_CONTINUE;
   }
 
   if (silc_unlikely(!silc_id_str2id(packet->src_id,
@@ -174,7 +174,7 @@ SILC_FSM_STATE(silc_client_channel_message)
                                    &remote_id, sizeof(remote_id)))) {
     /** Invalid source ID */
     silc_fsm_next(fsm, silc_client_channel_message_error);
-    return SILC_FSM_CONTINUE;
+    SILC_FSM_CONTINUE;
   }
 
   /* Get sender client entry */
@@ -194,7 +194,7 @@ SILC_FSM_STATE(silc_client_channel_message)
                                    sizeof(channel_id)))) {
     /** Invalid destination ID */
     silc_fsm_next(fsm, silc_client_channel_message_error);
-    return SILC_FSM_CONTINUE;
+    SILC_FSM_CONTINUE;
   }
 
   /* Find the channel */
@@ -202,7 +202,7 @@ SILC_FSM_STATE(silc_client_channel_message)
   if (silc_unlikely(!channel)) {
     /** Unknown channel */
     silc_fsm_next(fsm, silc_client_channel_message_error);
-    return SILC_FSM_CONTINUE;
+    SILC_FSM_CONTINUE;
   }
 
   /* Check that user is on channel */
@@ -211,7 +211,7 @@ SILC_FSM_STATE(silc_client_channel_message)
     SILC_LOG_WARNING(("Message from user not on channel, client or "
                      "server bug"));
     silc_fsm_next(fsm, silc_client_channel_message_error);
-    return SILC_FSM_CONTINUE;
+    SILC_FSM_CONTINUE;
   }
 
   /* If there is no channel private key then just decrypt the message
@@ -295,7 +295,7 @@ SILC_FSM_STATE(silc_client_channel_message)
   silc_client_unref_channel(client, conn, channel);
   if (payload)
     silc_message_payload_free(payload);
-  return SILC_FSM_FINISH;
+  SILC_FSM_FINISH;
 }
 
 /* Channel message error. */
@@ -304,7 +304,7 @@ SILC_FSM_STATE(silc_client_channel_message_error)
 {
   SilcPacket packet = state_context;
   silc_packet_free(packet);
-  return SILC_FSM_FINISH;
+  SILC_FSM_FINISH;
 }
 
 /******************************* Channel Key ********************************/
@@ -455,7 +455,7 @@ SILC_FSM_STATE(silc_client_channel_key)
   silc_client_save_channel_key(client, conn, &packet->buffer, NULL);
   silc_packet_free(packet);
 
-  return SILC_FSM_FINISH;
+  SILC_FSM_FINISH;
 }
 
 /**************************** Channel Private Key ***************************/
@@ -701,6 +701,8 @@ SilcBool silc_client_add_to_channel(SilcClient client,
   if (silc_client_on_channel(channel, client_entry))
     return TRUE;
 
+  SILC_LOG_DEBUG(("Add client %s to channel", client_entry->nickname));
+
   chu = silc_calloc(1, sizeof(*chu));
   if (!chu)
     return FALSE;
@@ -731,10 +733,16 @@ SilcBool silc_client_remove_from_channel(SilcClient client,
   if (!chu)
     return FALSE;
 
+  SILC_LOG_DEBUG(("Remove client %s from channel", client_entry->nickname));
+
   silc_hash_table_del(chu->client->channels, chu->channel);
   silc_hash_table_del(chu->channel->user_list, chu->client);
   silc_free(chu);
 
+  /* If channel became empty, delete it */
+  if (!silc_hash_table_count(channel->user_list))
+    silc_client_del_channel(client, conn, channel);
+
   silc_client_unref_client(client, conn, client_entry);
   silc_client_unref_channel(client, conn, channel);
 
@@ -750,10 +758,20 @@ void silc_client_remove_from_channels(SilcClient client,
   SilcHashTableList htl;
   SilcChannelUser chu;
 
+  if (!silc_hash_table_count(client_entry->channels))
+    return;
+
+  SILC_LOG_DEBUG(("Remove client from all joined channels"));
+
   silc_hash_table_list(client_entry->channels, &htl);
   while (silc_hash_table_get(&htl, NULL, (void *)&chu)) {
     silc_hash_table_del(chu->client->channels, chu->channel);
     silc_hash_table_del(chu->channel->user_list, chu->client);
+
+    /* If channel became empty, delete it */
+    if (!silc_hash_table_count(chu->channel->user_list))
+      silc_client_del_channel(client, conn, chu->channel);
+
     silc_client_unref_client(client, conn, chu->client);
     silc_client_unref_channel(client, conn, chu->channel);
     silc_free(chu);