diff 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
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/src/gt_conf.c	Sat Feb 20 21:18:28 2010 -0800
     1.3 @@ -0,0 +1,225 @@
     1.4 +/*
     1.5 + * $Id: gt_conf.c,v 1.4 2004/03/24 06:27:40 hipnod Exp $
     1.6 + *
     1.7 + * Copyright (C) 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 +#include "gt_conf.h"
    1.22 +
    1.23 +/*****************************************************************************/
    1.24 +
    1.25 +#define CHECK_CONFIG_INTERVAL       (1 * MINUTES)
    1.26 +
    1.27 +/*****************************************************************************/
    1.28 +
    1.29 +static Config     *gt_conf;
    1.30 +
    1.31 +static char       *conf_path;
    1.32 +static time_t      conf_mtime;
    1.33 +
    1.34 +static Dataset    *cache;
    1.35 +
    1.36 +static timer_id    refresh_timer;
    1.37 +
    1.38 +/*****************************************************************************/
    1.39 +
    1.40 +static char *get_key (const char *key_str)
    1.41 +{
    1.42 +	char *str;
    1.43 +	char *key;
    1.44 +
    1.45 +	if (!(str = STRDUP (key_str)))
    1.46 +		return NULL;
    1.47 +
    1.48 +	key = string_sep (&str, "=");
    1.49 +	return key;
    1.50 +}
    1.51 +
    1.52 +static char *cache_lookup (const char *key_str)
    1.53 +{
    1.54 +	char *key;
    1.55 +	char *data;
    1.56 +
    1.57 +	if (!(key = get_key (key_str)))
    1.58 +		return NULL;
    1.59 +
    1.60 +	data = dataset_lookupstr (cache, key);
    1.61 +	free (key);
    1.62 +
    1.63 +	return data;
    1.64 +}
    1.65 +
    1.66 +static void cache_insert (const char *key_str, const char *value)
    1.67 +{
    1.68 +	char *key;
    1.69 +
    1.70 +	if (!(key = get_key (key_str)))
    1.71 +		return;
    1.72 +
    1.73 +	dataset_insertstr (&cache, key, value);
    1.74 +	free (key);
    1.75 +}
    1.76 +
    1.77 +char *gt_config_get_str (const char *key)
    1.78 +{
    1.79 +	char *str;
    1.80 +	char *ret;
    1.81 +
    1.82 +	if (!(str = cache_lookup (key)))
    1.83 +		str = config_get_str (gt_conf, (char *)key);
    1.84 +
    1.85 +	ret = str;
    1.86 +
    1.87 +	/* unset keys are marked specially by the empty string so
    1.88 +	 * we don't have to call config_get_xxx for them */
    1.89 +	if (string_isempty (str))
    1.90 +	{
    1.91 +		ret = NULL;
    1.92 +		str = "";
    1.93 +	}
    1.94 +
    1.95 +	/* hrm, the dataset doesn't handle inserting the same item you lookup
    1.96 +	 * yet, so we can't do the insert unconditionally here.. */
    1.97 +	if (str != cache_lookup (key))
    1.98 +		cache_insert (key, str);
    1.99 +
   1.100 +	return ret;
   1.101 +}
   1.102 +
   1.103 +int gt_config_get_int (const char *key)
   1.104 +{
   1.105 +	return ATOI (gt_config_get_str (key));
   1.106 +}
   1.107 +
   1.108 +/* check the mtime on the conf file. If it has changed, reload */
   1.109 +static int refresh_conf (void *udata)
   1.110 +{
   1.111 +	struct stat  conf_st;
   1.112 +	char        *path;
   1.113 +	BOOL         ret;
   1.114 +
   1.115 +	path = STRDUP (gift_conf_path (conf_path));
   1.116 +	ret = file_stat (path, &conf_st);
   1.117 +
   1.118 +	if (!ret || conf_st.st_mtime != conf_mtime)
   1.119 +	{
   1.120 +		GT->DBGFN (GT, "Gnutella.conf changed on disk. flushing cached config");
   1.121 +
   1.122 +		/* gt_config_get_xxx will reload the cache */
   1.123 +		dataset_clear (cache);
   1.124 +		cache = NULL;
   1.125 +
   1.126 +		conf_mtime = conf_st.st_mtime;
   1.127 +	}
   1.128 +
   1.129 +	free (path);
   1.130 +	return TRUE;
   1.131 +}
   1.132 +
   1.133 +BOOL gt_config_load_file (const char *relative_path, BOOL update, BOOL force)
   1.134 +{
   1.135 +	char        *src_path;
   1.136 +	char        *dst_path;
   1.137 +	BOOL         src_exists;
   1.138 +	BOOL         dst_exists;
   1.139 +	struct stat  src_st;
   1.140 +	struct stat  dst_st;
   1.141 +	BOOL         ret        = TRUE;
   1.142 +
   1.143 +	src_path = STRDUP (stringf ("%s/%s", platform_data_dir(), relative_path));
   1.144 +	dst_path = STRDUP (gift_conf_path (relative_path));
   1.145 +
   1.146 +	src_exists = file_stat (src_path, &src_st);
   1.147 +	dst_exists = file_stat (dst_path, &dst_st);
   1.148 +
   1.149 +	/* 
   1.150 +	 * NOTE: the user may modify the config files in ~/.giFT/Gnutella/.
   1.151 +	 * If so, the mtime there should be greater, so look for an mtime
   1.152 +	 * greater than instead of not equal to the those files. 
   1.153 +	 */
   1.154 +	if (force || (src_exists && 
   1.155 +	              (!dst_exists || src_st.st_mtime > dst_st.st_mtime)))
   1.156 +	{
   1.157 +		/* 
   1.158 +		 * Copy the default configuration from the data dir
   1.159 +		 * (usually "/usr/local/share/giFT/Gnutella/") 
   1.160 +		 */
   1.161 +		GT->DBGFN (GT, "reloading configuration for %s (copying %s -> %s)", 
   1.162 +		           relative_path, src_path, dst_path);
   1.163 +		ret = file_cp (src_path, dst_path);
   1.164 +	}
   1.165 +
   1.166 +	free (dst_path);
   1.167 +	free (src_path);
   1.168 +
   1.169 +	return ret;
   1.170 +}
   1.171 +
   1.172 +static Config *load_config (const char *relative_path)
   1.173 +{
   1.174 +	Config  *conf;
   1.175 +	char    *full_path;
   1.176 +
   1.177 +	full_path = STRDUP (gift_conf_path (relative_path));
   1.178 +
   1.179 +	if (!(conf = config_new (full_path)))
   1.180 +	{
   1.181 +		/* copy the configuration from the data dir */
   1.182 +		gt_config_load_file (relative_path, TRUE, TRUE);
   1.183 +
   1.184 +		/* retry loading the configuration */
   1.185 +		conf = config_new (full_path);
   1.186 +	}
   1.187 +
   1.188 +	free (full_path);
   1.189 +
   1.190 +	return conf;
   1.191 +}
   1.192 +
   1.193 +/*****************************************************************************/
   1.194 +
   1.195 +BOOL gt_config_init (void)
   1.196 +{
   1.197 +	struct stat st;
   1.198 +
   1.199 +	refresh_timer = timer_add (CHECK_CONFIG_INTERVAL, 
   1.200 +	                           (TimerCallback)refresh_conf, NULL);
   1.201 +
   1.202 +	conf_path = STRDUP (stringf ("%s/%s.conf", GT->name, GT->name));
   1.203 +
   1.204 +	if (file_stat (gift_conf_path (conf_path), &st))
   1.205 +	    conf_mtime = st.st_mtime;
   1.206 +
   1.207 +	gt_conf = load_config (conf_path);
   1.208 +	cache = dataset_new (DATASET_HASH);
   1.209 +
   1.210 +	if (!refresh_timer || !conf_path || !gt_conf)
   1.211 +		return FALSE;
   1.212 +
   1.213 +	return TRUE;
   1.214 +}
   1.215 +
   1.216 +void gt_config_cleanup (void)
   1.217 +{
   1.218 +	dataset_clear (cache);
   1.219 +	cache = NULL;
   1.220 +
   1.221 +	config_free (gt_conf);
   1.222 +	gt_conf = NULL;
   1.223 +
   1.224 +	free (conf_path);
   1.225 +	conf_path = NULL;
   1.226 +
   1.227 +	timer_remove_zero (&refresh_timer);
   1.228 +}