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