Global cosmetic change.
[silc.git] / lib / silccore / idcache.c
1 /*
2
3   idcache.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 /* XXX: This ID cache system sucks and must be rewritten! */
21 /*
22  * $Id$
23  * $Log$
24  * Revision 1.2  2000/07/05 06:06:35  priikone
25  *      Global cosmetic change.
26  *
27  * Revision 1.1.1.1  2000/06/27 11:36:55  priikone
28  *      Imported from internal CVS/Added Log headers.
29  *
30  *
31  */
32
33 #include "silcincludes.h"
34
35 /* qsort() sorter function. */
36
37 static int silc_idcache_sorter(const void *a, const void *b)
38 {
39   SilcIDCache *a1, *b1;
40   
41   a1 = (SilcIDCache *)a;
42   b1 = (SilcIDCache *)b;
43   
44   return a1->data[0] - b1->data[0];
45 }
46
47 /* Sorts given cache by data */
48
49 void silc_idcache_sort_by_data(SilcIDCache *cache, unsigned int count)
50 {
51   qsort(cache, count, sizeof(*cache), silc_idcache_sorter);
52 }
53
54 /* Find ID Cache entry by data. The data maybe anything that must
55    match exactly. */
56
57 int silc_idcache_find_by_data(SilcIDCache *cache, unsigned int cache_count,
58                               char *data, SilcIDCache **ret)
59 {
60   int i;
61
62   if (cache == NULL)
63     return FALSE;
64
65   if (data == NULL)
66     return FALSE;
67
68   for (i = 0; i < cache_count; i++)
69     if (cache[i].data && !memcmp(cache[i].data, data, strlen(data))) {
70       if (ret)
71         *ret = &(cache[i]);
72       return TRUE;
73     }
74
75   return FALSE;
76 }
77
78 /* Find ID Cache entry by ID. */
79
80 int silc_idcache_find_by_id(SilcIDCache *cache, unsigned int cache_count, 
81                             void *id, SilcIdType type, SilcIDCache **ret)
82 {
83   int i, id_len;
84
85   if (cache == NULL)
86     return FALSE;
87
88   if (id == NULL)
89     return FALSE;
90
91   id_len = silc_id_get_len(type);
92
93   for (i = 0; i < cache_count; i++)
94     if (cache[i].id && !memcmp(cache[i].id, id, id_len)) {
95       if (ret)
96         *ret = &(cache[i]);
97       return TRUE;
98     }
99
100   return FALSE;
101 }
102
103 /* Add new entry to the cache. Returns number of allocated cache
104    entries in the cache. */
105
106 int silc_idcache_add(SilcIDCache **cache, unsigned int cache_count,
107                      char *data, SilcIdType id_type, void *id, 
108                      void *context)
109 {
110   SilcIDCache *c;
111   int i;
112   unsigned long curtime = time(NULL);
113
114   SILC_LOG_DEBUG(("Adding cache entry"));
115
116   c = *cache;
117
118   if (c == NULL) {
119     c = silc_calloc(5, sizeof(*c));
120     cache_count = 5;
121   }
122
123   /* See if it exists already */
124   if (silc_idcache_find_by_id(c, cache_count, id, id_type, NULL) == TRUE)
125     return cache_count;
126
127   for (i = 0; i < cache_count; i++) {
128     if (c[i].data == NULL) {
129       c[i].data = data;
130       c[i].type = id_type;
131       c[i].id = id;
132       c[i].expire = curtime + SILC_ID_CACHE_EXPIRE;
133       c[i].context = context;
134       break;
135     }
136   }
137
138   if (i == cache_count) {
139     c = silc_realloc(c, sizeof(*c) * (cache_count + 5));
140     for (i = cache_count; i < cache_count + 5; i++) {
141       c[i].data = NULL;
142       c[i].id = NULL;
143     }
144     c[cache_count].data = data;
145     c[cache_count].type = id_type;
146     c[cache_count].id = id;
147     c[cache_count].expire = curtime + SILC_ID_CACHE_EXPIRE;
148     c[cache_count].context = context;
149     cache_count += 5;
150   }
151
152   *cache = c;
153
154   return cache_count;
155 }
156
157 /* Delete cache entry from cache. */
158 /* XXX */
159
160 int silc_idcache_del(SilcIDCache *cache, SilcIDCache *old)
161 {
162
163   return TRUE;
164 }
165
166 /* XXX */
167
168 int silc_idcache_del_by_data(SilcIDCache *cache, unsigned int cache_count,
169                              char *data)
170 {
171
172   return TRUE;
173 }
174
175 /* Deletes ID cache entry by ID. */
176
177 int silc_idcache_del_by_id(SilcIDCache *cache, unsigned int cache_count,
178                            SilcIdType type, void *id)
179 {
180   int i, id_len;
181
182   if (cache == NULL)
183     return FALSE;
184
185   if (id == NULL)
186     return FALSE;
187
188   id_len = silc_id_get_len(type);
189
190   for (i = 0; i < cache_count; i++)
191     if (cache[i].id && !memcmp(cache[i].id, id, id_len)) {
192       cache[i].id = NULL;
193       cache[i].data = NULL;
194       cache[i].type = 0;
195       cache[i].context = NULL;
196       return TRUE;
197     }
198
199   return FALSE;
200 }
201
202 /* Deletes all ID entries from cache. Free's memory as well. */
203
204 int silc_idcache_del_all(SilcIDCache **cache, unsigned int cache_count)
205 {
206   SilcIDCache *c = *cache;
207   int i;
208
209   if (c == NULL)
210     return FALSE;
211
212   for (i = 0; i < cache_count; i++) {
213     c[i].id = NULL;
214     c[i].data = NULL;
215     c[i].type = 0;
216     c[i].expire = 0;
217     c[i].context = NULL;
218   }
219
220   silc_free(*cache);
221   *cache = NULL;
222
223   return TRUE;
224 }
225
226 /* Purges the cache by removing expired cache entires. This does not
227    free any memory though. */
228
229 int silc_idcache_purge(SilcIDCache *cache, unsigned int cache_count)
230 {
231   unsigned long curtime = time(NULL);
232   int i;
233
234   if (cache == NULL)
235     return FALSE;
236
237   for (i = 0; i < cache_count; i++) {
238     if (cache[i].data && 
239         (cache[i].expire == 0 || cache[i].expire < curtime)) {
240       cache[i].id = NULL;
241       cache[i].data = NULL;
242       cache[i].type = 0;
243       cache[i].expire = 0;
244       cache[i].context = NULL;
245     }
246   }
247
248   return TRUE;
249 }