1 /* vim:tw=78:ts=8:sw=4:set ft=c: */
3 Copyright (C) 2006-2007 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
30 static gboolean
valid_key(const guchar
*key
, gsize len
)
34 for (b
= 0; b
< len
; b
++) {
42 gboolean
cache_get_mutex(const guchar
*md5filename
, pth_mutex_t
**result
)
48 for (p
= key_cache
, len
= 0; len
<= cache_size
;) {
49 memcpy(&f
, p
, sizeof(file_cache_t
));
52 if (memcmp(&f
.filename
, md5filename
, sizeof(f
.filename
)) == 0) {
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
)
66 memset(&f
, 0, sizeof(file_cache_t
));
70 gint
cache_file_count()
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
)
83 p
+= sizeof(file_cache_t
);
84 len
+= sizeof(file_cache_t
);
86 if (len
+ sizeof(file_cache_t
) > cache_size
)
90 memset(&f
, 0, sizeof(file_cache_t
));
94 void cache_adjust_timer()
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) {
107 if (f
.timeout
== 0) {
108 memset(&f
.key
, 0, sizeof(f
.key
));
110 send_cache_status_all();
113 memcpy(p
, &f
, sizeof(file_cache_t
));
116 p
+= sizeof(file_cache_t
);
117 len
+= sizeof(file_cache_t
);
119 if (len
+ sizeof(file_cache_t
) > cache_size
)
123 memset(&f
, 0, sizeof(file_cache_t
));
126 gboolean
cache_add_file(const guchar
*md5file
, const guchar
*shakey
)
130 gint nfiles
= cache_file_count();
134 * Make sure there is enough secure memory.
136 if (!md5file
|| (nfiles
+ 1) * sizeof(file_cache_t
) > cache_size
)
140 * Find the first available "slot".
142 for (p
= key_cache
, len
= 0; len
<= cache_size
;) {
143 memcpy(&f
, p
, sizeof(file_cache_t
));
145 if (f
.used
== FALSE
) {
146 memset(&f
, 0, sizeof(file_cache_t
));
147 f
.mutex
= xmalloc(sizeof(pth_mutex_t
));
152 pth_mutex_init(f
.mutex
);
153 memcpy(&f
.filename
, md5file
, sizeof(f
.filename
));
156 memcpy(&f
.key
, shakey
, sizeof(f
.key
));
159 f
.reset
= f
.timeout
= -2;
160 memcpy(p
, &f
, sizeof(file_cache_t
));
161 memset(&f
, 0, sizeof(file_cache_t
));
165 p
+= sizeof(file_cache_t
);
166 len
+= sizeof(file_cache_t
);
168 if (len
+ sizeof(file_cache_t
) > cache_size
)
172 memset(&f
, 0, sizeof(file_cache_t
));
176 static void reset_entry(file_cache_t
*f
)
178 pth_mutex_t
*m
= f
->mutex
;
180 if (!f
->refcount
&& m
) {
182 memset(f
, 0, sizeof(file_cache_t
));
185 memset(f
->key
, 0, sizeof(f
->key
));
188 gboolean
cache_clear(const guchar
*md5filename
, gint which
)
194 for (p
= key_cache
, len
= 0; len
<= cache_size
;) {
195 memcpy(&f
, p
, sizeof(file_cache_t
));
199 memcpy(p
, &f
, sizeof(file_cache_t
));
200 memset(&f
, 0, sizeof(file_cache_t
));
202 else if (f
.used
== TRUE
&& which
== 1) {
203 if (memcmp(&f
.filename
, md5filename
, sizeof(f
.filename
)) == 0) {
205 memcpy(p
, &f
, sizeof(file_cache_t
));
206 memset(&f
, 0, sizeof(file_cache_t
));
207 send_cache_status_all();
212 p
+= sizeof(file_cache_t
);
213 len
+= sizeof(file_cache_t
);
215 if (len
+ sizeof(file_cache_t
) > cache_size
)
219 memset(&f
, 0, sizeof(file_cache_t
));
222 send_cache_status_all();
229 gboolean
cache_iscached(const guchar
*md5filename
)
234 gboolean ret
= FALSE
;
236 for (p
= key_cache
, len
= 0; len
<= cache_size
;) {
237 memcpy(&f
, p
, sizeof(file_cache_t
));
239 if (f
.used
== TRUE
) {
240 if (memcmp(&f
.filename
, md5filename
, sizeof(f
.filename
)) == 0) {
241 ret
= valid_key(f
.key
, sizeof(f
.key
));
242 memset(&f
, 0, sizeof(file_cache_t
));
247 p
+= sizeof(file_cache_t
);
248 len
+= sizeof(file_cache_t
);
250 if (len
+ sizeof(file_cache_t
) > cache_size
)
254 memset(&f
, 0, sizeof(file_cache_t
));
258 gboolean
cache_reset_timeout(const guchar
*md5filename
, glong timeout
)
268 for (p
= key_cache
, len
= 0; len
<= cache_size
;) {
269 memcpy(&f
, p
, sizeof(file_cache_t
));
271 if (memcmp((gchar
*)f
.filename
, (gchar
*)md5filename
, sizeof(f
.filename
)) == 0) {
276 p
+= sizeof(file_cache_t
);
277 len
+= sizeof(file_cache_t
);
279 if (len
+ sizeof(file_cache_t
) > cache_size
)
283 memset(&f
, 0, sizeof(file_cache_t
));
286 return cache_set_timeout(md5filename
, timeout
);
288 return cache_set_timeout(md5filename
, t
);
291 gboolean
cache_set_timeout(const guchar
*md5filename
, glong timeout
)
297 for (p
= key_cache
, len
= 0; len
<= cache_size
;) {
298 memcpy(&f
, p
, sizeof(file_cache_t
));
301 if (memcmp((gchar
*)f
.filename
, (gchar
*)md5filename
, sizeof(f
.filename
)) == 0) {
302 f
.reset
= f
.timeout
= timeout
;
303 memcpy(p
, &f
, sizeof(file_cache_t
));
304 memset(&f
, 0, sizeof(file_cache_t
));
309 p
+= sizeof(file_cache_t
);
310 len
+= sizeof(file_cache_t
);
312 if (len
+ sizeof(file_cache_t
) > cache_size
)
316 memset(&f
, 0, sizeof(file_cache_t
));
317 return (md5filename
) ? FALSE
: TRUE
;
320 gboolean
cache_update_key(const guchar
*md5filename
, const guchar
*shakey
)
326 for (p
= key_cache
, len
= 0; len
<= cache_size
;) {
327 memcpy(&f
, p
, sizeof(file_cache_t
));
329 if (f
.used
== TRUE
) {
330 if (memcmp((gchar
*)f
.filename
, (gchar
*)md5filename
, sizeof(f
.filename
)) == 0) {
331 memcpy(&f
.key
, shakey
, sizeof(f
.key
));
332 memcpy(p
, &f
, sizeof(file_cache_t
));
333 memset(&f
, 0, sizeof(file_cache_t
));
338 p
+= sizeof(file_cache_t
);
339 len
+= sizeof(file_cache_t
);
341 if (len
+ sizeof(file_cache_t
) > cache_size
)
345 memset(&f
, 0, sizeof(file_cache_t
));
346 return cache_add_file(md5filename
, shakey
);
349 gboolean
cache_get_key(const guchar
*md5file
, guchar
*shakey
)
355 for (p
= key_cache
, len
= 0; len
<= cache_size
;) {
356 memcpy(&f
, p
, sizeof(file_cache_t
));
359 * The slot may be used but not yet contain a key.
361 if (f
.used
== TRUE
) {
362 if (memcmp(&f
.filename
, md5file
, sizeof(f
.filename
)) == 0) {
363 if (valid_key(f
.key
, sizeof(f
.key
)) == FALSE
)
366 memcpy(shakey
, &f
.key
, sizeof(f
.key
));
367 memset(&f
, 0, sizeof(file_cache_t
));
372 p
+= sizeof(file_cache_t
);
373 len
+= sizeof(file_cache_t
);
375 if (len
+ sizeof(file_cache_t
) > cache_size
)
380 memset(&f
, 0, sizeof(file_cache_t
));
384 gboolean
cache_has_file(const guchar
*md5file
)
390 for (p
= key_cache
, len
= 0; len
<= cache_size
;) {
391 memcpy(&f
, p
, sizeof(file_cache_t
));
393 if (memcmp(&f
.filename
, md5file
, sizeof(f
.filename
)) == 0) {
394 memset(&f
, 0, sizeof(file_cache_t
));
398 p
+= sizeof(file_cache_t
);
399 len
+= sizeof(file_cache_t
);
401 if (len
+ sizeof(file_cache_t
) > cache_size
)
405 memset(&f
, 0, sizeof(file_cache_t
));
409 gboolean
cache_decr_refcount(const guchar
*md5file
)
415 for (p
= key_cache
, len
= 0; len
<= cache_size
;) {
416 memcpy(&f
, p
, sizeof(file_cache_t
));
418 if (f
.used
== TRUE
) {
419 if (memcmp(&f
.filename
, md5file
, sizeof(f
.filename
)) == 0) {
425 memcpy(p
, &f
, sizeof(file_cache_t
));
426 memset(&f
, 0, sizeof(file_cache_t
));
431 p
+= sizeof(file_cache_t
);
432 len
+= sizeof(file_cache_t
);
434 if (len
+ sizeof(file_cache_t
) > cache_size
)
438 memset(&f
, 0, sizeof(file_cache_t
));
442 gboolean
cache_incr_refcount(const guchar
*md5file
)
448 for (p
= key_cache
, len
= 0; len
<= cache_size
;) {
449 memcpy(&f
, p
, sizeof(file_cache_t
));
451 if (f
.used
== TRUE
) {
452 if (memcmp(&f
.filename
, md5file
, sizeof(f
.filename
)) == 0) {
454 memcpy(p
, &f
, sizeof(file_cache_t
));
455 memset(&f
, 0, sizeof(file_cache_t
));
460 p
+= sizeof(file_cache_t
);
461 len
+= sizeof(file_cache_t
);
463 if (len
+ sizeof(file_cache_t
) > cache_size
)
467 memset(&f
, 0, sizeof(file_cache_t
));