view src/file_cache.c @ 0:d39e1d0d75b6

initial add
author paulo@hit-nxdomain.opendns.com
date Sat, 20 Feb 2010 21:18:28 -0800
parents
children
line source
1 /*
2 * $Id: file_cache.c,v 1.15 2004/03/24 06:28:16 hipnod Exp $
3 *
4 * Copyright (C) 2001-2003 giFT project (gift.sourceforge.net)
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2, or (at your option) any
9 * later version.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 */
17 #include "gt_gnutella.h"
19 #include "file_cache.h"
21 /*****************************************************************************/
23 FileCache *file_cache_new (const char *file)
24 {
25 FileCache *file_cache;
27 if (!(file_cache = malloc (sizeof (FileCache))))
28 return NULL;
30 memset (file_cache, 0, sizeof (FileCache));
32 file_cache->file = STRDUP (file);
34 if (!file_cache_load (file_cache))
35 GT->DBGFN (GT, "failed loading %s", file);
37 return file_cache;
38 }
40 void file_cache_free (FileCache *cache)
41 {
42 if (!cache)
43 return;
45 dataset_clear (cache->d);
47 free (cache->file);
48 free (cache);
49 }
51 /*****************************************************************************/
53 int file_cache_load (FileCache *cache)
54 {
55 struct stat st;
56 time_t mtime;
57 char *line = NULL;
58 FILE *f;
59 int nlines;
61 if (!cache)
62 return FALSE;
64 if (!(f = fopen (cache->file, "r")))
65 {
66 GT->DBGFN (GT, "couldnt open %s for reading: %s", cache->file,
67 GIFT_STRERROR ());
68 return FALSE;
69 }
71 mtime = 0;
73 if (file_stat (cache->file, &st))
74 mtime = st.st_mtime;
76 dataset_clear (cache->d);
78 cache->d = dataset_new (DATASET_HASH);
79 cache->mtime = mtime;
81 nlines = 0;
83 while (file_read_line (f, &line))
84 {
85 char *key;
86 char *value = line;
88 key = string_sep (&value, " ");
90 string_trim (key);
91 string_trim (value);
93 if (!key)
94 continue;
96 if (!value)
97 value = "";
99 dataset_insertstr (&cache->d, key, value);
101 nlines++;
102 }
104 if (fclose (f) != 0)
105 return FALSE;
107 GT->DBGFN (GT, "loaded filecache for %s. nlines = %i", cache->file, nlines);
108 return TRUE;
109 }
111 static void sync_one (ds_data_t *key, ds_data_t *value, String *s)
112 {
113 char *keystr = key->data;
114 char *valuestr = value->data;
116 string_appendf (s, "%s %s\n", keystr, valuestr);
117 }
119 BOOL file_cache_sync (FileCache *cache)
120 {
121 FILE *f;
122 String *s;
123 char tmp_path[PATH_MAX];
125 if (!cache)
126 return FALSE;
128 snprintf (tmp_path, sizeof (tmp_path), "%s.tmp", cache->file);
130 if (!(s = string_new (NULL, 0, 0, TRUE)))
131 return FALSE;
133 if (!(f = fopen (tmp_path, "w")))
134 {
135 GT->DBGFN (GT, "couldnt write to %s: %s", tmp_path, GIFT_STRERROR ());
136 string_free (s);
137 return FALSE;
138 }
140 GT->DBGFN (GT, "syncing %s to disk", tmp_path);
142 dataset_foreach (cache->d, DS_FOREACH(sync_one), s);
144 if (fwrite (s->str, 1, s->len, f) != s->len)
145 {
146 GT->DBGFN (GT, "failed writing %s: %s", tmp_path, GIFT_STRERROR());
147 string_free (s);
148 fclose (f);
149 return FALSE;
150 }
152 string_free (s);
154 if (fclose (f) != 0)
155 {
156 GT->DBGFN (GT, "failed closing %s: %s", tmp_path, GIFT_STRERROR());
157 return FALSE;
158 }
160 if (!file_mv (tmp_path, cache->file))
161 {
162 GT->DBGFN (GT, "file move %s -> %s failed", tmp_path, cache->file);
163 return FALSE;
164 }
166 return TRUE;
167 }
169 void file_cache_flush (FileCache *cache)
170 {
171 if (!cache)
172 return;
174 dataset_clear (cache->d);
175 cache->d = NULL;
176 }
178 /*****************************************************************************/
180 char *file_cache_lookup (FileCache *cache, const char *key)
181 {
182 if (!cache)
183 return NULL;
185 return dataset_lookupstr (cache->d, key);
186 }
188 void file_cache_insert (FileCache *cache, const char *key, const char *value)
189 {
190 if (!cache)
191 return;
193 dataset_insertstr (&cache->d, key, value);
194 }
196 void file_cache_remove (FileCache *cache, const char *key)
197 {
198 if (!cache)
199 return;
201 dataset_removestr (cache->d, key);
202 }