implemented KICK command
[silc.git] / lib / silcclient / client.c
index 928d4c188cf72c41b2e7f989c06a98bc11f1e6cd..8447ee3cc4ab91f0394ab67b1a720efa772641dd 100644 (file)
@@ -603,8 +603,7 @@ SILC_TASK_CALLBACK(silc_client_packet_process)
        return;
       }
       
-      client->ops->say(client, conn, "Connection closed: premature EOF");
-      SILC_LOG_DEBUG(("Premature EOF from connection %d", sock->sock));
+      SILC_LOG_DEBUG(("EOF from connection %d", sock->sock));
       client->ops->disconnect(client, conn);
       silc_client_close_connection(client, sock);
       return;
@@ -917,7 +916,6 @@ void silc_client_packet_send(SilcClient client,
     packetdata.dst_id_len = 0;
     packetdata.dst_id_type = SILC_ID_NONE;
   }
-  packetdata.rng = client->rng;
   packetdata.truelen = data_len + SILC_PACKET_HEADER_LEN + 
     packetdata.src_id_len + packetdata.dst_id_len;
   packetdata.padlen = SILC_PACKET_PADLEN(packetdata.truelen);
@@ -1014,7 +1012,6 @@ void silc_client_packet_send_to_channel(SilcClient client,
   packetdata.dst_id = id_string;
   packetdata.dst_id_len = SILC_ID_CHANNEL_LEN;
   packetdata.dst_id_type = SILC_ID_CHANNEL;
-  packetdata.rng = client->rng;
   packetdata.truelen = payload->len + SILC_PACKET_HEADER_LEN + 
     packetdata.src_id_len + packetdata.dst_id_len;
   packetdata.padlen = SILC_PACKET_PADLEN((SILC_PACKET_HEADER_LEN +
@@ -1121,7 +1118,6 @@ void silc_client_packet_send_private_message(SilcClient client,
     packetdata.dst_id = conn->local_id_data;
   packetdata.dst_id_len = SILC_ID_CLIENT_LEN;
   packetdata.dst_id_type = SILC_ID_CLIENT;
-  packetdata.rng = client->rng;
   packetdata.truelen = buffer->len + SILC_PACKET_HEADER_LEN + 
     packetdata.src_id_len + packetdata.dst_id_len;
   packetdata.padlen = SILC_PACKET_PADLEN((SILC_PACKET_HEADER_LEN +
@@ -1426,11 +1422,16 @@ void silc_client_notify_by_server(SilcClient client,
       goto out;
     }
 
-    /* Get channel entry */
-    channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
-                               SILC_ID_CHANNEL);
+    /* Get Channel ID */
+    tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
+    if (!tmp)
+      goto out;
+
+    channel_id = silc_id_payload_parse_id(tmp, tmp_len);
     if (!channel_id)
       goto out;
+
+    /* Get channel entry */
     if (!silc_idcache_find_by_id_one(conn->channel_cache, (void *)channel_id,
                                     SILC_ID_CHANNEL, &id_cache))
       break;
@@ -1526,8 +1527,13 @@ void silc_client_notify_by_server(SilcClient client,
     silc_idcache_del_by_id(conn->client_cache, SILC_ID_CLIENT, 
                           client_entry->id);
 
+    /* Get signoff message */
+    tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
+    if (tmp_len > 128)
+      tmp = NULL;
+
     /* Notify application */
-    client->ops->notify(client, conn, type, client_entry);
+    client->ops->notify(client, conn, type, client_entry, tmp);
 
     /* Free data */
     if (client_entry->nickname)
@@ -1822,6 +1828,59 @@ void silc_client_notify_by_server(SilcClient client,
     /* Notify application */
     client->ops->notify(client, conn, type, channel, channel);
     break;
+
+  case SILC_NOTIFY_TYPE_KICKED:
+    /*
+     * A client (maybe me) was kicked from a channel
+     */
+
+    /* Get Client ID */
+    tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
+    if (!tmp)
+      goto out;
+
+    client_id = silc_id_payload_parse_id(tmp, tmp_len);
+    if (!client_id)
+      goto out;
+
+    /* Find Client entry */
+    client_entry = 
+      silc_idlist_get_client_by_id(client, conn, client_id);
+    if (!client_entry)
+      goto out;
+
+    /* Get channel entry */
+    channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
+                               SILC_ID_CHANNEL);
+    if (!channel_id)
+      goto out;
+    if (!silc_idcache_find_by_id_one(conn->channel_cache, (void *)channel_id,
+                                    SILC_ID_CHANNEL, &id_cache))
+      break;
+
+    channel = (SilcChannelEntry)id_cache->context;
+
+    /* Get comment */
+    tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
+
+    /* 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->ops->notify(client, conn, type, client_entry, tmp, channel);
+
+    /* If I was kicked from channel, remove the channel */
+    if (client_entry == conn->local_entry) {
+      if (conn->current_channel == channel)
+       conn->current_channel = NULL;
+      silc_idcache_del_by_id(conn->channel_cache, 
+                            SILC_ID_CHANNEL, channel->id);
+      silc_free(channel->channel_name);
+      silc_free(channel->id);
+      silc_free(channel->key);
+      silc_cipher_free(channel->channel_key);
+      silc_free(channel);
+    }
+    break;
     
   default:
     break;