updates.
[silc.git] / lib / silcclient / client_notify.c
index 9b825954f2deb2f9618be991fc39f478a84eaa33..64ad2658cfead157f2ecfb3dd774e8f14d0ceeca 100644 (file)
@@ -35,11 +35,12 @@ typedef struct {
 SILC_TASK_CALLBACK(silc_client_notify_check_client)
 { 
   SilcClientNotifyResolve res = (SilcClientNotifyResolve)context;
-  SilcClientConnection conn = res->context;
-  SilcClient client = conn->client;
+  SilcClient client = res->context;
+  SilcClientConnection conn = res->sock->user_data;
   SilcClientID *client_id = res->packet;
   silc_client_get_client_by_id_resolve(client, conn, client_id, NULL, NULL);
   silc_free(client_id);
+  silc_socket_free(res->sock);
   silc_free(res);
 }
 
@@ -87,7 +88,7 @@ static void silc_client_notify_by_server_resolve(SilcClient client,
                                 silc_client_command_reply_whois_i, 0,
                                 ++conn->cmd_ident);
     silc_client_command_send(client, conn, SILC_COMMAND_WHOIS, conn->cmd_ident,
-                            1, 3, idp->data, idp->len);
+                            1, 4, idp->data, idp->len);
     silc_client_command_pending(conn, SILC_COMMAND_WHOIS, conn->cmd_ident,
                                silc_client_notify_by_server_pending, res);
   } else {
@@ -308,10 +309,11 @@ void silc_client_notify_by_server(SilcClient client,
        that we'll remove the client from cache. */
     if (!silc_hash_table_count(client_entry->channels)) {
       SilcClientNotifyResolve res = silc_calloc(1, sizeof(*res));
-      res->context = conn;
+      res->context = client;
+      res->sock = silc_socket_dup(conn->sock);
       res->packet = silc_id_dup(client_id, SILC_ID_CLIENT);
-      silc_schedule_task_add(client->schedule, 0,
-                            silc_client_notify_check_client, conn,
+      silc_schedule_task_add(client->schedule, conn->sock->sock,
+                            silc_client_notify_check_client, res,
                             (5 + (silc_rng_get_rn16(client->rng) % 29)),
                             0, SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
     }
@@ -739,8 +741,11 @@ void silc_client_notify_by_server(SilcClient client,
     /* Find target Client entry */
     client_entry2 = 
       silc_client_get_client_by_id(client, conn, client_id);
-    if (!client_entry2)
+    if (!client_entry2) {
+      silc_client_notify_by_server_resolve(client, conn, packet, 
+                                          SILC_ID_CLIENT, client_id);
       goto out;
+    }
 
     /* Get channel entry */
     channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
@@ -812,7 +817,8 @@ void silc_client_notify_by_server(SilcClient client,
       goto out;
 
     /* Replace the Channel ID */
-    silc_client_replace_channel_id(client, conn, channel, channel_id);
+    if (silc_client_replace_channel_id(client, conn, channel, channel_id))
+      channel_id = NULL;
 
     /* Notify application */
     client->internal->ops->notify(client, conn, type, channel, channel);
@@ -890,6 +896,17 @@ void silc_client_notify_by_server(SilcClient client,
        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;
+       res->sock = silc_socket_dup(conn->sock);
+       res->packet = silc_id_dup(client_entry->id, SILC_ID_CLIENT);
+       silc_schedule_task_add(client->schedule, conn->sock->sock,
+                              silc_client_notify_check_client, res,
+                              (5 + (silc_rng_get_rn16(client->rng) % 529)),
+                              0, SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
+      }
     }
     break;
 
@@ -1131,6 +1148,10 @@ void silc_client_notify_by_server(SilcClient client,
       if (tmp && notify == SILC_NOTIFY_TYPE_NICK_CHANGE &&
          !silc_hash_table_count(client_entry->channels))
        silc_client_del_client(client, conn, client_entry);
+      else if (notify == SILC_NOTIFY_TYPE_SIGNOFF ||
+              notify == SILC_NOTIFY_TYPE_SERVER_SIGNOFF ||
+              notify == SILC_NOTIFY_TYPE_KILLED)
+       silc_client_del_client(client, conn, client_entry);
     }
     break;