updates.
[silc.git] / lib / silcclient / command_reply.c
index 228dce57f1cddb43724a392b7a504b73e4b009e4..f775d60c6fdbb82513df57edf38751e8b6298d4b 100644 (file)
@@ -239,6 +239,8 @@ silc_client_command_reply_whois_save(SilcClientCommandReplyContext cmd,
   char *realname = NULL;
   uint32 idle = 0, mode = 0;
   SilcBuffer channels = NULL;
+  unsigned char *fingerprint;
+  uint32 fingerprint_len;
   
   argc = silc_argument_get_arg_num(cmd->args);
 
@@ -277,6 +279,8 @@ silc_client_command_reply_whois_save(SilcClientCommandReplyContext cmd,
   if (tmp)
     SILC_GET32_MSB(idle, tmp);
 
+  fingerprint = silc_argument_get_arg_type(cmd->args, 9, &fingerprint_len);
+
   /* Check if we have this client cached already. */
   if (!silc_idcache_find_by_id_one_ext(conn->client_cache, (void *)client_id, 
                                       NULL, NULL, 
@@ -293,10 +297,21 @@ silc_client_command_reply_whois_save(SilcClientCommandReplyContext cmd,
     silc_free(client_id);
   }
 
+  if (fingerprint && !client_entry->fingerprint) {
+    client_entry->fingerprint = 
+      silc_calloc(fingerprint_len, 
+                 sizeof(*client_entry->fingerprint));
+    memcpy(client_entry->fingerprint, fingerprint, fingerprint_len);
+    client_entry->fingerprint_len = fingerprint_len;
+  }
+
+  if (client_entry->status & SILC_CLIENT_STATUS_RESOLVING)
+    client_entry->status &= ~SILC_CLIENT_STATUS_RESOLVING;
+
   /* Notify application */
   if (!cmd->callback)
     COMMAND_REPLY((ARGS, client_entry, nickname, username, realname, 
-                  channels, mode, idle));
+                  channels, mode, idle, fingerprint));
 
   if (channels)
     silc_buffer_free(channels);
@@ -386,8 +401,8 @@ SILC_CLIENT_CMD_REPLY_FUNC(whowas)
   }
 
  out:
-  SILC_CLIENT_PENDING_EXEC(cmd, SILC_COMMAND_WHOIS);
-  SILC_CLIENT_PENDING_DESTRUCTOR(cmd, SILC_COMMAND_WHOIS);
+  SILC_CLIENT_PENDING_EXEC(cmd, SILC_COMMAND_WHOWAS);
+  SILC_CLIENT_PENDING_DESTRUCTOR(cmd, SILC_COMMAND_WHOWAS);
   silc_client_command_reply_free(cmd);
 }
 
@@ -451,6 +466,9 @@ silc_client_command_reply_identify_save(SilcClientCommandReplyContext cmd,
                                name, info, NULL, 0);
     }
 
+    if (client_entry->status & SILC_CLIENT_STATUS_RESOLVING)
+      client_entry->status &= ~SILC_CLIENT_STATUS_RESOLVING;
+
     /* Notify application */
     COMMAND_REPLY((ARGS, client_entry, name, info));
     break;
@@ -580,7 +598,11 @@ SILC_CLIENT_CMD_REPLY_FUNC(nick)
   silc_client_receive_new_id(cmd->client, cmd->sock, idp);
     
   /* Notify application */
+  SILC_CLIENT_PENDING_EXEC(cmd, SILC_COMMAND_NICK);
   COMMAND_REPLY((ARGS, conn->local_entry));
+  SILC_CLIENT_PENDING_DESTRUCTOR(cmd, SILC_COMMAND_NICK);
+  silc_client_command_reply_free(cmd);
+  return;
 
  out:
   SILC_CLIENT_PENDING_EXEC(cmd, SILC_COMMAND_NICK);
@@ -816,6 +838,9 @@ SILC_CLIENT_CMD_REPLY_FUNC(info)
     /* Add it to the cache */
     silc_idcache_add(conn->server_cache, server->server_name,
                     server->server_id, (void *)server, FALSE);
