/*
Copyright (C) 2010 ABRT team
Copyright (C) 2010 RedHat Inc
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "libabrt.h"
#define ABRT_CONF "abrt.conf"
char * g_settings_sWatchCrashdumpArchiveDir = NULL;
unsigned int g_settings_nMaxCrashReportsSize = 1000;
char * g_settings_dump_location = NULL;
bool g_settings_delete_uploaded = 0;
bool g_settings_autoreporting = 0;
char * g_settings_autoreporting_event = NULL;
bool g_settings_shortenedreporting = 0;
bool g_settings_explorechroots = 0;
unsigned int g_settings_debug_level = 0;
void free_abrt_conf_data()
{
free(g_settings_sWatchCrashdumpArchiveDir);
g_settings_sWatchCrashdumpArchiveDir = NULL;
free(g_settings_dump_location);
g_settings_dump_location = NULL;
free(g_settings_autoreporting_event);
g_settings_autoreporting_event = NULL;
}
/* Beware - the function normalizes only slashes - that's the most often
* problem we have to face.
*/
static char *xstrdup_normalized_path(const char *path)
{
const size_t len = strlen(path);
char *const res = xzalloc(len + 1);
res[0] = path[0];
const char *p = path + 1;
char *r = res;
for (; p - path < len; ++p)
if (*p != '/' || *r != '/')
*++r = *p;
/* remove trailing slash if the path is not '/' */
if (r - res > 1 && *r == '/')
*r = '\0';
return res;
}
static void ParseCommon(map_string_t *settings, const char *conf_filename)
{
const char *value;
value = get_map_string_item_or_NULL(settings, "WatchCrashdumpArchiveDir");
if (value)
{
g_settings_sWatchCrashdumpArchiveDir = xstrdup_normalized_path(value);
remove_map_string_item(settings, "WatchCrashdumpArchiveDir");
}
value = get_map_string_item_or_NULL(settings, "MaxCrashReportsSize");
if (value)
{
char *end;
errno = 0;
unsigned long ul = strtoul(value, &end, 10);
if (errno || end == value || *end != '\0' || ul > INT_MAX)
error_msg("Error parsing %s setting: '%s'", "MaxCrashReportsSize", value);
else
g_settings_nMaxCrashReportsSize = ul;
remove_map_string_item(settings, "MaxCrashReportsSize");
}
value = get_map_string_item_or_NULL(settings, "DumpLocation");
if (value)
{
g_settings_dump_location = xstrdup_normalized_path(value);
remove_map_string_item(settings, "DumpLocation");
}
else
g_settings_dump_location = xstrdup(DEFAULT_DUMP_LOCATION);
value = get_map_string_item_or_NULL(settings, "DeleteUploaded");
if (value)
{
g_settings_delete_uploaded = string_to_bool(value);
remove_map_string_item(settings, "DeleteUploaded");
}
value = get_map_string_item_or_NULL(settings, "AutoreportingEnabled");
if (value)
{
g_settings_autoreporting = string_to_bool(value);
remove_map_string_item(settings, "AutoreportingEnabled");
}
value = get_map_string_item_or_NULL(settings, "AutoreportingEvent");
if (value)
{
g_settings_autoreporting_event = xstrdup(value);
remove_map_string_item(settings, "AutoreportingEvent");
}
else
g_settings_autoreporting_event = xstrdup("report_uReport");
value = get_map_string_item_or_NULL(settings, "ShortenedReporting");
if (value)
{
g_settings_shortenedreporting = string_to_bool(value);
remove_map_string_item(settings, "ShortenedReporting");
}
else
{
/* Default: enabled for GNOME desktop, else disabled */
const char *desktop_env = getenv("DESKTOP_SESSION");
g_settings_shortenedreporting = (desktop_env && strcasestr(desktop_env, "gnome") != NULL);
}
value = get_map_string_item_or_NULL(settings, "ExploreChroots");
if (value)
{
g_settings_explorechroots = string_to_bool(value);
remove_map_string_item(settings, "ExploreChroots");
}
else
g_settings_explorechroots = false;
value = get_map_string_item_or_NULL(settings, "DebugLevel");
if (value)
{
char *end;
errno = 0;
unsigned long ul = strtoul(value, &end, 10);
if (errno || end == value || *end != '\0' || ul > INT_MAX)
error_msg("Error parsing %s setting: '%s'", "DebugLevel", value);
else
g_settings_debug_level = ul;
remove_map_string_item(settings, "DebugLevel");
}
GHashTableIter iter;
const char *name;
/*char *value; - already declared */
init_map_string_iter(&iter, settings);
while (next_map_string_iter(&iter, &name, &value))
{
error_msg("Unrecognized variable '%s' in '%s'", name, conf_filename);
}
}
static const char *get_abrt_conf_file_name(void)
{
const char *const abrt_conf = getenv("ABRT_CONF_FILE_NAME");
return abrt_conf == NULL ? ABRT_CONF : abrt_conf;
}
int load_abrt_conf()
{
free_abrt_conf_data();
const char *const abrt_conf = get_abrt_conf_file_name();
map_string_t *settings = new_map_string();
if (!load_abrt_conf_file(abrt_conf, settings))
perror_msg("Can't load '%s'", abrt_conf);
ParseCommon(settings, abrt_conf);
free_map_string(settings);
return 0;
}
static const char *const *get_conf_directories(void)
{
static const char *base_directories[3];
const char *d = getenv("ABRT_DEFAULT_CONF_DIR");
const char *c = getenv("ABRT_CONF_DIR");
base_directories[0] = d != NULL ? d : DEFAULT_CONF_DIR;
base_directories[1] = c != NULL ? d : CONF_DIR;
base_directories[2] = NULL;
return base_directories;
}
int load_abrt_conf_file(const char *file, map_string_t *settings)
{
const char *const *conf_directories = get_conf_directories();
return load_conf_file_from_dirs(file, conf_directories, settings, /*skip key w/o values:*/ false);
}
int load_abrt_plugin_conf_file(const char *file, map_string_t *settings)
{
static const char *const base_directories[] = { DEFAULT_PLUGINS_CONF_DIR, PLUGINS_CONF_DIR, NULL };
return load_conf_file_from_dirs(file, base_directories, settings, /*skip key w/o values:*/ false);
}
int save_abrt_conf_file(const char *file, map_string_t *settings)
{
char *path = concat_path_file(CONF_DIR, file);
int retval = save_conf_file(path, settings);
free(path);
return retval;
}
int save_abrt_plugin_conf_file(const char *file, map_string_t *settings)
{
char *path = concat_path_file(PLUGINS_CONF_DIR, file);
int retval = save_conf_file(path, settings);
free(path);
return retval;
}