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