#include "clientlibincludes.h"
#include "client_internal.h"
+typedef struct {
+ SilcPacketContext *packet;
+ void *context;
+ SilcSocketConnection sock;
+} *SilcClientNotifyResolve;
+
/* Called when notify is received and some async operation (such as command)
is required before processing the notify message. This calls again the
silc_client_notify_by_server and reprocesses the original notify packet. */
static void silc_client_notify_by_server_pending(void *context, void *context2)
{
- SilcPacketContext *p = (SilcPacketContext *)context;
- silc_client_notify_by_server(p->context, p->sock, p);
- silc_socket_free(p->sock);
+ SilcClientNotifyResolve res = (SilcClientNotifyResolve)context;
+ silc_client_notify_by_server(res->context, res->sock, res->packet);
+ silc_socket_free(res->sock);
}
/* Destructor for the pending command callback */
static void silc_client_notify_by_server_destructor(void *context)
{
- silc_packet_context_free((SilcPacketContext *)context);
+ SilcClientNotifyResolve res = (SilcClientNotifyResolve)context;
+ silc_packet_context_free(res->packet);
+ silc_free(res);
}
/* Resolve client information from server by Client ID. */
SilcPacketContext *packet,
SilcClientID *client_id)
{
- SilcPacketContext *p = silc_packet_context_dup(packet);
+ SilcClientNotifyResolve res = silc_calloc(1, sizeof(*res));
SilcBuffer idp = silc_id_payload_encode(client_id, SILC_ID_CLIENT);
- p->context = (void *)client;
- p->sock = silc_socket_dup(conn->sock);
+ res->packet = silc_packet_context_dup(packet);
+ res->context = client;
+ res->sock = silc_socket_dup(conn->sock);
silc_client_send_command(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,
- silc_client_notify_by_server_pending, p);
+ silc_client_notify_by_server_pending, res);
silc_buffer_free(idp);
}
/* If nickname or username hasn't been resolved, do so */
if (!client_entry->nickname || !client_entry->username) {
+ if (client_entry->status & SILC_CLIENT_STATUS_RESOLVING)
+ goto out;
+ client_entry->status |= SILC_CLIENT_STATUS_RESOLVING;
silc_client_notify_by_server_resolve(client, conn, packet, client_id);
goto out;
}
silc_free(client_id);
}
+ 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,
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;
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) {
+ 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. */
uint32 clients_count = 0;
int c;
+ SILC_LOG_DEBUG(("Start"));
+
for (c = 0; c < i->list_count; c++) {
uint16 idp_len;
SilcClientID *client_id;
{
GetClientsByListInternal i = (GetClientsByListInternal)context;
+ SILC_LOG_DEBUG(("Start"));
+
if (i->found == FALSE)
i->completion(i->client, i->conn, NULL, 0, i->context);
uint32 *res_argv_lens = NULL, *res_argv_types = NULL, res_argc = 0;
GetClientsByListInternal in;
+ SILC_LOG_DEBUG(("Start"));
+
in = silc_calloc(1, sizeof(*in));
in->client = client;
in->conn = conn;
it from the server. */
entry = id_cache ? (SilcClientEntry)id_cache->context : NULL;
if (!id_cache || !entry->nickname) {
+
+ if (entry) {
+ if (entry->status & SILC_CLIENT_STATUS_RESOLVING) {
+ silc_free(client_id);
+ silc_buffer_pull(client_id_list, idp_len);
+ continue;
+ }
+
+ entry->status |= SILC_CLIENT_STATUS_RESOLVING;
+ }
+
/* No we don't have it, query it from the server. Assemble argument
table that will be sent fr the IDENTIFY command later. */
res_argv = silc_realloc(res_argv, sizeof(*res_argv) *
SilcIDCacheList list = NULL;
SilcClientEntry entry = NULL;
+ SILC_LOG_DEBUG(("Start"));
+
/* Find ID from cache */
if (!silc_idcache_find_by_name(conn->client_cache, (char *)nickname,
&list)) {
SilcBuffer idp;
GetClientByIDInternal i = silc_calloc(1, sizeof(*i));
+ SILC_LOG_DEBUG(("Start"));
+
idp = silc_id_payload_encode(client_id, SILC_ID_CLIENT);
silc_client_send_command(client, conn, SILC_COMMAND_WHOIS,
++conn->cmd_ident,
SilcClientEntry client_entry;
char *nick = NULL;
+ SILC_LOG_DEBUG(("Start"));
+
/* Save the client infos */
client_entry = silc_calloc(1, sizeof(*client_entry));
client_entry->id = id;
{
char *nick = NULL;
+ SILC_LOG_DEBUG(("Start"));
+
if (!client_entry->username && username)
silc_parse_userfqdn(username, &client_entry->username,
&client_entry->hostname);
void silc_client_del_client_entry(SilcClient client,
SilcClientEntry client_entry)
{
+ SILC_LOG_DEBUG(("Start"));
+
silc_free(client_entry->nickname);
silc_free(client_entry->username);
silc_free(client_entry->realname);
SilcIDCacheEntry id_cache;
SilcChannelEntry entry;
+ SILC_LOG_DEBUG(("Start"));
+
if (!silc_idcache_find_by_name_one(conn->channel_cache, channel,
&id_cache))
return NULL;
SilcIDCacheEntry id_cache;
SilcChannelEntry entry;
+ SILC_LOG_DEBUG(("Start"));
+
if (!silc_idcache_find_by_id_one(conn->channel_cache, channel_id,
&id_cache))
return NULL;
GetChannelByIDInternal i = (GetChannelByIDInternal)context;
SilcChannelEntry entry;
+ SILC_LOG_DEBUG(("Start"));
+
/* Get the channel */
entry = silc_client_get_channel_by_id(i->client, i->conn,
i->channel_id);
SilcBuffer idp;
GetChannelByIDInternal i = silc_calloc(1, sizeof(*i));
+ SILC_LOG_DEBUG(("Start"));
+
idp = silc_id_payload_encode(channel_id, SILC_ID_CHANNEL);
silc_client_send_command(client, conn, SILC_COMMAND_IDENTIFY,
++conn->cmd_ident,
SilcBuffer idp;
SilcChannelEntry channel;
+ SILC_LOG_DEBUG(("Start"));
+
channel = silc_client_get_channel_by_id(client, conn, channel_id);
if (channel)
return channel;
SilcIDCacheEntry id_cache;
SilcServerEntry entry;
+ SILC_LOG_DEBUG(("Start"));
+
if (!silc_idcache_find_by_name_one(conn->server_cache, server_name,
&id_cache))
return NULL;
SilcIDCacheEntry id_cache;
SilcServerEntry entry;
+ SILC_LOG_DEBUG(("Start"));
+
if (!silc_idcache_find_by_id_one(conn->server_cache, (void *)server_id,
&id_cache))
return NULL;
SilcClientEntry *clients;
uint32 clients_count = 0;
+ SILC_LOG_DEBUG(("Start"));
+
if (!client->params->nickname_format[0])
return;