X-Git-Url: http://git.silcnet.org/gitweb/?a=blobdiff_plain;f=lib%2Fsilcclient%2Fidlist.c;h=1197a90bf47e636f4290a53f19efde326292279a;hb=517c8c6c585abe5e5d971125e367c29fcdee8f4c;hp=c50b8a5f8d5420e1a6d2f3fd0d5ac279cd33f9e7;hpb=7e87feeb3a406211a66f136325ee49ffe53c06f3;p=silc.git diff --git a/lib/silcclient/idlist.c b/lib/silcclient/idlist.c index c50b8a5f..1197a90b 100644 --- a/lib/silcclient/idlist.c +++ b/lib/silcclient/idlist.c @@ -41,7 +41,8 @@ SILC_CLIENT_CMD_FUNC(get_client_callback) i->nickname, i->server, &clients_count); if (clients) { - i->completion(i->cmd->client, i->cmd->conn, NULL, 0, i->context); + i->completion(i->cmd->client, i->cmd->conn, clients, + clients_count, i->context); i->found = TRUE; silc_free(clients); } @@ -126,8 +127,10 @@ SilcClientEntry *silc_client_get_clients_local(SilcClient client, if (!silc_idcache_find_by_data_loose(conn->client_cache, nickname, &list)) return NULL; - if (silc_idcache_list_count(list) == 0) + if (!silc_idcache_list_count(list)) { + silc_idcache_list_free(list); return NULL; + } clients = silc_calloc(silc_idcache_list_count(list), sizeof(*clients)); *clients_count = silc_idcache_list_count(list); @@ -273,6 +276,74 @@ SilcClientEntry silc_client_get_client_by_id(SilcClient client, return (SilcClientEntry)id_cache->context; } +typedef struct { + SilcClient client; + SilcClientConnection conn; + SilcClientID *client_id; + SilcGetClientCallback completion; + void *context; + int found; +} *GetClientByIDInternal; + +SILC_CLIENT_CMD_FUNC(get_client_by_id_callback) +{ + GetClientByIDInternal i = (GetClientByIDInternal)context; + SilcClientEntry entry; + + /* 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); + i->found = TRUE; + } +} + +static void silc_client_get_client_by_id_destructor(void *context) +{ + GetClientByIDInternal i = (GetClientByIDInternal)context; + + if (i->found == FALSE) + i->completion(i->client, i->conn, NULL, 0, i->context); + + if (i->client_id) + silc_free(i->client_id); + silc_free(i); +} + +/* Same as above but will always resolve the information from the server. + Use this only if you know that you don't have the entry and the only + thing you know about the client is its ID. */ + +void silc_client_get_client_by_id_resolve(SilcClient client, + SilcClientConnection conn, + SilcClientID *client_id, + SilcGetClientCallback completion, + void *context) +{ + SilcBuffer idp; + GetClientByIDInternal i = silc_calloc(1, sizeof(*i)); + + idp = silc_id_payload_encode(client_id, SILC_ID_CLIENT); + silc_client_send_command(client, conn, SILC_COMMAND_IDENTIFY, + ++conn->cmd_ident, + 1, 3, idp->data, idp->len); + silc_buffer_free(idp); + + i->client = client; + i->conn = conn; + i->client_id = silc_id_dup(client_id, SILC_ID_CLIENT); + i->completion = completion; + i->context = context; + + /* Add pending callback */ + silc_client_command_pending(conn, SILC_COMMAND_IDENTIFY, + ++conn->cmd_ident, + silc_client_get_client_by_id_destructor, + silc_client_command_get_client_by_id_callback, + (void *)i); +} + /* Finds entry for channel by the channel name. Returns the entry or NULL if the entry was not found. It is found only if the client is joined to the channel. */