updates.
[silc.git] / lib / silcclient / client_notify.c
index b4d4a78e8e166228f6c0b6e4f80f49099f3438cd..8b3663b979e5492162b6513cd7e84f13d349dd37 100644 (file)
@@ -41,6 +41,8 @@ static void silc_client_notify_by_server_pending(void *context, void *context2)
   SilcClientCommandReplyContext reply = 
     (SilcClientCommandReplyContext)context2;
 
+  SILC_LOG_DEBUG(("Start"));
+
   if (reply) {
     SilcCommandStatus status;
     unsigned char *tmp = silc_argument_get_arg_type(reply->args, 1, NULL);
@@ -78,7 +80,10 @@ static void silc_client_notify_by_server_resolve(SilcClient client,
   res->context = client;
   res->sock = silc_socket_dup(conn->sock);
 
-  silc_client_send_command(client, conn, SILC_COMMAND_WHOIS, ++conn->cmd_ident,
+  silc_client_command_register(client, SILC_COMMAND_WHOIS, NULL, NULL,
+                              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);
   silc_client_command_pending(conn, SILC_COMMAND_WHOIS, conn->cmd_ident,
                              silc_client_notify_by_server_destructor,
@@ -125,8 +130,8 @@ void silc_client_notify_by_server(SilcClient client,
   switch(type) {
   case SILC_NOTIFY_TYPE_NONE:
     /* Notify application */
-    client->ops->notify(client, conn, type, 
-                       silc_argument_get_arg_type(args, 1, NULL));
+    client->internal->ops->notify(client, conn, type, 
+                                 silc_argument_get_arg_type(args, 1, NULL));
     break;
 
   case SILC_NOTIFY_TYPE_INVITE:
@@ -174,7 +179,8 @@ void silc_client_notify_by_server(SilcClient client,
       goto out;
 
     /* Notify application */
-    client->ops->notify(client, conn, type, channel, tmp, client_entry);
+    client->internal->ops->notify(client, conn, type, channel, tmp, 
+                                 client_entry);
     break;
 
   case SILC_NOTIFY_TYPE_JOIN:
@@ -241,7 +247,7 @@ void silc_client_notify_by_server(SilcClient client,
     /* 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, channel);
+    client->internal->ops->notify(client, conn, type, client_entry, channel);
     break;
 
   case SILC_NOTIFY_TYPE_LEAVE:
@@ -291,7 +297,7 @@ void silc_client_notify_by_server(SilcClient client,
     /* 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, channel);
+    client->internal->ops->notify(client, conn, type, client_entry, channel);
     break;
 
   case SILC_NOTIFY_TYPE_SIGNOFF:
@@ -328,7 +334,7 @@ void silc_client_notify_by_server(SilcClient client,
       tmp = NULL;
 
     /* Notify application */
-    client->ops->notify(client, conn, type, client_entry, tmp);
+    client->internal->ops->notify(client, conn, type, client_entry, tmp);
 
     /* Free data */
     silc_client_del_client_entry(client, conn, client_entry);
@@ -418,8 +424,9 @@ void silc_client_notify_by_server(SilcClient client,
     /* 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, silc_id_payload_get_type(idp),
-                       client_entry, tmp, channel);
+    client->internal->ops->notify(client, conn, type, 
+                                 silc_id_payload_get_type(idp),
+                                 client_entry, tmp, channel);
 
     silc_id_payload_free(idp);
     break;
@@ -467,25 +474,37 @@ void silc_client_notify_by_server(SilcClient client,
     /* Find Client entry and if not found resolve it */
     client_entry2 = silc_client_get_client_by_id(client, conn, client_id);
     if (!client_entry2) {
+      /* Resolve the entry information */
       silc_client_notify_by_server_resolve(client, conn, packet, client_id);
-      goto out;
+
+      /* Add the new entry even though we resolved it. This is because we
+        want to replace the old entry with the new entry here right now. */
+      client_entry2 = 
+       silc_client_add_client(client, conn, NULL, NULL, NULL, 
+                              silc_id_dup(client_id, SILC_ID_CLIENT), 
+                              client_entry->mode);
+
+      /* Replace old ID entry with new one on all channels. */
+      silc_client_replace_from_channels(client, conn, client_entry,
+                                       client_entry2);
     } else {
       if (client_entry2 != conn->local_entry)
        silc_client_nickname_format(client, conn, client_entry2);
-    }
 
-    /* Remove the old from cache */
-    silc_idcache_del_by_context(conn->client_cache, client_entry);
+      /* Remove the old from cache */
+      silc_idcache_del_by_context(conn->client_cache, client_entry);
 
-    /* Replace old ID entry with new one on all channels. */
-    silc_client_replace_from_channels(client, conn, client_entry,
-                                     client_entry2);
+      /* Replace old ID entry with new one on all channels. */
+      silc_client_replace_from_channels(client, conn, client_entry,
+                                       client_entry2);
 
-    /* Notify application */
-    client->ops->notify(client, conn, type, client_entry, client_entry2);
+      /* Notify application */
+      client->internal->ops->notify(client, conn, type, 
+                                   client_entry, client_entry2);
 
-    /* Free data */
-    silc_client_del_client_entry(client, conn, client_entry);
+      /* Free data */
+      silc_client_del_client_entry(client, conn, client_entry);
+    }
     break;
 
   case SILC_NOTIFY_TYPE_CMODE_CHANGE:
@@ -584,8 +603,9 @@ void silc_client_notify_by_server(SilcClient client,
     /* 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, silc_id_payload_get_type(idp), 
-                       client_entry, mode, NULL, tmp, channel);
+    client->internal->ops->notify(client, conn, type, 
+                                 silc_id_payload_get_type(idp), 
+                                 client_entry, mode, NULL, tmp, channel);
 
     silc_id_payload_free(idp);
     break;
@@ -659,8 +679,9 @@ void silc_client_notify_by_server(SilcClient client,
     /* 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, mode, 
-                       client_entry2, channel);
+    client->internal->ops->notify(client, conn, type, 
+                                 client_entry, mode, 
+                                 client_entry2, channel);
     break;
 
   case SILC_NOTIFY_TYPE_MOTD:
@@ -676,7 +697,7 @@ void silc_client_notify_by_server(SilcClient client,
       goto out;
     
     /* Notify application */
-    client->ops->notify(client, conn, type, tmp);
+    client->internal->ops->notify(client, conn, type, tmp);
     break;
 
   case SILC_NOTIFY_TYPE_CHANNEL_CHANGE:
@@ -727,7 +748,7 @@ void silc_client_notify_by_server(SilcClient client,
                     channel->id, channel, 0, NULL);
 
     /* Notify application */
-    client->ops->notify(client, conn, type, channel, channel);
+    client->internal->ops->notify(client, conn, type, channel, channel);
     break;
 
   case SILC_NOTIFY_TYPE_KICKED:
@@ -787,8 +808,8 @@ void silc_client_notify_by_server(SilcClient client,
     /* 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, 
-                       client_entry2, channel);
+    client->internal->ops->notify(client, conn, type, client_entry, tmp, 
+                                 client_entry2, channel);
 
     /* If I was kicked from channel, remove the channel */
     if (client_entry == conn->local_entry) {
@@ -828,7 +849,7 @@ void silc_client_notify_by_server(SilcClient client,
     tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
 
     /* Notify application. */
-    client->ops->notify(client, conn, type, client_entry, tmp);
+    client->internal->ops->notify(client, conn, type, client_entry, tmp);
 
     if (client_entry != conn->local_entry) {
       /* Remove client from all channels */
@@ -874,7 +895,8 @@ void silc_client_notify_by_server(SilcClient client,
       /* Notify application. We don't keep server entries so the server
         entry is returned as NULL. The client's are returned as array
         of SilcClientEntry pointers. */
-      client->ops->notify(client, conn, type, NULL, clients, clients_count);
+      client->internal->ops->notify(client, conn, type, NULL, 
+                                   clients, clients_count);
 
       for (i = 0; i < clients_count; i++) {
        /* Remove client from all channels */