Mercurial > hg > index.fcgi > gift-gnutella > gift-gnutella-0.0.11-1pba
comparison 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 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:6c738d812746 |
---|---|
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 */ | |
16 | |
17 #include "gt_gnutella.h" | |
18 | |
19 #include "file_cache.h" | |
20 | |
21 /*****************************************************************************/ | |
22 | |
23 FileCache *file_cache_new (const char *file) | |
24 { | |
25 FileCache *file_cache; | |
26 | |
27 if (!(file_cache = malloc (sizeof (FileCache)))) | |
28 return NULL; | |
29 | |
30 memset (file_cache, 0, sizeof (FileCache)); | |
31 | |
32 file_cache->file = STRDUP (file); | |
33 | |
34 if (!file_cache_load (file_cache)) | |
35 GT->DBGFN (GT, "failed loading %s", file); | |
36 | |
37 return file_cache; | |
38 } | |
39 | |
40 void file_cache_free (FileCache *cache) | |
41 { | |
42 if (!cache) | |
43 return; | |
44 | |
45 dataset_clear (cache->d); | |
46 | |
47 free (cache->file); | |
48 free (cache); | |
49 } | |
50 | |
51 /*****************************************************************************/ | |
52 | |
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; | |
60 | |
61 if (!cache) | |
62 return FALSE; | |
63 | |
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 } | |
70 | |
71 mtime = 0; | |
72 | |
73 if (file_stat (cache->file, &st)) | |
74 mtime = st.st_mtime; | |
75 | |
76 dataset_clear (cache->d); | |
77 | |
78 cache->d = dataset_new (DATASET_HASH); | |
79 cache->mtime = mtime; | |
80 | |
81 nlines = 0; | |
82 | |
83 while (file_read_line (f, &line)) | |
84 { | |
85 char *key; | |
86 char *value = line; | |
87 | |
88 key = string_sep (&value, " "); | |
89 | |
90 string_trim (key); | |
91 string_trim (value); | |
92 | |
93 if (!key) | |
94 continue; | |
95 | |
96 if (!value) | |
97 value = ""; | |
98 | |
99 dataset_insertstr (&cache->d, key, value); | |
100 | |
101 nlines++; | |
102 } | |
103 | |
104 if (fclose (f) != 0) | |
105 return FALSE; | |
106 | |
107 GT->DBGFN (GT, "loaded filecache for %s. nlines = %i", cache->file, nlines); | |
108 return TRUE; | |
109 } | |
110 | |
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; | |
115 | |
116 string_appendf (s, "%s %s\n", keystr, valuestr); | |
117 } | |
118 | |
119 BOOL file_cache_sync (FileCache *cache) | |
120 { | |
121 FILE *f; | |
122 String *s; | |
123 char tmp_path[PATH_MAX]; | |
124 | |
125 if (!cache) | |
126 return FALSE; | |
127 | |
128 snprintf (tmp_path, sizeof (tmp_path), "%s.tmp", cache->file); | |
129 | |
130 if (!(s = string_new (NULL, 0, 0, TRUE))) | |
131 return FALSE; | |
132 | |
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 } | |
139 | |
140 GT->DBGFN (GT, "syncing %s to disk", tmp_path); | |
141 | |
142 dataset_foreach (cache->d, DS_FOREACH(sync_one), s); | |
143 | |
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 } | |
151 | |
152 string_free (s); | |
153 | |
154 if (fclose (f) != 0) | |
155 { | |
156 GT->DBGFN (GT, "failed closing %s: %s", tmp_path, GIFT_STRERROR()); | |
157 return FALSE; | |
158 } | |
159 | |
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 } | |
165 | |
166 return TRUE; | |
167 } | |
168 | |
169 void file_cache_flush (FileCache *cache) | |
170 { | |
171 if (!cache) | |
172 return; | |
173 | |
174 dataset_clear (cache->d); | |
175 cache->d = NULL; | |
176 } | |
177 | |
178 /*****************************************************************************/ | |
179 | |
180 char *file_cache_lookup (FileCache *cache, const char *key) | |
181 { | |
182 if (!cache) | |
183 return NULL; | |
184 | |
185 return dataset_lookupstr (cache->d, key); | |
186 } | |
187 | |
188 void file_cache_insert (FileCache *cache, const char *key, const char *value) | |
189 { | |
190 if (!cache) | |
191 return; | |
192 | |
193 dataset_insertstr (&cache->d, key, value); | |
194 } | |
195 | |
196 void file_cache_remove (FileCache *cache, const char *key) | |
197 { | |
198 if (!cache) | |
199 return; | |
200 | |
201 dataset_removestr (cache->d, key); | |
202 } |