updates.
[silc.git] / lib / silcclient / idlist.c
index e361a5027c39226a6357ddc12873c97abe9790b4..2d5a8c0cdb8f2fc780605d6252cdbc32b5a828e1 100644 (file)
@@ -308,7 +308,7 @@ SILC_CLIENT_CMD_FUNC(get_clients_list_callback)
     /* Get Client ID */
     SILC_GET16_MSB(idp_len, client_id_list->data + 2);
     idp_len += 4;
-    client_id = silc_id_payload_parse_id(client_id_list->data, idp_len);
+    client_id = silc_id_payload_parse_id(client_id_list->data, idp_len, NULL);
     if (!client_id) {
       silc_buffer_pull(client_id_list, idp_len);
       continue;
@@ -362,6 +362,7 @@ void silc_client_get_clients_by_list(SilcClient client,
   unsigned char **res_argv = NULL;
   SilcUInt32 *res_argv_lens = NULL, *res_argv_types = NULL, res_argc = 0;
   GetClientsByListInternal in;
+  bool wait_res = FALSE;
 
   SILC_LOG_DEBUG(("Start"));
 
@@ -377,37 +378,46 @@ void silc_client_get_clients_by_list(SilcClient client,
     SilcUInt16 idp_len;
     SilcClientID *client_id;
     SilcClientEntry entry;
+    bool ret;
 
     /* Get Client ID */
     SILC_GET16_MSB(idp_len, client_id_list->data + 2);
     idp_len += 4;
-    client_id = silc_id_payload_parse_id(client_id_list->data, idp_len);
+    client_id = silc_id_payload_parse_id(client_id_list->data, idp_len, NULL);
     if (!client_id) {
       silc_buffer_pull(client_id_list, idp_len);
       continue;
     }
 
     /* Check if we have this client cached already. */
-    id_cache = NULL;
-    silc_idcache_find_by_id_one_ext(conn->client_cache, (void *)client_id, 
-                                   NULL, NULL, 
-                                   silc_hash_client_id_compare, NULL,
-                                   &id_cache);
+    ret =
+      silc_idcache_find_by_id_one_ext(conn->client_cache, (void *)client_id, 
+                                     NULL, NULL, 
+                                     silc_hash_client_id_compare, NULL,
+                                     &id_cache);
 
     /* If we don't have the entry or it has incomplete info, then resolve
        it from the server. */
-    entry = id_cache ? (SilcClientEntry)id_cache->context : NULL;
-    if (!id_cache || !entry->nickname) {
+    if (!ret || !((SilcClientEntry)id_cache->context)->nickname) {
+      entry = ret ? (SilcClientEntry)id_cache->context : NULL;
 
       if (entry) {
        if (entry->status & SILC_CLIENT_STATUS_RESOLVING) {
-         entry->status &= ~SILC_CLIENT_STATUS_RESOLVING;
+         /* Attach to this resolving and wait until it finishes */
+         silc_client_command_pending(
+                           conn, SILC_COMMAND_NONE, 
+                           entry->resolve_cmd_ident,
+                           silc_client_command_get_clients_list_callback, 
+                           (void *)in);
+         wait_res = TRUE;
+
          silc_free(client_id);
          silc_buffer_pull(client_id_list, idp_len);
          continue;
        }
 
        entry->status |= SILC_CLIENT_STATUS_RESOLVING;
+       entry->resolve_cmd_ident = conn->cmd_ident + 1;
       }
 
       /* No we don't have it, query it from the server. Assemble argument
@@ -428,6 +438,9 @@ void silc_client_get_clients_by_list(SilcClient client,
     silc_buffer_pull(client_id_list, idp_len);
   }
 
+  silc_buffer_push(client_id_list, client_id_list->data - 
+                  client_id_list->head);
+
   /* Query the client information from server if the list included clients
      that we don't know about. */
   if (res_argc) {
@@ -451,8 +464,6 @@ void silc_client_get_clients_by_list(SilcClient client,
                                silc_client_command_get_clients_list_callback, 
                                (void *)in);
 
-    silc_buffer_push(client_id_list, client_id_list->data - 
-                    client_id_list->head);
     silc_buffer_free(res_cmd);
     silc_free(res_argv);
     silc_free(res_argv_lens);
@@ -460,8 +471,8 @@ void silc_client_get_clients_by_list(SilcClient client,
     return;
   }
 
-  silc_buffer_push(client_id_list, client_id_list->data - 
-                  client_id_list->head);
+  if (wait_res)
+    return;
 
   /* We have the clients in cache, get them and call the completion */
   silc_client_command_get_clients_list_callback((void *)in, NULL);
@@ -506,10 +517,13 @@ SILC_CLIENT_CMD_FUNC(get_client_by_id_callback)
 
   /* Get the client */
   entry = silc_client_get_client_by_id(i->client, i->conn, i->client_id);
-  if (entry)
-    i->completion(i->client, i->conn, &entry, 1, i->context);
-  else
-    i->completion(i->client, i->conn, NULL, 0, i->context);
+  if (entry) {
+    if (i->completion)
+      i->completion(i->client, i->conn, &entry, 1, i->context);
+  } else {
+    if (i->completion)
+      i->completion(i->client, i->conn, NULL, 0, i->context);
+  }
 
   silc_free(i->client_id);
   silc_free(i);
@@ -941,6 +955,39 @@ SilcServerEntry silc_client_get_server_by_id(SilcClient client,
   return entry;
 }
 
+/* Add new server entry */
+
+SilcServerEntry silc_client_add_server(SilcClient client,
+                                      SilcClientConnection conn,
+                                      const char *server_name,
+                                      const char *server_info,
+                                      SilcServerID *server_id)
+{
+  SilcServerEntry server_entry;
+
+  server_entry = silc_calloc(1, sizeof(*server_entry));
+  if (!server_entry || !server_id)
+    return NULL;
+
+  server_entry->server_id = server_id;
+  if (server_name)
+    server_entry->server_name = strdup(server_name);
+  if (server_info)
+    server_entry->server_info = strdup(server_info);
+
+  /* Add server to cache */
+  if (!silc_idcache_add(conn->server_cache, server_entry->server_name,
+                       server_entry->server_id, server_entry, 0, NULL)) {
+    silc_free(server_entry->server_id);
+    silc_free(server_entry->server_name);
+    silc_free(server_entry->server_info);
+    silc_free(server_entry);
+    return NULL;
+  }
+
+  return server_entry;
+}
+
 /* Removes server from the cache by the server entry. */
 
 bool silc_client_del_server(SilcClient client, SilcClientConnection conn,
@@ -966,6 +1013,7 @@ void silc_client_nickname_format(SilcClient client,
   char *cp;
   char *newnick = NULL;
   int i, off = 0, len;
+  bool freebase;
   SilcClientEntry *clients;
   SilcUInt32 clients_count = 0;
   SilcClientEntry unformatted = NULL;
@@ -988,10 +1036,15 @@ void silc_client_nickname_format(SilcClient client,
     return;
 
   len = 0;
-  for (i = 0; i < clients_count; i++)
+  freebase = TRUE;
+  for (i = 0; i < clients_count; i++) {
     if (clients[i]->valid && clients[i] != client_entry)
       len++;
-  if (!len)
+    if (clients[i]->valid && clients[i] != client_entry &&
+       !strcmp(clients[i]->nickname, client_entry->nickname))
+      freebase = FALSE;
+  }
+  if (!len || freebase)
     return;
 
   cp = client->internal->params->nickname_format;