1 /* vim:tw=78:ts=8:sw=4:set ft=c: */
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
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 if (valid_key(f
.key
, sizeof(f
.key
)) == TRUE
) {
109 memset(&f
.key
, 0, sizeof(f
.key
));
110 send_cache_status_all();
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
)
126 memset(&f
, 0, sizeof(file_cache_t
));
129 gboolean
cache_add_file(const guchar
*md5file
, const guchar
*shakey
)
133 gint nfiles
= cache_file_count();
137 * Make sure there is enough secure memory.
139 if (!md5file
|| (nfiles
+ 1) * sizeof(file_cache_t
) > cache_size
)
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
));
155 pth_mutex_init(f
.mutex
);
156 memcpy(&f
.filename
, md5file
, sizeof(f
.filename
));
159 memcpy(&f
.key
, shakey
, sizeof(f
.key
));
162 f
.reset
= f
.timeout
= -2;
163 memcpy(p
, &f
, sizeof(file_cache_t
));
164 memset(&f
, 0, sizeof(file_cache_t
));
168 p
+= sizeof(file_cache_t
);
169 len
+= sizeof(file_cache_t
);
171 if (len
+ sizeof(file_cache_t
) > cache_size
)
175 memset(&f
, 0, sizeof(file_cache_t
));
179 static void reset_entry(file_cache_t
*f
)
181 pth_mutex_t
*m
= f
->mutex
;
183 if (!f
->refcount
&& m
) {
185 memset(f
, 0, sizeof(file_cache_t
));
188 memset(f
->key
, 0, sizeof(f
->key
));
191 gboolean
cache_clear(const guchar
*md5filename
, gint which
)
197 for (p
= key_cache
, len
= 0; len
<= cache_size
;) {
198 memcpy(&f
, p
, sizeof(file_cache_t
));
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) {
208 memcpy(p
, &f
, sizeof(file_cache_t
));
211 send_cache_status_all();
213 memset(&f
, 0, sizeof(file_cache_t
));
218 p
+= sizeof(file_cache_t
);
219 len
+= sizeof(file_cache_t
);
221 if (len
+ sizeof(file_cache_t
) > cache_size
)
225 memset(&f
, 0, sizeof(file_cache_t
));
228 send_cache_status_all();
235 gboolean
cache_iscached(const guchar
*md5filename
)
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
));
253 p
+= sizeof(file_cache_t
);
254 len
+= sizeof(file_cache_t
);
256 if (len
+ sizeof(file_cache_t
) > cache_size
)
260 memset(&f
, 0, sizeof(file_cache_t
));
264 gboolean
cache_reset_timeout(const guchar
*md5filename
, glong timeout
)
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) {
282 p
+= sizeof(file_cache_t
);
283 len
+= sizeof(file_cache_t
);
285 if (len
+ sizeof(file_cache_t
) > cache_size
)
289 memset(&f
, 0, sizeof(file_cache_t
));
292 return cache_set_timeout(md5filename
, timeout
);
294 return cache_set_timeout(md5filename
, t
);
297 gboolean
cache_set_timeout(const guchar
*md5filename
, glong timeout
)
303 for (p
= key_cache
, len
= 0; len
<= cache_size
;) {
304 memcpy(&f
, p
, sizeof(file_cache_t
));
307 if (memcmp((gchar
*)f
.filename
, (gchar
*)md5filename
, sizeof(f
.filename
)) == 0) {
311 f
.reset
= f
.timeout
= timeout
;
313 memcpy(p
, &f
, sizeof(file_cache_t
));
314 memset(&f
, 0, sizeof(file_cache_t
));
319 p
+= sizeof(file_cache_t
);
320 len
+= sizeof(file_cache_t
);
322 if (len
+ sizeof(file_cache_t
) > cache_size
)
326 memset(&f
, 0, sizeof(file_cache_t
));
327 return (md5filename
) ? FALSE
: TRUE
;
330 gboolean
cache_update_key(const guchar
*md5filename
, const guchar
*shakey
)
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) {
342 memcpy(&f
.key
, shakey
, sizeof(f
.key
));
344 memcpy(p
, &f
, sizeof(file_cache_t
));
345 memset(&f
, 0, sizeof(file_cache_t
));
350 p
+= sizeof(file_cache_t
);
351 len
+= sizeof(file_cache_t
);
353 if (len
+ sizeof(file_cache_t
) > cache_size
)
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
)
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
)
378 memcpy(shakey
, &f
.key
, sizeof(f
.key
));
379 memset(&f
, 0, sizeof(file_cache_t
));
384 p
+= sizeof(file_cache_t
);
385 len
+= sizeof(file_cache_t
);
387 if (len
+ sizeof(file_cache_t
) > cache_size
)
392 memset(&f
, 0, sizeof(file_cache_t
));
396 gboolean
cache_has_file(const guchar
*md5file
)
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
));
410 p
+= sizeof(file_cache_t
);
411 len
+= sizeof(file_cache_t
);
413 if (len
+ sizeof(file_cache_t
) > cache_size
)
417 memset(&f
, 0, sizeof(file_cache_t
));
421 gboolean
cache_decr_refcount(const guchar
*md5file
)
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) {
437 memcpy(p
, &f
, sizeof(file_cache_t
));
438 memset(&f
, 0, sizeof(file_cache_t
));
443 p
+= sizeof(file_cache_t
);
444 len
+= sizeof(file_cache_t
);
446 if (len
+ sizeof(file_cache_t
) > cache_size
)
450 memset(&f
, 0, sizeof(file_cache_t
));
454 gboolean
cache_incr_refcount(const guchar
*md5file
)
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) {
466 memcpy(p
, &f
, sizeof(file_cache_t
));
467 memset(&f
, 0, sizeof(file_cache_t
));
472 p
+= sizeof(file_cache_t
);
473 len
+= sizeof(file_cache_t
);
475 if (len
+ sizeof(file_cache_t
) > cache_size
)
479 memset(&f
, 0, sizeof(file_cache_t
));