int i = 0;
bool found = FALSE;
+ assert(client && conn);
+ if (!nickname)
+ return NULL;
+
/* Find ID from cache */
- if (!silc_idcache_find_by_name(conn->client_cache, (char *)nickname, &list))
+ if (!silc_idcache_find_by_name(conn->internal->client_cache,
+ (char *)nickname, &list))
return NULL;
if (!silc_idcache_list_count(list)) {
void *context)
{
GetClientInternal i;
+ int len;
char *userhost;
+ assert(client && conn);
+
if (!nickname)
return;
i->context = context;
if (nickname && server) {
- userhost = silc_calloc(strlen(nickname) + strlen(server) + 2,
- sizeof(*userhost));
- strncat(userhost, nickname, strlen(nickname));
- strncat(userhost, "@", 1);
- strncat(userhost, server, strlen(server));
+ len = strlen(nickname) + strlen(server) + 3;
+ userhost = silc_calloc(len, sizeof(*userhost));
+ silc_strncat(userhost, len, nickname, strlen(nickname));
+ silc_strncat(userhost, len, "@", 1);
+ silc_strncat(userhost, len, server, strlen(server));
} else {
- userhost = strdup(nickname);
+ userhost = silc_memdup(nickname, strlen(nickname));
}
/* Register our own command reply for this command */
SILC_LOG_DEBUG(("Start"));
/* Find ID from cache */
- if (!silc_idcache_find_by_name(conn->client_cache, (char *)nickname,
- &list)) {
+ if (!silc_idcache_find_by_name(conn->internal->client_cache,
+ (char *)nickname, &list)) {
identify:
if (query) {
SilcBuffer client_id_list;
SilcGetClientCallback completion;
void *context;
+ int res_count;
} *GetClientsByListInternal;
SILC_CLIENT_CMD_FUNC(get_clients_list_callback)
SILC_LOG_DEBUG(("Start"));
+ if (i->res_count) {
+ i->res_count--;
+ if (i->res_count)
+ return;
+ }
+
+ SILC_LOG_DEBUG(("Resolved all clients"));
+
for (c = 0; c < i->list_count; c++) {
SilcUInt16 idp_len;
SilcClientID *client_id;
}
/* Get the client entry */
- if (silc_idcache_find_by_id_one_ext(i->conn->client_cache,
+ if (silc_idcache_find_by_id_one_ext(i->conn->internal->client_cache,
(void *)client_id,
NULL, NULL,
silc_hash_client_id_compare, NULL,
unsigned char **res_argv = NULL;
SilcUInt32 *res_argv_lens = NULL, *res_argv_types = NULL, res_argc = 0;
GetClientsByListInternal in;
+ bool wait_res = FALSE;
+
+ assert(client && conn && client_id_list);
SILC_LOG_DEBUG(("Start"));
SilcUInt16 idp_len;
SilcClientID *client_id;
SilcClientEntry entry;
+ bool ret;
/* Get Client ID */
SILC_GET16_MSB(idp_len, client_id_list->data + 2);
}
/* 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->internal->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;
+ in->res_count++;
+
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
- table that will be sent fr the IDENTIFY command later. */
+ table that will be sent for the IDENTIFY command later. */
res_argv = silc_realloc(res_argv, sizeof(*res_argv) *
(res_argc + 1));
res_argv_lens = silc_realloc(res_argv_lens, sizeof(*res_argv_lens) *
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) {
silc_client_command_pending(conn, SILC_COMMAND_IDENTIFY, conn->cmd_ident,
silc_client_command_get_clients_list_callback,
(void *)in);
+ in->res_count++;
- 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);
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);
{
SilcIDCacheEntry id_cache;
+ assert(client && conn);
+ if (!client_id)
+ return NULL;
+
SILC_LOG_DEBUG(("Finding client by ID (%s)",
silc_id_render(client_id, SILC_ID_CLIENT)));
/* Find ID from cache */
- if (!silc_idcache_find_by_id_one_ext(conn->client_cache, (void *)client_id,
- NULL, NULL,
+ if (!silc_idcache_find_by_id_one_ext(conn->internal->client_cache,
+ (void *)client_id, NULL, NULL,
silc_hash_client_id_compare, NULL,
&id_cache))
return NULL;
void silc_client_get_client_by_id_resolve(SilcClient client,
SilcClientConnection conn,
SilcClientID *client_id,
+ SilcBuffer attributes,
SilcGetClientCallback completion,
void *context)
{
SilcBuffer idp;
GetClientByIDInternal i = silc_calloc(1, sizeof(*i));
+ assert(client && conn && client_id);
+
SILC_LOG_DEBUG(("Start"));
i->client = client;
/* Send the command */
idp = silc_id_payload_encode(client_id, SILC_ID_CLIENT);
silc_client_command_send(client, conn, SILC_COMMAND_WHOIS, conn->cmd_ident,
- 1, 3, idp->data, idp->len);
+ 2, 3, attributes ? attributes->data : NULL,
+ attributes ? attributes->len : 0,
+ 4, idp->data, idp->len);
silc_buffer_free(idp);
/* Add pending callback */
silc_client_nickname_format(client, conn, client_entry);
/* Add client to cache, the non-formatted nickname is saved to cache */
- if (!silc_idcache_add(conn->client_cache, nick, client_entry->id,
+ if (!silc_idcache_add(conn->internal->client_cache, nick, client_entry->id,
(void *)client_entry, 0, NULL)) {
silc_free(client_entry->nickname);
silc_free(client_entry->username);
SILC_LOG_DEBUG(("Start"));
- if (!client_entry->username && username)
- silc_parse_userfqdn(username, &client_entry->username,
+ if ((!client_entry->username || !client_entry->hostname) && username) {
+ silc_free(client_entry->username);
+ silc_free(client_entry->hostname);
+ client_entry->username = NULL;
+ client_entry->hostname = NULL;
+ silc_parse_userfqdn(username, &client_entry->username,
&client_entry->hostname);
+ }
if (!client_entry->realname && userinfo)
client_entry->realname = strdup(userinfo);
if (!client_entry->nickname && nickname) {
if (nick) {
/* Remove the old cache entry and create a new one */
- silc_idcache_del_by_context(conn->client_cache, client_entry);
- silc_idcache_add(conn->client_cache, nick, client_entry->id,
+ silc_idcache_del_by_context(conn->internal->client_cache, client_entry);
+ silc_idcache_add(conn->internal->client_cache, nick, client_entry->id,
client_entry, 0, NULL);
}
}
bool silc_client_del_client(SilcClient client, SilcClientConnection conn,
SilcClientEntry client_entry)
{
- bool ret = silc_idcache_del_by_context(conn->client_cache, client_entry);
+ bool ret = silc_idcache_del_by_context(conn->internal->client_cache,
+ client_entry);
/* Remove from channels */
silc_client_remove_from_channels(client, conn, client_entry);
NULL, NULL, NULL, TRUE);
/* Put it to the ID cache */
- if (!silc_idcache_add(conn->channel_cache, channel->channel_name,
+ if (!silc_idcache_add(conn->internal->channel_cache, channel->channel_name,
(void *)channel->id, (void *)channel, 0, NULL)) {
silc_free(channel->channel_name);
silc_hash_table_free(channel->user_list);
bool silc_client_del_channel(SilcClient client, SilcClientConnection conn,
SilcChannelEntry channel)
{
- bool ret = silc_idcache_del_by_context(conn->channel_cache, channel);
+ bool ret = silc_idcache_del_by_context(conn->internal->channel_cache,
+ channel);
SILC_LOG_DEBUG(("Start"));
SILC_LOG_DEBUG(("New Channel ID id(%s)",
silc_id_render(new_id, SILC_ID_CHANNEL)));
- silc_idcache_del_by_id(conn->channel_cache, channel->id);
+ silc_idcache_del_by_id(conn->internal->channel_cache, channel->id);
silc_free(channel->id);
channel->id = new_id;
- return silc_idcache_add(conn->channel_cache, channel->channel_name,
+ return silc_idcache_add(conn->internal->channel_cache,
+ channel->channel_name,
(void *)channel->id, (void *)channel, 0, NULL);
}
SilcIDCacheEntry id_cache;
SilcChannelEntry entry;
+ assert(client && conn);
+ if (!channel)
+ return NULL;
+
SILC_LOG_DEBUG(("Start"));
- if (!silc_idcache_find_by_name_one(conn->channel_cache, channel,
+ if (!silc_idcache_find_by_name_one(conn->internal->channel_cache, channel,
&id_cache))
return NULL;
SilcIDCacheEntry id_cache;
SilcChannelEntry entry;
+ assert(client && conn);
+ if (!channel_id)
+ return NULL;
+
SILC_LOG_DEBUG(("Start"));
- if (!silc_idcache_find_by_id_one(conn->channel_cache, channel_id,
+ if (!silc_idcache_find_by_id_one(conn->internal->channel_cache, channel_id,
&id_cache))
return NULL;
SilcBuffer idp;
GetChannelByIDInternal i = silc_calloc(1, sizeof(*i));
+ assert(client && conn && channel_id);
+
SILC_LOG_DEBUG(("Start"));
i->client = client;
SilcIDCacheEntry id_cache;
SilcServerEntry entry;
+ assert(client && conn);
+ if (!server_name)
+ return NULL;
+
SILC_LOG_DEBUG(("Start"));
- if (!silc_idcache_find_by_name_one(conn->server_cache, server_name,
- &id_cache))
+ if (!silc_idcache_find_by_name_one(conn->internal->server_cache,
+ server_name, &id_cache))
return NULL;
entry = (SilcServerEntry)id_cache->context;
SilcIDCacheEntry id_cache;
SilcServerEntry entry;
+ assert(client && conn);
+ if (!server_id)
+ return NULL;
+
SILC_LOG_DEBUG(("Start"));
- if (!silc_idcache_find_by_id_one(conn->server_cache, (void *)server_id,
- &id_cache))
+ if (!silc_idcache_find_by_id_one(conn->internal->server_cache,
+ (void *)server_id, &id_cache))
return NULL;
entry = (SilcServerEntry)id_cache->context;
{
SilcServerEntry server_entry;
+ SILC_LOG_DEBUG(("Start"));
+
server_entry = silc_calloc(1, sizeof(*server_entry));
if (!server_entry || !server_id)
return NULL;
server_entry->server_info = strdup(server_info);
/* Add server to cache */
- if (!silc_idcache_add(conn->server_cache, server_entry->server_name,
+ if (!silc_idcache_add(conn->internal->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);
bool silc_client_del_server(SilcClient client, SilcClientConnection conn,
SilcServerEntry server)
{
- bool ret = silc_idcache_del_by_context(conn->server_cache, server);
+ bool ret = silc_idcache_del_by_context(conn->internal->server_cache, server);
silc_free(server->server_name);
silc_free(server->server_info);
silc_free(server->server_id);
return ret;
}
+/* Updates the `server_entry' with the new information sent as argument. */
+
+void silc_client_update_server(SilcClient client,
+ SilcClientConnection conn,
+ SilcServerEntry server_entry,
+ const char *server_name,
+ const char *server_info)
+{
+ SILC_LOG_DEBUG(("Start"));
+
+ if (server_name && (!server_entry->server_name ||
+ strcmp(server_entry->server_name, server_name))) {
+
+ silc_idcache_del_by_context(conn->internal->server_cache, server_entry);
+ silc_free(server_entry->server_name);
+ server_entry->server_name = strdup(server_name);
+ silc_idcache_add(conn->internal->server_cache, server_entry->server_name,
+ server_entry->server_id,
+ server_entry, 0, NULL);
+ }
+
+ if (server_info && (!server_entry->server_info ||
+ strcmp(server_entry->server_info, server_info))) {
+ silc_free(server_entry->server_info);
+ server_entry->server_info = strdup(server_info);
+ }
+}
+
/* Formats the nickname of the client specified by the `client_entry'.
If the format is specified by the application this will format the
nickname and replace the old nickname in the client entry. If the
if (!client_entry->hostname)
break;
len = strcspn(client_entry->hostname, ".");
+ i = strcspn(client_entry->hostname, "-");
+ if (i < len)
+ len = i;
newnick = silc_realloc(newnick, sizeof(*newnick) * (off + len));
memcpy(&newnick[off], client_entry->hostname, len);
off += len;