From 13a19b78ba45353f9a6a59c8dbb02336c339db35 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Wed, 20 Apr 2011 13:55:19 +0200 Subject: daemon: simplify parsing of settings; remove remaining c++isms in daemon This change will not compile, because in C++, void* cannot be automatically cast to char*. Next change renames Settings.cpp to *.c and fixes this. Signed-off-by: Denys Vlasenko --- src/daemon/Daemon.cpp | 163 +++++++++++----------------- src/daemon/Settings.cpp | 277 ++++++++++++------------------------------------ src/daemon/Settings.h | 2 - src/daemon/abrt.conf | 7 -- 4 files changed, 128 insertions(+), 321 deletions(-) (limited to 'src/daemon') diff --git a/src/daemon/Daemon.cpp b/src/daemon/Daemon.cpp index 3ac53aeb..6b894f01 100644 --- a/src/daemon/Daemon.cpp +++ b/src/daemon/Daemon.cpp @@ -21,7 +21,6 @@ #endif #include #include -#include #include #include /* ioctl(FIONREAD) */ #include "abrtlib.h" @@ -33,9 +32,6 @@ #define PROGNAME "abrtd" -using namespace std; - - #define VAR_RUN_PIDFILE VAR_RUN"/abrtd.pid" #define SOCKET_FILE VAR_RUN"/abrt/abrt.socket" @@ -64,7 +60,6 @@ static volatile sig_atomic_t s_sig_caught; static int s_signal_pipe[2]; static int s_signal_pipe_write = -1; static int s_upload_watch = -1; -static pid_t log_scanner_pid = -1; static unsigned s_timeout; static bool s_exiting; @@ -241,12 +236,6 @@ static gboolean handle_signal_cb(GIOChannel *gio, GIOCondition condition, gpoint pid_t pid; while ((pid = waitpid(-1, NULL, WNOHANG)) > 0) { - if (pid == log_scanner_pid) - { - log("log scanner exited"); - log_scanner_pid = -1; - continue; - } if (socket_client_count) socket_client_count--; if (!socket_channel_cb_id) @@ -597,81 +586,69 @@ int main(int argc, char** argv) bool pidfile_created = false; /* Initialization */ - try - { - init_daemon_logging(); + init_daemon_logging(); - VERB1 log("Loading settings"); - if (load_settings() != 0) - throw 1; + VERB1 log("Loading settings"); + if (load_settings() != 0) + goto init_error; - sanitize_dump_dir_rights(); + sanitize_dump_dir_rights(); - VERB1 log("Creating glib main loop"); - pMainloop = g_main_loop_new(NULL, FALSE); + VERB1 log("Creating glib main loop"); + pMainloop = g_main_loop_new(NULL, FALSE); - VERB1 log("Initializing inotify"); - errno = 0; - int inotify_fd = inotify_init(); - if (inotify_fd == -1) - perror_msg_and_die("inotify_init failed"); - close_on_exec_on(inotify_fd); + VERB1 log("Initializing inotify"); + errno = 0; + int inotify_fd = inotify_init(); + if (inotify_fd == -1) + perror_msg_and_die("inotify_init failed"); + close_on_exec_on(inotify_fd); - /* Watching DEBUG_DUMPS_DIR for new files... */ - if (inotify_add_watch(inotify_fd, DEBUG_DUMPS_DIR, IN_CREATE | IN_MOVED_TO) < 0) - { - perror_msg("inotify_add_watch failed on '%s'", DEBUG_DUMPS_DIR); - throw 1; - } - if (g_settings_sWatchCrashdumpArchiveDir) - { - s_upload_watch = inotify_add_watch(inotify_fd, g_settings_sWatchCrashdumpArchiveDir, IN_CLOSE_WRITE|IN_MOVED_TO); - if (s_upload_watch < 0) - { - perror_msg("inotify_add_watch failed on '%s'", g_settings_sWatchCrashdumpArchiveDir); - throw 1; - } - } - VERB1 log("Adding inotify watch to glib main loop"); - channel_inotify = g_io_channel_unix_new(inotify_fd); - channel_inotify_event_id = g_io_add_watch(channel_inotify, - G_IO_IN, - handle_inotify_cb, - NULL); - - /* Add an event source which waits for INT/TERM signal */ - VERB1 log("Adding signal pipe watch to glib main loop"); - channel_signal = g_io_channel_unix_new(s_signal_pipe[0]); - channel_signal_event_id = g_io_add_watch(channel_signal, - G_IO_IN, - handle_signal_cb, - NULL); - - /* Mark the territory */ - VERB1 log("Creating pid file"); - if (create_pidfile() != 0) - throw 1; - pidfile_created = true; - - /* Open socket to receive new crashes. */ - dumpsocket_init(); - - /* Note: this already may process a few dbus messages, - * therefore it should be the last thing to initialize. - */ - VERB1 log("Initializing dbus"); - if (init_dbus() != 0) - throw 1; + /* Watching DEBUG_DUMPS_DIR for new files... */ + if (inotify_add_watch(inotify_fd, DEBUG_DUMPS_DIR, IN_CREATE | IN_MOVED_TO) < 0) + { + perror_msg("inotify_add_watch failed on '%s'", DEBUG_DUMPS_DIR); + goto init_error; } - catch (...) + if (g_settings_sWatchCrashdumpArchiveDir) { - /* Initialization error */ - error_msg("Error while initializing daemon"); - /* Inform parent that initialization failed */ - if (!(opts & OPT_d)) - kill(parent_pid, SIGINT); - goto cleanup; + s_upload_watch = inotify_add_watch(inotify_fd, g_settings_sWatchCrashdumpArchiveDir, IN_CLOSE_WRITE|IN_MOVED_TO); + if (s_upload_watch < 0) + { + perror_msg("inotify_add_watch failed on '%s'", g_settings_sWatchCrashdumpArchiveDir); + goto init_error; + } } + VERB1 log("Adding inotify watch to glib main loop"); + channel_inotify = g_io_channel_unix_new(inotify_fd); + channel_inotify_event_id = g_io_add_watch(channel_inotify, + G_IO_IN, + handle_inotify_cb, + NULL); + + /* Add an event source which waits for INT/TERM signal */ + VERB1 log("Adding signal pipe watch to glib main loop"); + channel_signal = g_io_channel_unix_new(s_signal_pipe[0]); + channel_signal_event_id = g_io_add_watch(channel_signal, + G_IO_IN, + handle_signal_cb, + NULL); + + /* Mark the territory */ + VERB1 log("Creating pid file"); + if (create_pidfile() != 0) + goto init_error; + pidfile_created = true; + + /* Open socket to receive new crashes. */ + dumpsocket_init(); + + /* Note: this already may process a few dbus messages, + * therefore it should be the last thing to initialize. + */ + VERB1 log("Initializing dbus"); + if (init_dbus() != 0) + goto init_error; /* Inform parent that we initialized ok */ if (!(opts & OPT_d)) @@ -685,22 +662,6 @@ int main(int argc, char** argv) /* Only now we want signal pipe to work */ s_signal_pipe_write = s_signal_pipe[1]; - if (g_settings_sLogScanners) - { - const char *scanner_argv[] = { - "/bin/sh", "-c", - g_settings_sLogScanners, - NULL - }; - log_scanner_pid = fork_execv_on_steroids(EXECFLG_INPUT_NUL, - (char**)scanner_argv, - /*pipefds:*/ NULL, - /*env_vec:*/ NULL, - /*dir:*/ NULL, - /*uid:*/ 0); - VERB1 log("Started log scanner, pid:%d", (int)log_scanner_pid); - } - /* Enter the event loop */ log("Init complete, entering main loop"); run_main_loop(pMainloop); @@ -729,12 +690,6 @@ int main(int argc, char** argv) free_settings(); - if (log_scanner_pid > 0) - { - VERB2 log("Sending SIGTERM to %d", log_scanner_pid); - kill(log_scanner_pid, SIGTERM); - } - /* Exiting */ if (s_sig_caught && s_sig_caught != SIGALRM && s_sig_caught != SIGCHLD) { @@ -743,4 +698,12 @@ int main(int argc, char** argv) raise(s_sig_caught); } error_msg_and_die("Exiting"); + + init_error: + /* Initialization error */ + error_msg("Error while initializing daemon"); + /* Inform parent that initialization failed */ + if (!(opts & OPT_d)) + kill(parent_pid, SIGINT); + goto cleanup; } diff --git a/src/daemon/Settings.cpp b/src/daemon/Settings.cpp index cb77d191..90efd199 100644 --- a/src/daemon/Settings.cpp +++ b/src/daemon/Settings.cpp @@ -19,31 +19,7 @@ #include "abrtlib.h" #include "Settings.h" -#define SECTION_COMMON "Common" -#define SECTION_LOG_SCANNERS "LogScanners" - -/* Conf file has this format: - * [ section_name1 ] - * name1 = value1 - * name2 = value2 - * [ section_name2 ] - * name = value - */ - -/* Static data */ -/* Filled by load_settings() */ - -/* map["name"] = "value" strings from [ Common ] section. - * If the same name found on more than one line, - * the values are appended, separated by comma: map["name"] = "value1,value2" */ -static map_string_t s_mapSectionCommon; - -/* Public data */ - -/* [ Common ] */ -/* one line: "OpenGPGCheck = value" */ bool g_settings_bOpenGPGCheck = false; -/* one line: "OpenGPGPublicKeys = value1,value2" */ GList * g_settings_setOpenGPGPublicKeys = NULL; GList * g_settings_setBlackListedPkgs = NULL; GList * g_settings_setBlackListedPaths = NULL; @@ -51,13 +27,21 @@ char * g_settings_sWatchCrashdumpArchiveDir = NULL; unsigned int g_settings_nMaxCrashReportsSize = 1000; bool g_settings_bProcessUnpackaged = false; -/* [ LogScanners ] */ -char * g_settings_sLogScanners = NULL; +void free_settings() +{ + list_free_with_free(g_settings_setOpenGPGPublicKeys); + g_settings_setOpenGPGPublicKeys = NULL; -/* - * Loading - */ + list_free_with_free(g_settings_setBlackListedPkgs); + g_settings_setBlackListedPkgs = NULL; + + list_free_with_free(g_settings_setBlackListedPaths); + g_settings_setBlackListedPaths = NULL; + + free(g_settings_sWatchCrashdumpArchiveDir); + g_settings_sWatchCrashdumpArchiveDir = NULL; +} static GList *parse_list(const char* list) { @@ -85,43 +69,65 @@ static GList *parse_list(const char* list) } strbuf_free(item); + return l; } -static int ParseCommon() +static void ParseCommon(map_string_h *settings, const char *conf_filename) { - map_string_t::const_iterator end = s_mapSectionCommon.end(); - map_string_t::const_iterator it = s_mapSectionCommon.find("OpenGPGCheck"); - if (it != end) + char *value; + + value = g_hash_table_lookup(settings, "OpenGPGCheck"); + if (value) { - g_settings_bOpenGPGCheck = string_to_bool(it->second.c_str()); + g_settings_bOpenGPGCheck = string_to_bool(value); + g_hash_table_remove(settings, "OpenGPGCheck"); } - it = s_mapSectionCommon.find("BlackList"); - if (it != end) + + value = g_hash_table_lookup(settings, "BlackList"); + if (value) + { + g_settings_setBlackListedPkgs = parse_list(value); + g_hash_table_remove(settings, "BlackList"); + } + + value = g_hash_table_lookup(settings, "BlackListedPaths"); + if (value) { - g_settings_setBlackListedPkgs = parse_list(it->second.c_str()); + g_settings_setBlackListedPaths = parse_list(value); + g_hash_table_remove(settings, "BlackListedPaths"); } - it = s_mapSectionCommon.find("BlackListedPaths"); - if (it != end) + + value = g_hash_table_lookup(settings, "WatchCrashdumpArchiveDir"); + if (value) { - g_settings_setBlackListedPaths = parse_list(it->second.c_str()); + g_settings_sWatchCrashdumpArchiveDir = xstrdup(value); + g_hash_table_remove(settings, "WatchCrashdumpArchiveDir"); } - it = s_mapSectionCommon.find("WatchCrashdumpArchiveDir"); - if (it != end) + + value = g_hash_table_lookup(settings, "MaxCrashReportsSize"); + if (value) { - g_settings_sWatchCrashdumpArchiveDir = xstrdup(it->second.c_str()); +//fixme: dont die + g_settings_nMaxCrashReportsSize = xatoi_positive(value); + g_hash_table_remove(settings, "MaxCrashReportsSize"); } - it = s_mapSectionCommon.find("MaxCrashReportsSize"); - if (it != end) + + value = g_hash_table_lookup(settings, "ProcessUnpackaged"); + if (value) { - g_settings_nMaxCrashReportsSize = xatoi_positive(it->second.c_str()); + g_settings_bProcessUnpackaged = string_to_bool(value); + g_hash_table_remove(settings, "ProcessUnpackaged"); } - it = s_mapSectionCommon.find("ProcessUnpackaged"); - if (it != end) + + GHashTableIter iter; + char *name; + /*char *value; - already declared */ + g_hash_table_iter_init(&iter, settings); + while (g_hash_table_iter_next(&iter, (void**)&name, (void**)&value)) { - g_settings_bProcessUnpackaged = string_to_bool(it->second.c_str()); + error_msg("Unrecognized variable '%s' in '%s'", name, conf_filename); } - return 0; /* no error */ } static void LoadGPGKeys() @@ -135,7 +141,7 @@ static void LoadGPGKeys() char *line; while ((line = xmalloc_fgetline(fp)) != NULL) { - if (line[0] == '/') // probably the begining of path, so let's handle it as a key + if (line[0] == '/') // probably the beginning of a path, so let's handle it as a key g_settings_setOpenGPGPublicKeys = g_list_append(g_settings_setOpenGPGPublicKeys, line); else free(line); @@ -144,171 +150,18 @@ static void LoadGPGKeys() } } -/** - * Reads configuration from file to s_mapSection* static variables. - * The file must be opened for reading. - */ -static int ReadConfigurationFromFile(FILE *fp) -{ - char *line; - std::string section; - int lineno = 0; - while ((line = xmalloc_fgetline(fp)) != NULL) - { - ++lineno; - bool is_key = true; - bool is_section = false; - bool is_quote = false; - unsigned ii; - std::string key, value; - for (ii = 0; line[ii] != '\0'; ii++) - { - if (is_quote && line[ii] == '\\' && line[ii + 1]) - { - value += line[ii]; - ii++; - value += line[ii]; - continue; - } - if (isspace(line[ii]) && !is_quote && is_key) - { - continue; - } - if (line[ii] == '#' && !is_quote && key == "") - { - break; - } - if (line[ii] == '[' && !is_quote) - { - is_section = true; - section = ""; - continue; - } - if (line[ii] == '"') - { - is_quote = !is_quote; - value += line[ii]; - continue; - } - if (is_section) - { - if (line[ii] == ']') - break; - section += line[ii]; - continue; - } - if (is_key && line[ii] == '=' && !is_quote) - { - while (isspace(line[ii + 1])) ii++; - is_key = false; - key = value; - value = ""; - continue; - } - value += line[ii]; - } /* for */ - - if (is_quote) - { - error_msg("abrt.conf: Invalid syntax on line %d", lineno); - goto return_error; - } - - if (is_section) - { - if (line[ii] != ']') /* section not closed */ - { - error_msg("abrt.conf: Section not closed on line %d", lineno); - goto return_error; - } - goto free_line; - } - - if (is_key) - { - if (!value.empty()) /* the key is stored in value */ - { - error_msg("abrt.conf: Invalid syntax on line %d", lineno); - goto return_error; - } - goto free_line; - } - if (key.empty()) /* A line without key: " = something" */ - { - error_msg("abrt.conf: Invalid syntax on line %d", lineno); - goto return_error; - } - - if (section == SECTION_COMMON) - { - if (s_mapSectionCommon[key] != "") - s_mapSectionCommon[key] += ","; - s_mapSectionCommon[key] += value; - } - else if (section == SECTION_LOG_SCANNERS) - { - g_settings_sLogScanners = xstrdup(value.c_str()); - } - else - { - error_msg("abrt.conf: Ignoring entry in invalid section [%s]", section.c_str()); - return_error: - free(line); - return 1; /* error */ - } - free_line: - free(line); - } /* while */ - - return 0; /* success */ -} - -/* abrt daemon loads .conf file */ int load_settings() { - int err = 0; - - FILE *fp = fopen(CONF_DIR"/abrt.conf", "r"); - if (fp) - { - err = ReadConfigurationFromFile(fp); - fclose(fp); - } - else - error_msg("Unable to read configuration file %s", CONF_DIR"/abrt.conf"); - - if (err == 0) - err = ParseCommon(); - - if (err == 0) - { - /* - * loading gpg keys will invoke rpm_load_gpgkey() from rpm.cpp - * pgpReadPkts which makes nss to re-init and thus makes - * bugzilla plugin work :-/ - */ - //FIXME FIXME FIXME FIXME FIXME FIXME!!! - //if (g_settings_bOpenGPGCheck) - LoadGPGKeys(); - } - - return err; -} - -void free_settings() -{ - list_free_with_free(g_settings_setOpenGPGPublicKeys); - g_settings_setOpenGPGPublicKeys = NULL; + free_settings(); - list_free_with_free(g_settings_setBlackListedPkgs); - g_settings_setBlackListedPkgs = NULL; + map_string_h *settings = new_map_string(); + if (!load_conf_file(CONF_DIR"/abrt.conf", settings, /*skip key w/o values:*/ false)) + error_msg("Can't open '%s'", CONF_DIR"/abrt.conf"); - list_free_with_free(g_settings_setBlackListedPaths); - g_settings_setBlackListedPaths = NULL; + ParseCommon(settings, CONF_DIR"/abrt.conf"); + free_map_string(settings); - free(g_settings_sWatchCrashdumpArchiveDir); - g_settings_sWatchCrashdumpArchiveDir = NULL; + LoadGPGKeys(); - free(g_settings_sLogScanners); - g_settings_sLogScanners = NULL; + return 0; } diff --git a/src/daemon/Settings.h b/src/daemon/Settings.h index a869cfcc..c01f8c4a 100644 --- a/src/daemon/Settings.h +++ b/src/daemon/Settings.h @@ -33,8 +33,6 @@ extern bool g_settings_bOpenGPGCheck; extern bool g_settings_bProcessUnpackaged; extern char * g_settings_sWatchCrashdumpArchiveDir; -extern char * g_settings_sLogScanners; - int load_settings(); void free_settings(); diff --git a/src/daemon/abrt.conf b/src/daemon/abrt.conf index 3b87b0ff..cb0dbbbe 100644 --- a/src/daemon/abrt.conf +++ b/src/daemon/abrt.conf @@ -1,4 +1,3 @@ -[ Common ] # With this option set to "yes", # only crashes in signed packages will be analyzed. # the list of public keys used to check the signature is @@ -28,9 +27,3 @@ BlackListedPaths = /usr/share/doc/*,*/example* # Max size for crash storage [MiB] or 0 for unlimited # MaxCrashReportsSize = 1000 - - -### # So far we support only one line here -### # -### [ LogScanners ] -### abrt-dump-oops = abrt-dump-oops -d /var/spool/abrt -rwx /var/log/messages -- cgit