mirror of https://github.com/BOINC/boinc.git
313 lines
5.8 KiB
C
313 lines
5.8 KiB
C
/*
|
|
* cfg-client.c
|
|
*
|
|
* Simple config file parser for the client
|
|
*/
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
#include <config.h>
|
|
#endif
|
|
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
#include <dc.h>
|
|
#include <dc_internal.h>
|
|
|
|
#include <glib.h>
|
|
|
|
/********************************************************************
|
|
* Constants
|
|
*/
|
|
|
|
/* Name of the group holding the master's configuration */
|
|
#define MASTER_GROUP "Master"
|
|
|
|
|
|
/********************************************************************
|
|
* Global variables
|
|
*/
|
|
|
|
static GKeyFile *config;
|
|
|
|
|
|
/********************************************************************
|
|
* Implementation
|
|
*/
|
|
|
|
int _DC_parseCfg(const char *cfgfile)
|
|
{
|
|
GError *error = NULL;
|
|
int ret;
|
|
|
|
/* Should not happen */
|
|
if (!cfgfile)
|
|
return DC_ERR_INTERNAL;
|
|
|
|
config = g_key_file_new();
|
|
ret = g_key_file_load_from_file(config, cfgfile, G_KEY_FILE_NONE,
|
|
&error);
|
|
if (!ret)
|
|
{
|
|
DC_log(LOG_ERR, "Failed to load the config file %s: %s",
|
|
cfgfile, error->message);
|
|
g_error_free(error);
|
|
return DC_ERR_CONFIG;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
static char *getCfgStr(const char *group, const char *key)
|
|
{
|
|
char *value, *tmp;
|
|
|
|
if (!config || !key)
|
|
return NULL;
|
|
|
|
value = g_key_file_get_value(config, group, key, NULL);
|
|
if (!value || g_mem_is_system_malloc())
|
|
return value;
|
|
tmp = strdup(value);
|
|
g_free(value);
|
|
return tmp;
|
|
}
|
|
|
|
static int getCfgInt(const char *group, const char *key, int defaultValue,
|
|
int *err)
|
|
{
|
|
char *value, *p;
|
|
long retval;
|
|
|
|
if (!config || !key)
|
|
return defaultValue;
|
|
|
|
value = g_key_file_get_value(config, group, key, NULL);
|
|
if (!value)
|
|
{
|
|
*err = 1;
|
|
return defaultValue;
|
|
}
|
|
|
|
retval = strtol(value, &p, 10);
|
|
/* Check for unit suffixes */
|
|
if (p && *p)
|
|
{
|
|
long mult = _DC_processSuffix(p);
|
|
if (mult == -1)
|
|
{
|
|
DC_log(LOG_WARNING, "Configuration value for key %s "
|
|
"is not a valid number, ignoring", key);
|
|
g_free(value);
|
|
*err = 1;
|
|
return defaultValue;
|
|
}
|
|
retval *= mult;
|
|
}
|
|
|
|
g_free(value);
|
|
*err = 0;
|
|
return retval;
|
|
}
|
|
|
|
static double getCfgDouble(const char *group, const char *key,
|
|
double defaultValue, int *err)
|
|
{
|
|
char *value, *p;
|
|
double retval;
|
|
|
|
if (!config || !key)
|
|
return defaultValue;
|
|
|
|
value = g_key_file_get_value(config, group, key, NULL);
|
|
if (!value)
|
|
{
|
|
*err = 1;
|
|
return defaultValue;
|
|
}
|
|
|
|
retval = strtod(value, &p);
|
|
if (p && *p)
|
|
{
|
|
long long mult = _DC_processSuffix(p);
|
|
if (mult == -1)
|
|
{
|
|
DC_log(LOG_WARNING, "Configuration value for key %s "
|
|
"is not a valid number, ignoring", key);
|
|
g_free(value);
|
|
*err = 1;
|
|
return defaultValue;
|
|
}
|
|
retval *= mult;
|
|
}
|
|
|
|
g_free(value);
|
|
*err = 0;
|
|
return retval;
|
|
}
|
|
|
|
static int getCfgBool(const char *group, const char *key, int defaultValue,
|
|
int *err)
|
|
{
|
|
char *value;
|
|
int retval;
|
|
|
|
if (!config || !key)
|
|
return !!defaultValue;
|
|
|
|
value = g_key_file_get_value(config, group, key, NULL);
|
|
if (!value)
|
|
{
|
|
*err = 1;
|
|
return !!defaultValue;
|
|
}
|
|
|
|
retval = _DC_parseBoolean(value);
|
|
g_free(value);
|
|
if (retval == -1)
|
|
{
|
|
*err = 1;
|
|
return !!defaultValue;
|
|
}
|
|
*err = 0;
|
|
return retval;
|
|
}
|
|
|
|
char *DC_getCfgStr(const char *key)
|
|
{
|
|
return getCfgStr(MASTER_GROUP, key);
|
|
}
|
|
|
|
int DC_getCfgInt(const char *key, int defaultValue)
|
|
{
|
|
int err;
|
|
|
|
return getCfgInt(MASTER_GROUP, key, defaultValue, &err);
|
|
}
|
|
|
|
int DC_getCfgBool(const char *key, int defaultValue)
|
|
{
|
|
int err;
|
|
|
|
return getCfgBool(MASTER_GROUP, key, defaultValue, &err);
|
|
}
|
|
|
|
char *DC_getClientCfgStr(const char *clientName, const char *key,
|
|
int fallbackGlobal)
|
|
{
|
|
char *group, *val;
|
|
|
|
if (!clientName)
|
|
return NULL;
|
|
|
|
group = g_strdup_printf("Client-%s", clientName);
|
|
val = getCfgStr(group, key);
|
|
g_free(group);
|
|
if (!val && fallbackGlobal)
|
|
val = getCfgStr(MASTER_GROUP, key);
|
|
return val;
|
|
}
|
|
|
|
int DC_getClientCfgInt(const char *clientName, const char *key,
|
|
int defaultValue, int fallbackGlobal)
|
|
{
|
|
int val, err;
|
|
char *group;
|
|
|
|
if (!clientName)
|
|
return defaultValue;
|
|
|
|
group = g_strdup_printf("Client-%s", clientName);
|
|
val = getCfgInt(group, key, defaultValue, &err);
|
|
g_free(group);
|
|
if (err && fallbackGlobal)
|
|
val = getCfgInt(MASTER_GROUP, key, defaultValue, &err);
|
|
return val;
|
|
}
|
|
|
|
double DC_getClientCfgDouble(const char *clientName, const char *key,
|
|
double defaultValue, int fallbackGlobal)
|
|
{
|
|
char *group;
|
|
double val;
|
|
int err;
|
|
|
|
if (!clientName)
|
|
return defaultValue;
|
|
|
|
group = g_strdup_printf("Client-%s", clientName);
|
|
val = getCfgDouble(group, key, defaultValue, &err);
|
|
g_free(group);
|
|
if (err && fallbackGlobal)
|
|
val = getCfgDouble(MASTER_GROUP, key, defaultValue, &err);
|
|
return val;
|
|
}
|
|
|
|
int DC_getClientCfgBool(const char *clientName, const char *key,
|
|
int defaultValue, int fallbackGlobal)
|
|
{
|
|
int val, err;
|
|
char *group;
|
|
|
|
if (!clientName)
|
|
return !!defaultValue;
|
|
|
|
group = g_strdup_printf("Client-%s", clientName);
|
|
val = getCfgBool(group, key, defaultValue, &err);
|
|
g_free(group);
|
|
if (err && fallbackGlobal)
|
|
val = getCfgBool(MASTER_GROUP, key, defaultValue, &err);
|
|
return val;
|
|
}
|
|
|
|
int _DC_initClientConfig(const char *clientName, FILE *f)
|
|
{
|
|
char **keys, *group, *val;
|
|
gsize i, cnt;
|
|
|
|
if (!clientName)
|
|
return DC_ERR_BADPARAM;
|
|
|
|
group = g_strdup_printf("Client-%s", clientName);
|
|
keys = g_key_file_get_string_list(config, group, CFG_SENDKEYS, &cnt,
|
|
NULL);
|
|
|
|
/* Always set LogLevel */
|
|
val = g_key_file_get_value(config, group, CFG_LOGLEVEL, NULL);
|
|
if (!val)
|
|
val = g_key_file_get_value(config, MASTER_GROUP, CFG_LOGLEVEL,
|
|
NULL);
|
|
if (val)
|
|
{
|
|
fprintf(f, "%s = %s\n", CFG_LOGLEVEL, val);
|
|
g_free(val);
|
|
}
|
|
|
|
/* Copy the values of the requested keys */
|
|
for (i = 0; keys && i < cnt; i++)
|
|
{
|
|
char *p;
|
|
|
|
/* Strip white space from the key name */
|
|
p = keys[i] + strlen(keys[i]) - 1;
|
|
while (*p == ' ' || *p == '\t')
|
|
*p-- = '\0';
|
|
p = keys[i];
|
|
while (*p == ' ' || *p == '\t')
|
|
p++;
|
|
|
|
val = g_key_file_get_value(config, group, p, NULL);
|
|
if (!val)
|
|
val = g_key_file_get_value(config, MASTER_GROUP, p,
|
|
NULL);
|
|
if (val)
|
|
{
|
|
fprintf(f, "%s = %s\n", p, val);
|
|
g_free(val);
|
|
}
|
|
}
|
|
|
|
g_strfreev(keys);
|
|
g_free(group);
|
|
return 0;
|
|
}
|