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 02110-1301 USA
31 static gboolean
valid_key(const guchar
*key
, gsize len
)
35 for (b
= 0; b
< len
; b
++) {
43 gboolean
cache_get_mutex(const guchar
*md5filename
, pth_mutex_t
**result
)
49 for (p
= key_cache
, len
= 0; len
<= cache_size
;) {
50 memcpy(&f
, p
, sizeof(file_cache_t
));
53 if (memcmp(&f
.filename
, md5filename
, sizeof(f
.filename
)) == 0) {
55 memset(&f
, 0, sizeof(file_cache_t
));
56 return *result
? TRUE
: FALSE
;
60 p
+= sizeof(file_cache_t
);
61 len
+= sizeof(file_cache_t
);
63 if (len
+ sizeof(file_cache_t
) > cache_size
)
67 memset(&f
, 0, sizeof(file_cache_t
));
71 gint
cache_file_count()
78 for (p
= key_cache
, len
= 0; len
<= cache_size
;) {
79 memcpy(&f
, p
, sizeof(file_cache_t
));
81 if (f
.used
== TRUE
&& valid_key(f
.key
, sizeof(f
.key
)) == TRUE
)
84 p
+= sizeof(file_cache_t
);
85 len
+= sizeof(file_cache_t
);
87 if (len
+ sizeof(file_cache_t
) > cache_size
)
91 memset(&f
, 0, sizeof(file_cache_t
));
95 void cache_adjust_timer()
101 for (p
= key_cache
, len
= 0; len
<= cache_size
;) {
102 memcpy(&f
, p
, sizeof(file_cache_t
));
104 if (f
.used
== TRUE
&& f
.reset
>= 0) {
108 if (f
.timeout
== 0) {
109 if (valid_key(f
.key
, sizeof(f
.key
)) == TRUE
) {
110 memset(&f
.key
, 0, sizeof(f
.key
));
111 send_status_all(STATUS_CACHE
);
117 memcpy(p
, &f
, sizeof(file_cache_t
));
120 p
+= sizeof(file_cache_t
);
121 len
+= sizeof(file_cache_t
);
123 if (len
+ sizeof(file_cache_t
) > cache_size
)
127 memset(&f
, 0, sizeof(file_cache_t
));
130 gboolean
cache_add_file(const guchar
*md5file
, const guchar
*shakey
)
134 gint nfiles
= cache_file_count();
138 * Make sure there is enough secure memory.
140 if (!md5file
|| (nfiles
+ 1) * sizeof(file_cache_t
) > cache_size
)
144 * Find the first available "slot".
146 for (p
= key_cache
, len
= 0; len
<= cache_size
;) {
147 memcpy(&f
, p
, sizeof(file_cache_t
));
149 if (f
.used
== FALSE
) {
150 memset(&f
, 0, sizeof(file_cache_t
));
151 f
.mutex
= xmalloc(sizeof(pth_mutex_t
));
156 pth_mutex_init(f
.mutex
);
157 memcpy(&f
.filename
, md5file
, sizeof(f
.filename
));
160 memcpy(&f
.key
, shakey
, sizeof(f
.key
));
163 f
.reset
= f
.timeout
= -2;
164 memcpy(p
, &f
, sizeof(file_cache_t
));
165 memset(&f
, 0, sizeof(file_cache_t
));
169 p
+= sizeof(file_cache_t
);
170 len
+= sizeof(file_cache_t
);
172 if (len
+ sizeof(file_cache_t
) > cache_size
)
176 memset(&f
, 0, sizeof(file_cache_t
));
180 static void reset_entry(file_cache_t
*f
)
182 pth_mutex_t
*m
= f
->mutex
;
184 if (!f
->refcount
&& m
) {
186 memset(f
, 0, sizeof(file_cache_t
));
189 memset(f
->key
, 0, sizeof(f
->key
));
192 gboolean
cache_clear(const guchar
*md5filename
, gint which
)
198 for (p
= key_cache
, len
= 0; len
<= cache_size
;) {
199 memcpy(&f
, p
, sizeof(file_cache_t
));
203 memcpy(p
, &f
, sizeof(file_cache_t
));
204 memset(&f
, 0, sizeof(file_cache_t
));
206 else if (f
.used
== TRUE
&& which
== 1) {
207 if (memcmp(&f
.filename
, md5filename
, sizeof(f
.filename
)) == 0) {
209 memcpy(p
, &f
, sizeof(file_cache_t
));
212 send_status_all(STATUS_CACHE
);
214 memset(&f
, 0, sizeof(file_cache_t
));
219 p
+= sizeof(file_cache_t
);
220 len
+= sizeof(file_cache_t
);
222 if (len
+ sizeof(file_cache_t
) > cache_size
)
226 memset(&f
, 0, sizeof(file_cache_t
));
229 send_status_all(STATUS_CACHE
);
236 gboolean
cache_iscached(const guchar
*md5filename
)
241 gboolean ret
= FALSE
;
243 for (p
= key_cache
, len
= 0; len
<= cache_size
;) {
244 memcpy(&f
, p
, sizeof(file_cache_t
));
246 if (f
.used
== TRUE
) {
247 if (memcmp(&f
.filename
, md5filename
, sizeof(f
.filename
)) == 0) {
248 ret
= valid_key(f
.key
, sizeof(f
.key
));
249 memset(&f
, 0, sizeof(file_cache_t
));
254 p
+= sizeof(file_cache_t
);
255 len
+= sizeof(file_cache_t
);
257 if (len
+ sizeof(file_cache_t
) > cache_size
)
261 memset(&f
, 0, sizeof(file_cache_t
));
265 gboolean
cache_reset_timeout(const guchar
*md5filename
, glong timeout
)
275 for (p
= key_cache
, len
= 0; len
<= cache_size
;) {
276 memcpy(&f
, p
, sizeof(file_cache_t
));
278 if (memcmp((gchar
*)f
.filename
, (gchar
*)md5filename
, sizeof(f
.filename
)) == 0) {
283 p
+= sizeof(file_cache_t
);
284 len
+= sizeof(file_cache_t
);
286 if (len
+ sizeof(file_cache_t
) > cache_size
)
290 memset(&f
, 0, sizeof(file_cache_t
));
293 return cache_set_timeout(md5filename
, timeout
);
295 return cache_set_timeout(md5filename
, t
);
298 gboolean
cache_set_timeout(const guchar
*md5filename
, glong timeout
)
304 for (p
= key_cache
, len
= 0; len
<= cache_size
;) {
305 memcpy(&f
, p
, sizeof(file_cache_t
));
308 if (memcmp((gchar
*)f
.filename
, (gchar
*)md5filename
, sizeof(f
.filename
)) == 0) {
312 f
.reset
= f
.timeout
= timeout
;
314 memcpy(p
, &f
, sizeof(file_cache_t
));
315 memset(&f
, 0, sizeof(file_cache_t
));
320 p
+= sizeof(file_cache_t
);
321 len
+= sizeof(file_cache_t
);
323 if (len
+ sizeof(file_cache_t
) > cache_size
)
327 memset(&f
, 0, sizeof(file_cache_t
));
328 return (md5filename
) ? FALSE
: TRUE
;
331 gboolean
cache_update_key(const guchar
*md5filename
, const guchar
*shakey
)
337 for (p
= key_cache
, len
= 0; len
<= cache_size
;) {
338 memcpy(&f
, p
, sizeof(file_cache_t
));
340 if (f
.used
== TRUE
) {
341 if (memcmp((gchar
*)f
.filename
, (gchar
*)md5filename
, sizeof(f
.filename
)) == 0) {
343 memcpy(&f
.key
, shakey
, sizeof(f
.key
));
345 memcpy(p
, &f
, sizeof(file_cache_t
));
346 memset(&f
, 0, sizeof(file_cache_t
));
351 p
+= sizeof(file_cache_t
);
352 len
+= sizeof(file_cache_t
);
354 if (len
+ sizeof(file_cache_t
) > cache_size
)
358 memset(&f
, 0, sizeof(file_cache_t
));
359 return cache_add_file(md5filename
, shakey
);
362 gboolean
cache_get_key(const guchar
*md5file
, guchar
*shakey
)
368 for (p
= key_cache
, len
= 0; len
<= cache_size
;) {
369 memcpy(&f
, p
, sizeof(file_cache_t
));
372 * The slot may be used but not yet contain a key.
374 if (f
.used
== TRUE
) {
375 if (memcmp(&f
.filename
, md5file
, sizeof(f
.filename
)) == 0) {
376 if (valid_key(f
.key
, sizeof(f
.key
)) == FALSE
)
379 memcpy(shakey
, &f
.key
, sizeof(f
.key
));
380 memset(&f
, 0, sizeof(file_cache_t
));
385 p
+= sizeof(file_cache_t
);
386 len
+= sizeof(file_cache_t
);
388 if (len
+ sizeof(file_cache_t
) > cache_size
)
393 memset(&f
, 0, sizeof(file_cache_t
));
397 gboolean
cache_has_file(const guchar
*md5file
)
403 for (p
= key_cache
, len
= 0; len
<= cache_size
;) {
404 memcpy(&f
, p
, sizeof(file_cache_t
));
406 if (memcmp(&f
.filename
, md5file
, sizeof(f
.filename
)) == 0) {
407 memset(&f
, 0, sizeof(file_cache_t
));
411 p
+= sizeof(file_cache_t
);
412 len
+= sizeof(file_cache_t
);
414 if (len
+ sizeof(file_cache_t
) > cache_size
)
418 memset(&f
, 0, sizeof(file_cache_t
));
422 gboolean
cache_decr_refcount(const guchar
*md5file
)
428 for (p
= key_cache
, len
= 0; len
<= cache_size
;) {
429 memcpy(&f
, p
, sizeof(file_cache_t
));
431 if (f
.used
== TRUE
) {
432 if (memcmp(&f
.filename
, md5file
, sizeof(f
.filename
)) == 0) {
438 memcpy(p
, &f
, sizeof(file_cache_t
));
439 memset(&f
, 0, sizeof(file_cache_t
));
444 p
+= sizeof(file_cache_t
);
445 len
+= sizeof(file_cache_t
);
447 if (len
+ sizeof(file_cache_t
) > cache_size
)
451 memset(&f
, 0, sizeof(file_cache_t
));
455 gboolean
cache_incr_refcount(const guchar
*md5file
)
461 for (p
= key_cache
, len
= 0; len
<= cache_size
;) {
462 memcpy(&f
, p
, sizeof(file_cache_t
));
464 if (f
.used
== TRUE
) {
465 if (memcmp(&f
.filename
, md5file
, sizeof(f
.filename
)) == 0) {
467 memcpy(p
, &f
, sizeof(file_cache_t
));
468 memset(&f
, 0, sizeof(file_cache_t
));
473 p
+= sizeof(file_cache_t
);
474 len
+= sizeof(file_cache_t
);
476 if (len
+ sizeof(file_cache_t
) > cache_size
)
480 memset(&f
, 0, sizeof(file_cache_t
));