+
+    if (SILC_ID_SERVER_COMPARE(server_id, conn->remote_id))
+      goto out;
   } else {
     server = (SilcServerEntry)id_cache->context;
   }
@@ -852,12 +877,14 @@ SILC_CLIENT_CMD_REPLY_FUNC(ping)
   curtime = time(NULL);
   id = silc_id_str2id(cmd->packet->src_id, cmd->packet->src_id_len,
                      cmd->packet->src_id_type);
-  if (!id) {
+  if (!id || !conn->ping) {
     COMMAND_REPLY_ERROR;
     goto out;
   }
 
   for (i = 0; i < conn->ping_count; i++) {
+    if (!conn->ping[i].dest_id)
+      continue;
     if (SILC_ID_SERVER_COMPARE(conn->ping[i].dest_id, id)) {
       diff = curtime - conn->ping[i].start_time;
       cmd->client->ops->say(cmd->client, conn, SILC_CLIENT_MESSAGE_INFO, 
@@ -963,6 +990,11 @@ SILC_CLIENT_CMD_REPLY_FUNC(join)
   /* Get topic */
   topic = silc_argument_get_arg_type(cmd->args, 10, NULL);
 
+  /* If we have the channel entry, remove it and create a new one */
+  channel = silc_client_get_channel(cmd->client, conn, channel_name);
+  if (channel)
+    silc_client_del_channel(cmd->client, conn, channel);
+
   /* Save received Channel ID. This actually creates the channel */
   channel = silc_client_new_channel_id(cmd->client, cmd->sock, channel_name, 
                                       mode, idp);
@@ -1256,7 +1288,7 @@ SILC_CLIENT_CMD_REPLY_FUNC(cumode)
   SilcClientEntry client_entry;
   SilcChannelEntry channel;
   SilcChannelUser chu;
-  unsigned char *tmp, *id;
+  unsigned char *modev, *tmp, *id;
   uint32 len, mode;
   
   SILC_GET16_MSB(status, silc_argument_get_arg_type(cmd->args, 1, NULL));
@@ -1268,8 +1300,8 @@ SILC_CLIENT_CMD_REPLY_FUNC(cumode)
   }
   
   /* Get channel mode */
-  tmp = silc_argument_get_arg_type(cmd->args, 2, NULL);
-  if (!tmp) {
+  modev = silc_argument_get_arg_type(cmd->args, 2, NULL);
+  if (!modev) {
     COMMAND_REPLY_ERROR;
     goto out;
   }
@@ -1320,7 +1352,8 @@ SILC_CLIENT_CMD_REPLY_FUNC(cumode)
   client_entry = (SilcClientEntry)id_cache->context;
 
   /* Save the mode */
-  SILC_GET32_MSB(mode, tmp);
+  SILC_GET32_MSB(mode, modev);
+  silc_list_start(channel->clients);
   while ((chu = silc_list_get(channel->clients)) != SILC_LIST_END) {
     if (chu->client == client_entry) {
       chu->mode = mode;
@@ -1690,6 +1723,18 @@ SILC_CLIENT_CMD_REPLY_FUNC(users)
 
     if (!id_cache || !((SilcClientEntry)id_cache->context)->username ||
        !((SilcClientEntry)id_cache->context)->realname) {
+
+      if (id_cache && id_cache->context) {
+       SilcClientEntry client_entry = (SilcClientEntry)id_cache->context;
+       if (client_entry->status & SILC_CLIENT_STATUS_RESOLVING) {
+         client_entry->status &= ~SILC_CLIENT_STATUS_RESOLVING;
+         silc_buffer_pull(client_id_list, idp_len);
+         silc_buffer_pull(client_mode_list, 4);
+         continue;
+       }
+       client_entry->status |= SILC_CLIENT_STATUS_RESOLVING;
+      }
+
       /* No we don't have it (or it is incomplete in information), query
         it from the server. Assemble argument table that will be sent
         for the WHOIS command later. */