annotate 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
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 }