Replaced occurrences of 'error' with 'rc' since an error() function
[pwmd.git] / src / cache.c
blob7751cf4de01d21acc5d6e5649582c558c53f6f2c
1 /* vim:tw=78:ts=8:sw=4:set ft=c: */
2 /*
3 Copyright (C) 2006-2008 Ben Kibbey <bjk@luxsci.net>
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 #include <stdio.h>
20 #include <glib.h>
21 #include <string.h>
23 #ifdef HAVE_CONFIG_H
24 #include <config.h>
25 #endif
27 #include "cache.h"
28 #include "mem.h"
30 static gboolean valid_key(const guchar *key, gsize len)
32 gint b;
34 for (b = 0; b < len; b++) {
35 if (key[b])
36 return TRUE;
39 return FALSE;
42 gboolean cache_get_mutex(const guchar *md5filename, pth_mutex_t **result)
44 void *p;
45 glong len;
46 file_cache_t f;
48 for (p = key_cache, len = 0; len <= cache_size;) {
49 memcpy(&f, p, sizeof(file_cache_t));
51 if (f.used == TRUE) {
52 if (memcmp(&f.filename, md5filename, sizeof(f.filename)) == 0) {
53 *result = f.mutex;
54 memset(&f, 0, sizeof(file_cache_t));
55 return *result ? TRUE : FALSE;
59 p += sizeof(file_cache_t);
60 len += sizeof(file_cache_t);
62 if (len + sizeof(file_cache_t) > cache_size)
63 break;
66 memset(&f, 0, sizeof(file_cache_t));
67 return FALSE;
70 gint cache_file_count()
72 void *p;
73 gint n = 0;
74 glong len;
75 file_cache_t f;
77 for (p = key_cache, len = 0; len <= cache_size;) {
78 memcpy(&f, p, sizeof(file_cache_t));
80 if (f.used == TRUE && valid_key(f.key, sizeof(f.key)) == TRUE)
81 n++;
83 p += sizeof(file_cache_t);
84 len += sizeof(file_cache_t);
86 if (len + sizeof(file_cache_t) > cache_size)
87 break;
90 memset(&f, 0, sizeof(file_cache_t));
91 return n;
94 void cache_adjust_timer()
96 file_cache_t f;
97 void *p;
98 glong len;
100 for (p = key_cache, len = 0; len <= cache_size;) {
101 memcpy(&f, p, sizeof(file_cache_t));
103 if (f.used == TRUE && f.reset >= 0) {
104 if (f.timeout > 0)
105 f.timeout--;
107 if (f.timeout == 0) {
108 if (valid_key(f.key, sizeof(f.key)) == TRUE) {
109 memset(&f.key, 0, sizeof(f.key));
110 send_cache_status_all();
113 f.timeout = -1;
116 memcpy(p, &f, sizeof(file_cache_t));
119 p += sizeof(file_cache_t);
120 len += sizeof(file_cache_t);
122 if (len + sizeof(file_cache_t) > cache_size)
123 break;
126 memset(&f, 0, sizeof(file_cache_t));
129 gboolean cache_add_file(const guchar *md5file, const guchar *shakey)
131 void *p;
132 file_cache_t f;
133 gint nfiles = cache_file_count();
134 glong len;
137 * Make sure there is enough secure memory.
139 if (!md5file || (nfiles + 1) * sizeof(file_cache_t) > cache_size)
140 return FALSE;
143 * Find the first available "slot".
145 for (p = key_cache, len = 0; len <= cache_size;) {
146 memcpy(&f, p, sizeof(file_cache_t));
148 if (f.used == FALSE) {
149 memset(&f, 0, sizeof(file_cache_t));
150 f.mutex = xmalloc(sizeof(pth_mutex_t));
152 if (!f.mutex)
153 return FALSE;
155 pth_mutex_init(f.mutex);
156 memcpy(&f.filename, md5file, sizeof(f.filename));
158 if (shakey)
159 memcpy(&f.key, shakey, sizeof(f.key));
161 f.used = TRUE;
162 f.reset = f.timeout = -2;
163 memcpy(p, &f, sizeof(file_cache_t));
164 memset(&f, 0, sizeof(file_cache_t));
165 return TRUE;
168 p += sizeof(file_cache_t);
169 len += sizeof(file_cache_t);
171 if (len + sizeof(file_cache_t) > cache_size)
172 break;
175 memset(&f, 0, sizeof(file_cache_t));
176 return FALSE;
179 static void reset_entry(file_cache_t *f)
181 pth_mutex_t *m = f->mutex;
183 if (!f->refcount && m) {
184 xfree(m);
185 memset(f, 0, sizeof(file_cache_t));
187 else
188 memset(f->key, 0, sizeof(f->key));
191 gboolean cache_clear(const guchar *md5filename, gint which)
193 void *p;
194 file_cache_t f;
195 glong len;
197 for (p = key_cache, len = 0; len <= cache_size;) {
198 memcpy(&f, p, sizeof(file_cache_t));
200 if (which == 2) {
201 reset_entry(&f);
202 memcpy(p, &f, sizeof(file_cache_t));
203 memset(&f, 0, sizeof(file_cache_t));
205 else if (f.used == TRUE && which == 1) {
206 if (memcmp(&f.filename, md5filename, sizeof(f.filename)) == 0) {
207 reset_entry(&f);
208 memcpy(p, &f, sizeof(file_cache_t));
210 if (f.reset)
211 send_cache_status_all();
213 memset(&f, 0, sizeof(file_cache_t));
214 return TRUE;
218 p += sizeof(file_cache_t);
219 len += sizeof(file_cache_t);
221 if (len + sizeof(file_cache_t) > cache_size)
222 break;
225 memset(&f, 0, sizeof(file_cache_t));
227 if (which == 2) {
228 send_cache_status_all();
229 return TRUE;
232 return FALSE;
235 gboolean cache_iscached(const guchar *md5filename)
237 void *p;
238 file_cache_t f;
239 glong len;
240 gboolean ret = FALSE;
242 for (p = key_cache, len = 0; len <= cache_size;) {
243 memcpy(&f, p, sizeof(file_cache_t));
245 if (f.used == TRUE) {
246 if (memcmp(&f.filename, md5filename, sizeof(f.filename)) == 0) {
247 ret = valid_key(f.key, sizeof(f.key));
248 memset(&f, 0, sizeof(file_cache_t));
249 return ret;
253 p += sizeof(file_cache_t);
254 len += sizeof(file_cache_t);
256 if (len + sizeof(file_cache_t) > cache_size)
257 break;
260 memset(&f, 0, sizeof(file_cache_t));
261 return FALSE;
264 gboolean cache_reset_timeout(const guchar *md5filename, glong timeout)
266 void *p;
267 file_cache_t f;
268 glong len;
269 glong t = -2;
271 if (!md5filename)
272 return FALSE;
274 for (p = key_cache, len = 0; len <= cache_size;) {
275 memcpy(&f, p, sizeof(file_cache_t));
277 if (memcmp((gchar *)f.filename, (gchar *)md5filename, sizeof(f.filename)) == 0) {
278 t = f.reset;
279 break;
282 p += sizeof(file_cache_t);
283 len += sizeof(file_cache_t);
285 if (len + sizeof(file_cache_t) > cache_size)
286 break;
289 memset(&f, 0, sizeof(file_cache_t));
291 if (t == -2)
292 return cache_set_timeout(md5filename, timeout);
294 return cache_set_timeout(md5filename, t);
297 gboolean cache_set_timeout(const guchar *md5filename, glong timeout)
299 void *p;
300 file_cache_t f;
301 glong len;
303 for (p = key_cache, len = 0; len <= cache_size;) {
304 memcpy(&f, p, sizeof(file_cache_t));
306 if (md5filename) {
307 if (memcmp((gchar *)f.filename, (gchar *)md5filename, sizeof(f.filename)) == 0) {
308 if (timeout == -2)
309 f.timeout = f.reset;
310 else
311 f.reset = f.timeout = timeout;
313 memcpy(p, &f, sizeof(file_cache_t));
314 memset(&f, 0, sizeof(file_cache_t));
315 return TRUE;
319 p += sizeof(file_cache_t);
320 len += sizeof(file_cache_t);
322 if (len + sizeof(file_cache_t) > cache_size)
323 break;
326 memset(&f, 0, sizeof(file_cache_t));
327 return (md5filename) ? FALSE : TRUE;
330 gboolean cache_update_key(const guchar *md5filename, const guchar *shakey)
332 void *p;
333 file_cache_t f;
334 glong len;
336 for (p = key_cache, len = 0; len <= cache_size;) {
337 memcpy(&f, p, sizeof(file_cache_t));
339 if (f.used == TRUE) {
340 if (memcmp((gchar *)f.filename, (gchar *)md5filename, sizeof(f.filename)) == 0) {
341 if (f.reset)
342 memcpy(&f.key, shakey, sizeof(f.key));
344 memcpy(p, &f, sizeof(file_cache_t));
345 memset(&f, 0, sizeof(file_cache_t));
346 return TRUE;
350 p += sizeof(file_cache_t);
351 len += sizeof(file_cache_t);
353 if (len + sizeof(file_cache_t) > cache_size)
354 break;
357 memset(&f, 0, sizeof(file_cache_t));
358 return cache_add_file(md5filename, shakey);
361 gboolean cache_get_key(const guchar *md5file, guchar *shakey)
363 void *p;
364 file_cache_t f;
365 glong len;
367 for (p = key_cache, len = 0; len <= cache_size;) {
368 memcpy(&f, p, sizeof(file_cache_t));
371 * The slot may be used but not yet contain a key.
373 if (f.used == TRUE) {
374 if (memcmp(&f.filename, md5file, sizeof(f.filename)) == 0) {
375 if (valid_key(f.key, sizeof(f.key)) == FALSE)
376 goto fail;
378 memcpy(shakey, &f.key, sizeof(f.key));
379 memset(&f, 0, sizeof(file_cache_t));
380 return TRUE;
384 p += sizeof(file_cache_t);
385 len += sizeof(file_cache_t);
387 if (len + sizeof(file_cache_t) > cache_size)
388 break;
391 fail:
392 memset(&f, 0, sizeof(file_cache_t));
393 return FALSE;
396 gboolean cache_has_file(const guchar *md5file)
398 void *p;
399 file_cache_t f;
400 glong len;
402 for (p = key_cache, len = 0; len <= cache_size;) {
403 memcpy(&f, p, sizeof(file_cache_t));
405 if (memcmp(&f.filename, md5file, sizeof(f.filename)) == 0) {
406 memset(&f, 0, sizeof(file_cache_t));
407 return TRUE;
410 p += sizeof(file_cache_t);
411 len += sizeof(file_cache_t);
413 if (len + sizeof(file_cache_t) > cache_size)
414 break;
417 memset(&f, 0, sizeof(file_cache_t));
418 return FALSE;
421 gboolean cache_decr_refcount(const guchar *md5file)
423 void *p;
424 file_cache_t f;
425 glong len;
427 for (p = key_cache, len = 0; len <= cache_size;) {
428 memcpy(&f, p, sizeof(file_cache_t));
430 if (f.used == TRUE) {
431 if (memcmp(&f.filename, md5file, sizeof(f.filename)) == 0) {
432 f.refcount--;
434 if (f.refcount < 0)
435 f.refcount = 0;
437 memcpy(p, &f, sizeof(file_cache_t));
438 memset(&f, 0, sizeof(file_cache_t));
439 return TRUE;
443 p += sizeof(file_cache_t);
444 len += sizeof(file_cache_t);
446 if (len + sizeof(file_cache_t) > cache_size)
447 break;
450 memset(&f, 0, sizeof(file_cache_t));
451 return FALSE;
454 gboolean cache_incr_refcount(const guchar *md5file)
456 void *p;
457 file_cache_t f;
458 glong len;
460 for (p = key_cache, len = 0; len <= cache_size;) {
461 memcpy(&f, p, sizeof(file_cache_t));
463 if (f.used == TRUE) {
464 if (memcmp(&f.filename, md5file, sizeof(f.filename)) == 0) {
465 f.refcount++;
466 memcpy(p, &f, sizeof(file_cache_t));
467 memset(&f, 0, sizeof(file_cache_t));
468 return TRUE;
472 p += sizeof(file_cache_t);
473 len += sizeof(file_cache_t);
475 if (len + sizeof(file_cache_t) > cache_size)
476 break;
479 memset(&f, 0, sizeof(file_cache_t));
480 return FALSE;