5 Author: Pekka Riikonen <priikone@poseidon.pspt.fi>
7 Copyright (C) 2000 Pekka Riikonen
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
22 #include "clientlibincludes.h"
25 SilcClientCommandContext cmd;
26 SilcGetClientCallback completion;
33 SILC_CLIENT_CMD_FUNC(get_client_callback)
35 GetClientInternal i = (GetClientInternal)context;
36 SilcClientEntry *clients;
37 unsigned int clients_count;
40 clients = silc_client_get_clients_local(i->cmd->client, i->cmd->conn,
41 i->nickname, i->server,
44 i->completion(i->cmd->client, i->cmd->conn, NULL, 0, i->context);
50 static void silc_client_get_client_destructor(void *context)
52 GetClientInternal i = (GetClientInternal)context;
54 if (i->found == FALSE)
55 i->completion(i->cmd->client, i->cmd->conn, NULL, 0, i->context);
57 silc_client_command_free(i->cmd);
59 silc_free(i->nickname);
65 /* Finds client entry or entries by the `nickname' and `server'. The
66 completion callback will be called when the client entries has been found.
68 Note: this function is always asynchronous and resolves the client
69 information from the server. Thus, if you already know the client
70 information then use the silc_client_get_client_by_id function to
71 get the client entry since this function may be very slow and should
72 be used only to initially get the client entries. */
74 void silc_client_get_clients(SilcClient client,
75 SilcClientConnection conn,
78 SilcGetClientCallback completion,
82 SilcClientCommandContext ctx;
83 GetClientInternal i = silc_calloc(1, sizeof(*i));
85 /* No ID found. Do query from the server. The query is done by
86 sending simple IDENTIFY command to the server. */
87 ctx = silc_client_command_alloc();
90 ctx->command = silc_client_command_find("IDENTIFY");
91 memset(ident, 0, sizeof(ident));
92 snprintf(ident, sizeof(ident), "IDENTIFY %s", nickname);
93 silc_parse_command_line(ident, &ctx->argv, &ctx->argv_lens,
94 &ctx->argv_types, &ctx->argc, 2);
95 ctx->command->cb(ctx);
98 i->nickname = nickname ? strdup(nickname) : NULL;
99 i->server = server ? strdup(server) : NULL;
100 i->completion = completion;
101 i->context = context;
103 /* Add pending callback */
104 silc_client_command_pending(conn, SILC_COMMAND_IDENTIFY,
106 silc_client_get_client_destructor,
107 silc_client_command_get_client_callback,
111 /* Same as above function but does not resolve anything from the server.
112 This checks local cache and returns all clients from the cache. */
114 SilcClientEntry *silc_client_get_clients_local(SilcClient client,
115 SilcClientConnection conn,
118 unsigned int *clients_count)
120 SilcIDCacheEntry id_cache;
121 SilcIDCacheList list = NULL;
122 SilcClientEntry entry, *clients;
125 /* Find ID from cache */
126 if (!silc_idcache_find_by_data_loose(conn->client_cache, nickname, &list))
129 if (silc_idcache_list_count(list) == 0)
132 clients = silc_calloc(silc_idcache_list_count(list), sizeof(*clients));
133 *clients_count = silc_idcache_list_count(list);
136 /* Take all without any further checking */
137 silc_idcache_list_first(list, &id_cache);
139 clients[i++] = id_cache->context;
140 if (!silc_idcache_list_next(list, &id_cache))
144 /* Check multiple cache entries for match */
145 silc_idcache_list_first(list, &id_cache);
147 entry = (SilcClientEntry)id_cache->context;
150 strncasecmp(server, entry->server, strlen(server))) {
151 if (!silc_idcache_list_next(list, &id_cache)) {
158 clients[i++] = id_cache->context;
159 if (!silc_idcache_list_next(list, &id_cache))
165 silc_idcache_list_free(list);
170 /* The old style function to find client entry. This is used by the
171 library internally. If `query' is TRUE then the client information is
172 requested by the server. The pending command callback must be set
175 SilcClientEntry silc_idlist_get_client(SilcClient client,
176 SilcClientConnection conn,
182 SilcIDCacheEntry id_cache;
183 SilcIDCacheList list = NULL;
184 SilcClientEntry entry = NULL;
186 /* Find ID from cache */
187 if (!silc_idcache_find_by_data_loose(conn->client_cache, nickname, &list)) {
192 SilcClientCommandContext ctx;
194 SILC_LOG_DEBUG(("Requesting Client ID from server"));
196 /* No ID found. Do query from the server. The query is done by
197 sending simple IDENTIFY command to the server. */
198 ctx = silc_client_command_alloc();
199 ctx->client = client;
201 ctx->command = silc_client_command_find("IDENTIFY");
202 memset(ident, 0, sizeof(ident));
203 snprintf(ident, sizeof(ident), "IDENTIFY %s", nickname);
204 silc_parse_command_line(ident, &ctx->argv, &ctx->argv_lens,
205 &ctx->argv_types, &ctx->argc, 2);
206 ctx->command->cb(ctx);
209 silc_idcache_list_free(list);
216 if (!server && !num) {
217 /* Take first found cache entry */
218 if (!silc_idcache_list_first(list, &id_cache))
221 entry = (SilcClientEntry)id_cache->context;
223 /* Check multiple cache entries for match */
224 silc_idcache_list_first(list, &id_cache);
225 entry = (SilcClientEntry)id_cache->context;
228 if (server && entry->server &&
229 !strncasecmp(server, entry->server, strlen(server)))
232 if (num && entry->num == num)
235 if (!silc_idcache_list_next(list, &id_cache)) {
240 entry = (SilcClientEntry)id_cache->context;
243 /* If match weren't found, request it */
249 silc_idcache_list_free(list);
254 /* Finds entry for client by the client's ID. Returns the entry or NULL
255 if the entry was not found. */
257 SilcClientEntry silc_client_get_client_by_id(SilcClient client,
258 SilcClientConnection conn,
259 SilcClientID *client_id)
261 SilcIDCacheEntry id_cache;
263 SILC_LOG_DEBUG(("Finding client by ID (%s)",
264 silc_id_render(client_id, SILC_ID_CLIENT)));
266 /* Find ID from cache */
267 if (!silc_idcache_find_by_id_one(conn->client_cache, client_id,
268 SILC_ID_CLIENT, &id_cache))
271 SILC_LOG_DEBUG(("Found"));
273 return (SilcClientEntry)id_cache->context;
276 /* Finds entry for channel by the channel name. Returns the entry or NULL
277 if the entry was not found. It is found only if the client is joined
280 SilcChannelEntry silc_client_get_channel(SilcClient client,
281 SilcClientConnection conn,
284 SilcIDCacheEntry id_cache;
285 SilcChannelEntry entry;
287 if (!silc_idcache_find_by_data_one(conn->channel_cache, channel, &id_cache))
290 entry = (SilcChannelEntry)id_cache->context;