Revert "Fixed a leak in cache_free()."
[pwmd.git] / src / cache.c
blobe89f5dc4ea3b34eb808deeb0efb0100a4b3a7a7e
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 02110-1301 USA
19 #include <stdio.h>
20 #include <glib.h>
21 #include <string.h>
22 #include <sys/mman.h>
23 #include <errno.h>
25 #ifdef HAVE_CONFIG_H
26 #include <config.h>
27 #endif
29 #include "status.h"
30 #include "cache.h"
31 #include "mem.h"
33 void log_write(const gchar *fmt, ...);
35 static gboolean valid_key(const guchar *key, gsize len)
37 gint b;
39 for (b = 0; b < len; b++) {
40 if (key[b])
41 return TRUE;
44 return FALSE;
47 static file_cache_t *get_entry(const guchar *md5file)
49 gint t = g_slist_length(key_cache);
50 gint i;
52 if (!md5file)
53 return NULL;
55 for (i = 0; i < t; i++) {
56 file_cache_t *p = g_slist_nth_data(key_cache, i);
58 if (!memcmp(p->filename, md5file, sizeof(p->filename)))
59 return p;
62 return NULL;
65 gboolean cache_get_mutex(const guchar *md5file, pth_mutex_t **result)
67 file_cache_t *p = get_entry(md5file);
69 if (p)
70 *result = p->mutex;
72 return p ? TRUE : FALSE;
75 gint cache_file_count()
77 gint t = g_slist_length(key_cache);
78 gint i;
79 gint n = 0;
81 for (i = 0; i < t; i++) {
82 file_cache_t *p = g_slist_nth_data(key_cache, i);
84 if (valid_key(p->key, sizeof(p->key)) == TRUE)
85 n++;
88 return n;
91 void cache_adjust_timer()
93 gint t = g_slist_length(key_cache);
94 gint i;
96 for (i = 0; i < t; i++) {
97 file_cache_t *p = g_slist_nth_data(key_cache, i);
99 if (p->reset >= 0) {
100 if (p->timeout > 0)
101 p->timeout--;
103 if (p->timeout == 0) {
104 if (valid_key(p->key, sizeof(p->key)) == TRUE) {
105 memset(&p->key, 0, sizeof(p->key));
106 send_status_all(STATUS_CACHE);
109 p->timeout = -1;
115 gboolean cache_add_file(const guchar *md5file, const guchar *shakey)
117 file_cache_t *p = g_malloc0(sizeof(file_cache_t));
118 GSList *new;
120 if (!p) {
121 log_write("%s(%i): %s", __FUNCTION__, __LINE__, strerror(ENOMEM));
122 return FALSE;
125 p->mutex = g_malloc(sizeof(pth_mutex_t));
127 if (!p->mutex) {
128 log_write("%s(%i): %s", __FUNCTION__, __LINE__, strerror(ENOMEM));
129 g_free(p);
130 return FALSE;
133 pth_mutex_init(p->mutex);
134 memcpy(p->filename, md5file, sizeof(p->filename));
136 if (shakey)
137 memcpy(p->key, shakey, sizeof(p->key));
139 p->reset = p->timeout = -2;
141 if (mlock(p, sizeof(file_cache_t)))
142 log_write("mlock(): %s", strerror(errno));
144 new = g_slist_append(key_cache, p);
146 if (!new) {
147 log_write("%s(%i): %s", __FUNCTION__, __LINE__, strerror(ENOMEM));
148 g_free(p->mutex);
149 memset(p, 0, sizeof(file_cache_t));
150 g_free(p);
151 return FALSE;
154 key_cache = new;
155 return TRUE;
158 static void free_entry(file_cache_t *p)
160 if (!p)
161 return;
163 if (p->mutex)
164 g_free(p->mutex);
166 memset(p, 0, sizeof(file_cache_t));
167 munlock(p, sizeof(file_cache_t));
168 key_cache = g_slist_remove(key_cache, p);
169 g_free(p);
172 void cache_free()
174 gint i;
176 for (i = 0; i < g_slist_length(key_cache); i++) {
177 file_cache_t *p = g_slist_nth_data(key_cache, i);
179 free_entry(p);
183 static void reset_entry(file_cache_t *p)
185 if (p && !p->refcount)
186 free_entry(p);
187 else if (p)
188 memset(p->key, 0, sizeof(p->key));
191 gboolean cache_clear(const guchar *md5file, gint which)
193 gint i, t;
194 file_cache_t *p = md5file ? get_entry(md5file) : NULL;
196 if (which == 1) {
197 if (!p)
198 return FALSE;
200 reset_entry(p);
201 p = get_entry(md5file);
202 send_status_all(STATUS_CACHE);
203 return TRUE;
206 again:
207 for (i = 0, t = cache_file_count(); i < t; i++) {
208 file_cache_t *p = g_slist_nth_data(key_cache, i);
210 reset_entry(p);
212 if (t != cache_file_count())
213 goto again;
216 send_status_all(STATUS_CACHE);
217 return TRUE;
220 gboolean cache_iscached(const guchar *md5file)
222 file_cache_t *p = get_entry(md5file);
224 return p ? valid_key(p->key, sizeof(p->key)) : FALSE;
227 gboolean cache_reset_timeout(const guchar *md5file, glong timeout)
229 file_cache_t *p = get_entry(md5file);
231 if (!p)
232 return FALSE;
234 if (p->reset == -2)
235 return cache_set_timeout(md5file, timeout);
237 return cache_set_timeout(md5file, p->reset);
240 gboolean cache_set_timeout(const guchar *md5file, glong timeout)
242 file_cache_t *p = get_entry(md5file);
244 if (!p)
245 return FALSE;
247 if (timeout == -2)
248 p->timeout = p->reset;
249 else
250 p->reset = p->timeout = timeout;
252 return TRUE;
255 gboolean cache_update_key(const guchar *md5file, const guchar *shakey)
257 file_cache_t *p = get_entry(md5file);
259 if (!p)
260 return cache_add_file(md5file, shakey);
262 if (p->reset)
263 memcpy(p->key, shakey, sizeof(p->key));
265 return TRUE;
268 gboolean cache_get_key(const guchar *md5file, guchar *shakey)
270 file_cache_t *p = get_entry(md5file);
272 if (!p || valid_key(p->key, sizeof(p->key)) == FALSE)
273 return FALSE;
275 memcpy(shakey, p->key, sizeof(p->key));
276 return TRUE;
279 gboolean cache_has_file(const guchar *md5file)
281 file_cache_t *p = get_entry(md5file);
283 return p ? TRUE : FALSE;
286 gboolean cache_decr_refcount(const guchar *md5file)
288 file_cache_t *p = get_entry(md5file);
290 if (!p)
291 return FALSE;
293 p->refcount--;
295 if (p->refcount < 0)
296 p->refcount = 0;
298 return TRUE;
301 gboolean cache_incr_refcount(const guchar *md5file)
303 file_cache_t *p = get_entry(md5file);
305 if (!p)
306 return FALSE;
308 p->refcount++;
309 return TRUE;