updates.
[silc.git] / lib / silcclient / idlist.c
1 /*
2
3   idlist.c
4
5   Author: Pekka Riikonen <priikone@poseidon.pspt.fi>
6
7   Copyright (C) 2000 Pekka Riikonen
8
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.
13   
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.
18
19 */
20 /* $Id$ */
21
22 #include "clientlibincludes.h"
23
24 /* Finds client entry from cache by nickname. If the entry is not found
25    from the cache this function queries it from the server. If `server'
26    and `num' are defined as well thisk checks the match from multiple
27    cache entries thus providing support for multiple same nickname
28    handling. This also ignores case-sensitivity. */
29
30 SilcClientEntry silc_idlist_get_client(SilcClient client,
31                                        SilcClientConnection conn,
32                                        char *nickname,
33                                        char *server,
34                                        unsigned int num)
35 {
36   SilcIDCacheEntry id_cache;
37   SilcIDCacheList list = NULL;
38   SilcClientEntry entry = NULL;
39
40   /* Find ID from cache */
41   if (!silc_idcache_find_by_data_loose(conn->client_cache, nickname, &list)) {
42     SilcClientCommandContext ctx;
43     char ident[512];
44     
45   identify:
46
47     SILC_LOG_DEBUG(("Requesting Client ID from server"));
48
49     /* No ID found. Do query from the server. The query is done by 
50        sending simple IDENTIFY command to the server. */
51     ctx = silc_calloc(1, sizeof(*ctx));
52     ctx->client = client;
53     ctx->conn = conn;
54     ctx->command = silc_client_command_find("IDENTIFY");
55     memset(ident, 0, sizeof(ident));
56     snprintf(ident, sizeof(ident), "IDENTIFY %s", nickname);
57     silc_parse_command_line(ident, &ctx->argv, &ctx->argv_lens, 
58                             &ctx->argv_types, &ctx->argc, 2);
59     ctx->command->cb(ctx);
60
61     if (list)
62       silc_idcache_list_free(list);
63
64     return NULL;
65   }
66
67   if (!server && !num) {
68     /* Take first found cache entry */
69     if (!silc_idcache_list_first(list, &id_cache))
70       goto identify;
71
72     entry = (SilcClientEntry)id_cache->context;
73   } else {
74     /* Check multiple cache entries for match */
75     silc_idcache_list_first(list, &id_cache);
76     entry = (SilcClientEntry)id_cache->context;
77     
78     while (entry) {
79       if (server && entry->server && 
80           !strncasecmp(server, entry->server, strlen(server)))
81         break;
82       
83       if (num && entry->num == num)
84         break;
85
86       if (!silc_idcache_list_next(list, &id_cache)) {
87         entry = NULL;
88         break;
89       }
90
91       entry = (SilcClientEntry)id_cache->context;
92     }
93
94     /* If match weren't found, request it */
95     if (!entry)
96       goto identify;
97   }
98
99   if (list)
100     silc_idcache_list_free(list);
101
102   return entry;
103 }
104
105 /* Finds client entry from cache by Client ID. If the entry is not found
106    from the cache this function can query it from the server. */
107
108 SilcClientEntry silc_idlist_get_client_by_id(SilcClient client,
109                                              SilcClientConnection conn,
110                                              SilcClientID *client_id,
111                                              int query)
112 {
113   SilcIDCacheEntry id_cache;
114
115   SILC_LOG_DEBUG(("Finding client by ID (%s)", 
116                   silc_id_render(client_id, SILC_ID_CLIENT)));
117
118   /* Find ID from cache */
119   if (!silc_idcache_find_by_id_one(conn->client_cache, client_id, 
120                                    SILC_ID_CLIENT, &id_cache)) {
121     if (!query) {
122       return NULL;
123     } else {
124       SilcBuffer idp = silc_id_payload_encode(client_id, SILC_ID_CLIENT);
125       silc_client_send_command(client, conn, SILC_COMMAND_WHOIS, 1,
126                                3, idp->data, idp->len);
127       return NULL;
128     }
129   }
130
131   return (SilcClientEntry)id_cache->context;
132 }
133
134 /* Finds channel entry from ID cache by channel name. */
135
136 SilcChannelEntry silc_idlist_get_channel(SilcClient client,
137                                          SilcClientConnection conn,
138                                          char *channel)
139 {
140   SilcIDCacheEntry id_cache;
141   SilcChannelEntry entry;
142
143   if (!silc_idcache_find_by_data_one(conn->channel_cache, channel, &id_cache))
144     return NULL;
145
146   entry = (SilcChannelEntry)id_cache->context;
147
148   return entry;
149 }