annotate src/gt_conf.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: gt_conf.c,v 1.4 2004/03/24 06:27:40 hipnod Exp $
paulo@0 3 *
paulo@0 4 * Copyright (C) 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 #include "gt_conf.h"
paulo@0 19
paulo@0 20 /*****************************************************************************/
paulo@0 21
paulo@0 22 #define CHECK_CONFIG_INTERVAL (1 * MINUTES)
paulo@0 23
paulo@0 24 /*****************************************************************************/
paulo@0 25
paulo@0 26 static Config *gt_conf;
paulo@0 27
paulo@0 28 static char *conf_path;
paulo@0 29 static time_t conf_mtime;
paulo@0 30
paulo@0 31 static Dataset *cache;
paulo@0 32
paulo@0 33 static timer_id refresh_timer;
paulo@0 34
paulo@0 35 /*****************************************************************************/
paulo@0 36
paulo@0 37 static char *get_key (const char *key_str)
paulo@0 38 {
paulo@0 39 char *str;
paulo@0 40 char *key;
paulo@0 41
paulo@0 42 if (!(str = STRDUP (key_str)))
paulo@0 43 return NULL;
paulo@0 44
paulo@0 45 key = string_sep (&str, "=");
paulo@0 46 return key;
paulo@0 47 }
paulo@0 48
paulo@0 49 static char *cache_lookup (const char *key_str)
paulo@0 50 {
paulo@0 51 char *key;
paulo@0 52 char *data;
paulo@0 53
paulo@0 54 if (!(key = get_key (key_str)))
paulo@0 55 return NULL;
paulo@0 56
paulo@0 57 data = dataset_lookupstr (cache, key);
paulo@0 58 free (key);
paulo@0 59
paulo@0 60 return data;
paulo@0 61 }
paulo@0 62
paulo@0 63 static void cache_insert (const char *key_str, const char *value)
paulo@0 64 {
paulo@0 65 char *key;
paulo@0 66
paulo@0 67 if (!(key = get_key (key_str)))
paulo@0 68 return;
paulo@0 69
paulo@0 70 dataset_insertstr (&cache, key, value);
paulo@0 71 free (key);
paulo@0 72 }
paulo@0 73
paulo@0 74 char *gt_config_get_str (const char *key)
paulo@0 75 {
paulo@0 76 char *str;
paulo@0 77 char *ret;
paulo@0 78
paulo@0 79 if (!(str = cache_lookup (key)))
paulo@0 80 str = config_get_str (gt_conf, (char *)key);
paulo@0 81
paulo@0 82 ret = str;
paulo@0 83
paulo@0 84 /* unset keys are marked specially by the empty string so
paulo@0 85 * we don't have to call config_get_xxx for them */
paulo@0 86 if (string_isempty (str))
paulo@0 87 {
paulo@0 88 ret = NULL;
paulo@0 89 str = "";
paulo@0 90 }
paulo@0 91
paulo@0 92 /* hrm, the dataset doesn't handle inserting the same item you lookup
paulo@0 93 * yet, so we can't do the insert unconditionally here.. */
paulo@0 94 if (str != cache_lookup (key))
paulo@0 95 cache_insert (key, str);
paulo@0 96
paulo@0 97 return ret;
paulo@0 98 }
paulo@0 99
paulo@0 100 int gt_config_get_int (const char *key)
paulo@0 101 {
paulo@0 102 return ATOI (gt_config_get_str (key));
paulo@0 103 }
paulo@0 104
paulo@0 105 /* check the mtime on the conf file. If it has changed, reload */
paulo@0 106 static int refresh_conf (void *udata)
paulo@0 107 {
paulo@0 108 struct stat conf_st;
paulo@0 109 char *path;
paulo@0 110 BOOL ret;
paulo@0 111
paulo@0 112 path = STRDUP (gift_conf_path (conf_path));
paulo@0 113 ret = file_stat (path, &conf_st);
paulo@0 114
paulo@0 115 if (!ret || conf_st.st_mtime != conf_mtime)
paulo@0 116 {
paulo@0 117 GT->DBGFN (GT, "Gnutella.conf changed on disk. flushing cached config");
paulo@0 118
paulo@0 119 /* gt_config_get_xxx will reload the cache */
paulo@0 120 dataset_clear (cache);
paulo@0 121 cache = NULL;
paulo@0 122
paulo@0 123 conf_mtime = conf_st.st_mtime;
paulo@0 124 }
paulo@0 125
paulo@0 126 free (path);
paulo@0 127 return TRUE;
paulo@0 128 }
paulo@0 129
paulo@0 130 BOOL gt_config_load_file (const char *relative_path, BOOL update, BOOL force)
paulo@0 131 {
paulo@0 132 char *src_path;
paulo@0 133 char *dst_path;
paulo@0 134 BOOL src_exists;
paulo@0 135 BOOL dst_exists;
paulo@0 136 struct stat src_st;
paulo@0 137 struct stat dst_st;
paulo@0 138 BOOL ret = TRUE;
paulo@0 139
paulo@0 140 src_path = STRDUP (stringf ("%s/%s", platform_data_dir(), relative_path));
paulo@0 141 dst_path = STRDUP (gift_conf_path (relative_path));
paulo@0 142
paulo@0 143 src_exists = file_stat (src_path, &src_st);
paulo@0 144 dst_exists = file_stat (dst_path, &dst_st);
paulo@0 145
paulo@0 146 /*
paulo@0 147 * NOTE: the user may modify the config files in ~/.giFT/Gnutella/.
paulo@0 148 * If so, the mtime there should be greater, so look for an mtime
paulo@0 149 * greater than instead of not equal to the those files.
paulo@0 150 */
paulo@0 151 if (force || (src_exists &&
paulo@0 152 (!dst_exists || src_st.st_mtime > dst_st.st_mtime)))
paulo@0 153 {
paulo@0 154 /*
paulo@0 155 * Copy the default configuration from the data dir
paulo@0 156 * (usually "/usr/local/share/giFT/Gnutella/")
paulo@0 157 */
paulo@0 158 GT->DBGFN (GT, "reloading configuration for %s (copying %s -> %s)",
paulo@0 159 relative_path, src_path, dst_path);
paulo@0 160 ret = file_cp (src_path, dst_path);
paulo@0 161 }
paulo@0 162
paulo@0 163 free (dst_path);
paulo@0 164 free (src_path);
paulo@0 165
paulo@0 166 return ret;
paulo@0 167 }
paulo@0 168
paulo@0 169 static Config *load_config (const char *relative_path)
paulo@0 170 {
paulo@0 171 Config *conf;
paulo@0 172 char *full_path;
paulo@0 173
paulo@0 174 full_path = STRDUP (gift_conf_path (relative_path));
paulo@0 175
paulo@0 176 if (!(conf = config_new (full_path)))
paulo@0 177 {
paulo@0 178 /* copy the configuration from the data dir */
paulo@0 179 gt_config_load_file (relative_path, TRUE, TRUE);
paulo@0 180
paulo@0 181 /* retry loading the configuration */
paulo@0 182 conf = config_new (full_path);
paulo@0 183 }
paulo@0 184
paulo@0 185 free (full_path);
paulo@0 186
paulo@0 187 return conf;
paulo@0 188 }
paulo@0 189
paulo@0 190 /*****************************************************************************/
paulo@0 191
paulo@0 192 BOOL gt_config_init (void)
paulo@0 193 {
paulo@0 194 struct stat st;
paulo@0 195
paulo@0 196 refresh_timer = timer_add (CHECK_CONFIG_INTERVAL,
paulo@0 197 (TimerCallback)refresh_conf, NULL);
paulo@0 198
paulo@0 199 conf_path = STRDUP (stringf ("%s/%s.conf", GT->name, GT->name));
paulo@0 200
paulo@0 201 if (file_stat (gift_conf_path (conf_path), &st))
paulo@0 202 conf_mtime = st.st_mtime;
paulo@0 203
paulo@0 204 gt_conf = load_config (conf_path);
paulo@0 205 cache = dataset_new (DATASET_HASH);
paulo@0 206
paulo@0 207 if (!refresh_timer || !conf_path || !gt_conf)
paulo@0 208 return FALSE;
paulo@0 209
paulo@0 210 return TRUE;
paulo@0 211 }
paulo@0 212
paulo@0 213 void gt_config_cleanup (void)
paulo@0 214 {
paulo@0 215 dataset_clear (cache);
paulo@0 216 cache = NULL;
paulo@0 217
paulo@0 218 config_free (gt_conf);
paulo@0 219 gt_conf = NULL;
paulo@0 220
paulo@0 221 free (conf_path);
paulo@0 222 conf_path = NULL;
paulo@0 223
paulo@0 224 timer_remove_zero (&refresh_timer);
paulo@0 225 }