Mercurial > hg > index.fcgi > gift-gnutella > gift-gnutella-0.0.11-1pba
diff 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 diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/file_cache.c Sat Feb 20 21:18:28 2010 -0800 1.3 @@ -0,0 +1,202 @@ 1.4 +/* 1.5 + * $Id: file_cache.c,v 1.15 2004/03/24 06:28:16 hipnod Exp $ 1.6 + * 1.7 + * Copyright (C) 2001-2003 giFT project (gift.sourceforge.net) 1.8 + * 1.9 + * This program is free software; you can redistribute it and/or modify it 1.10 + * under the terms of the GNU General Public License as published by the 1.11 + * Free Software Foundation; either version 2, or (at your option) any 1.12 + * later version. 1.13 + * 1.14 + * This program is distributed in the hope that it will be useful, but 1.15 + * WITHOUT ANY WARRANTY; without even the implied warranty of 1.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 1.17 + * General Public License for more details. 1.18 + */ 1.19 + 1.20 +#include "gt_gnutella.h" 1.21 + 1.22 +#include "file_cache.h" 1.23 + 1.24 +/*****************************************************************************/ 1.25 + 1.26 +FileCache *file_cache_new (const char *file) 1.27 +{ 1.28 + FileCache *file_cache; 1.29 + 1.30 + if (!(file_cache = malloc (sizeof (FileCache)))) 1.31 + return NULL; 1.32 + 1.33 + memset (file_cache, 0, sizeof (FileCache)); 1.34 + 1.35 + file_cache->file = STRDUP (file); 1.36 + 1.37 + if (!file_cache_load (file_cache)) 1.38 + GT->DBGFN (GT, "failed loading %s", file); 1.39 + 1.40 + return file_cache; 1.41 +} 1.42 + 1.43 +void file_cache_free (FileCache *cache) 1.44 +{ 1.45 + if (!cache) 1.46 + return; 1.47 + 1.48 + dataset_clear (cache->d); 1.49 + 1.50 + free (cache->file); 1.51 + free (cache); 1.52 +} 1.53 + 1.54 +/*****************************************************************************/ 1.55 + 1.56 +int file_cache_load (FileCache *cache) 1.57 +{ 1.58 + struct stat st; 1.59 + time_t mtime; 1.60 + char *line = NULL; 1.61 + FILE *f; 1.62 + int nlines; 1.63 + 1.64 + if (!cache) 1.65 + return FALSE; 1.66 + 1.67 + if (!(f = fopen (cache->file, "r"))) 1.68 + { 1.69 + GT->DBGFN (GT, "couldnt open %s for reading: %s", cache->file, 1.70 + GIFT_STRERROR ()); 1.71 + return FALSE; 1.72 + } 1.73 + 1.74 + mtime = 0; 1.75 + 1.76 + if (file_stat (cache->file, &st)) 1.77 + mtime = st.st_mtime; 1.78 + 1.79 + dataset_clear (cache->d); 1.80 + 1.81 + cache->d = dataset_new (DATASET_HASH); 1.82 + cache->mtime = mtime; 1.83 + 1.84 + nlines = 0; 1.85 + 1.86 + while (file_read_line (f, &line)) 1.87 + { 1.88 + char *key; 1.89 + char *value = line; 1.90 + 1.91 + key = string_sep (&value, " "); 1.92 + 1.93 + string_trim (key); 1.94 + string_trim (value); 1.95 + 1.96 + if (!key) 1.97 + continue; 1.98 + 1.99 + if (!value) 1.100 + value = ""; 1.101 + 1.102 + dataset_insertstr (&cache->d, key, value); 1.103 + 1.104 + nlines++; 1.105 + } 1.106 + 1.107 + if (fclose (f) != 0) 1.108 + return FALSE; 1.109 + 1.110 + GT->DBGFN (GT, "loaded filecache for %s. nlines = %i", cache->file, nlines); 1.111 + return TRUE; 1.112 +} 1.113 + 1.114 +static void sync_one (ds_data_t *key, ds_data_t *value, String *s) 1.115 +{ 1.116 + char *keystr = key->data; 1.117 + char *valuestr = value->data; 1.118 + 1.119 + string_appendf (s, "%s %s\n", keystr, valuestr); 1.120 +} 1.121 + 1.122 +BOOL file_cache_sync (FileCache *cache) 1.123 +{ 1.124 + FILE *f; 1.125 + String *s; 1.126 + char tmp_path[PATH_MAX]; 1.127 + 1.128 + if (!cache) 1.129 + return FALSE; 1.130 + 1.131 + snprintf (tmp_path, sizeof (tmp_path), "%s.tmp", cache->file); 1.132 + 1.133 + if (!(s = string_new (NULL, 0, 0, TRUE))) 1.134 + return FALSE; 1.135 + 1.136 + if (!(f = fopen (tmp_path, "w"))) 1.137 + { 1.138 + GT->DBGFN (GT, "couldnt write to %s: %s", tmp_path, GIFT_STRERROR ()); 1.139 + string_free (s); 1.140 + return FALSE; 1.141 + } 1.142 + 1.143 + GT->DBGFN (GT, "syncing %s to disk", tmp_path); 1.144 + 1.145 + dataset_foreach (cache->d, DS_FOREACH(sync_one), s); 1.146 + 1.147 + if (fwrite (s->str, 1, s->len, f) != s->len) 1.148 + { 1.149 + GT->DBGFN (GT, "failed writing %s: %s", tmp_path, GIFT_STRERROR()); 1.150 + string_free (s); 1.151 + fclose (f); 1.152 + return FALSE; 1.153 + } 1.154 + 1.155 + string_free (s); 1.156 + 1.157 + if (fclose (f) != 0) 1.158 + { 1.159 + GT->DBGFN (GT, "failed closing %s: %s", tmp_path, GIFT_STRERROR()); 1.160 + return FALSE; 1.161 + } 1.162 + 1.163 + if (!file_mv (tmp_path, cache->file)) 1.164 + { 1.165 + GT->DBGFN (GT, "file move %s -> %s failed", tmp_path, cache->file); 1.166 + return FALSE; 1.167 + } 1.168 + 1.169 + return TRUE; 1.170 +} 1.171 + 1.172 +void file_cache_flush (FileCache *cache) 1.173 +{ 1.174 + if (!cache) 1.175 + return; 1.176 + 1.177 + dataset_clear (cache->d); 1.178 + cache->d = NULL; 1.179 +} 1.180 + 1.181 +/*****************************************************************************/ 1.182 + 1.183 +char *file_cache_lookup (FileCache *cache, const char *key) 1.184 +{ 1.185 + if (!cache) 1.186 + return NULL; 1.187 + 1.188 + return dataset_lookupstr (cache->d, key); 1.189 +} 1.190 + 1.191 +void file_cache_insert (FileCache *cache, const char *key, const char *value) 1.192 +{ 1.193 + if (!cache) 1.194 + return; 1.195 + 1.196 + dataset_insertstr (&cache->d, key, value); 1.197 +} 1.198 + 1.199 +void file_cache_remove (FileCache *cache, const char *key) 1.200 +{ 1.201 + if (!cache) 1.202 + return; 1.203 + 1.204 + dataset_removestr (cache->d, key); 1.205 +}