diff options
author | Jiri Moskovcak <jmoskovc@redhat.com> | 2010-02-12 16:13:43 +0100 |
---|---|---|
committer | Jiri Moskovcak <jmoskovc@redhat.com> | 2010-02-12 16:13:43 +0100 |
commit | fd889cd72bd75634ed269e561c26732bd9e4a6e1 (patch) | |
tree | 633822db37f9fb1cd4bea97eb7cf467510e4461e | |
parent | d862c355099cddbd01a719029ce2161a4a6cc05d (diff) | |
parent | 5c273a5686f8d002a16183f44f73b4f50a03e799 (diff) | |
download | abrt-fd889cd72bd75634ed269e561c26732bd9e4a6e1.tar.gz abrt-fd889cd72bd75634ed269e561c26732bd9e4a6e1.tar.xz abrt-fd889cd72bd75634ed269e561c26732bd9e4a6e1.zip |
Merge branch 'master' into rhel6
-rw-r--r-- | inc/abrtlib.h | 2 | ||||
-rw-r--r-- | lib/Utils/Plugin.cpp | 69 | ||||
-rw-r--r-- | lib/Utils/Plugin.h | 16 | ||||
-rw-r--r-- | lib/Utils/xfuncs.cpp | 2 | ||||
-rw-r--r-- | src/CLI/report.cpp | 196 | ||||
-rw-r--r-- | src/Daemon/PluginManager.cpp | 54 | ||||
-rw-r--r-- | src/Daemon/PluginManager.h | 9 |
7 files changed, 200 insertions, 148 deletions
diff --git a/inc/abrtlib.h b/inc/abrtlib.h index 2f7b3bf7..ae8fef34 100644 --- a/inc/abrtlib.h +++ b/inc/abrtlib.h @@ -255,7 +255,7 @@ bool string_to_bool(const char *s); /* C++ style stuff */ std::string ssprintf(const char *format, ...); -std::string get_home_dir(int uid); +std::string get_home_dir(uid_t uid); std::string concat_path_file(const char *path, const char *filename); double get_dirsize(const char *pPath); double get_dirsize_find_largest_dir( diff --git a/lib/Utils/Plugin.cpp b/lib/Utils/Plugin.cpp index 2865027f..40cd2a02 100644 --- a/lib/Utils/Plugin.cpp +++ b/lib/Utils/Plugin.cpp @@ -17,6 +17,7 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "Plugin.h" +#include "abrtlib.h" CPlugin::CPlugin() {} @@ -33,3 +34,71 @@ const map_plugin_settings_t& CPlugin::GetSettings() { return m_pSettings; } + +bool LoadPluginSettings(const char *pPath, map_plugin_settings_t& pSettings, + bool skipKeysWithoutValue /*= true*/) +{ + FILE *fp = fopen(pPath, "r"); + if (!fp) + return false; + + char line[512]; + while (fgets(line, sizeof(line), fp)) + { + strchrnul(line, '\n')[0] = '\0'; + unsigned ii; + bool is_value = false; + bool valid = false; + bool in_quote = false; + std::string key; + std::string value; + for (ii = 0; line[ii] != '\0'; ii++) + { + if (line[ii] == '"') + { + in_quote = !in_quote; + } + if (isspace(line[ii]) && !in_quote) + { + continue; + } + if (line[ii] == '#' && !in_quote && key == "") + { + break; + } + if (line[ii] == '=' && !in_quote) + { + is_value = true; + valid = true; + continue; + } + if (!is_value) + { + key += line[ii]; + } + else + { + value += line[ii]; + } + } + + /* Skip broken or empty lines. */ + if (!valid) + continue; + + /* Skip lines with empty key. */ + if (key.length() == 0) + continue; + + if (skipKeysWithoutValue && value.length() == 0) + continue; + + /* Skip lines with unclosed quotes. */ + if (in_quote) + continue; + + pSettings[key] = value; + } + fclose(fp); + return true; +} diff --git a/lib/Utils/Plugin.h b/lib/Utils/Plugin.h index c699eb36..a2d3a7e9 100644 --- a/lib/Utils/Plugin.h +++ b/lib/Utils/Plugin.h @@ -118,9 +118,23 @@ typedef struct SPluginInfo PLUGINS_MAGIC_NUMBER,\ }; -/* helper finctions */ +/* helper functions */ std::string make_description_bz(const map_crash_data_t& pCrashData); std::string make_description_logger(const map_crash_data_t& pCrashData); std::string make_description_catcut(const map_crash_data_t& pCrashData); +/** + * Loads settings and stores it in second parameter. On success it + * returns true, otherwise returns false. + * + * @param path A path of config file. + * Config file consists of "key=value" lines. + * Lines in format "key=" (without value) are skipped. + * @param settings A readed plugin's settings. + * @return if it success it returns true, otherwise it returns false. + */ +extern bool LoadPluginSettings(const char *pPath, + map_plugin_settings_t& pSettings, + bool skipKeysWithoutValue = true); + #endif diff --git a/lib/Utils/xfuncs.cpp b/lib/Utils/xfuncs.cpp index 16f4cb0e..7301d7f0 100644 --- a/lib/Utils/xfuncs.cpp +++ b/lib/Utils/xfuncs.cpp @@ -252,7 +252,7 @@ void xstat(const char *name, struct stat *stat_buf) perror_msg_and_die("can't stat '%s'", name); } -std::string get_home_dir(int uid) +std::string get_home_dir(uid_t uid) { struct passwd* pw = getpwuid(uid); return pw ? pw->pw_dir : ""; diff --git a/src/CLI/report.cpp b/src/CLI/report.cpp index 39eccfb2..ebade16b 100644 --- a/src/CLI/report.cpp +++ b/src/CLI/report.cpp @@ -21,6 +21,7 @@ #include "abrtlib.h" #include "DebugDump.h" #include "CrashTypes.h" // FILENAME_* defines +#include "Plugin.h" // LoadPluginSettings #if HAVE_CONFIG_H # include <config.h> #endif @@ -414,6 +415,115 @@ static int run_report_editor(map_crash_data_t &cr) return 0; } +/** + * Asks user for a text response. + * @param question + * Question displayed to user. + * @param result + * Output array. + * @param result_size + * Maximum byte count to be written. + */ +static void read_from_stdin(const char *question, char *result, int result_size) +{ + printf(question); + fflush(NULL); + fgets(result, result_size, stdin); + // Remove the newline from the login. + char *newline = strchr(result, '\n'); + if (newline) + *newline = '\0'; +} + +/** + * Gets reporter plugin settings. + * @param ask_user + * If it's set to true and some reporter plugin settings are found to be missing + * (like login name or password), user is asked to provide the missing parts. + * @param settings + * A structure filled with reporter plugin settings. + */ +static void get_reporter_plugin_settings(map_map_string_t &settings, bool ask_user) +{ + /* First of all, load system-wide report plugin settings. */ + // Get informations about all plugins. + map_map_string_t plugins = call_GetPluginsInfo(); + // Check the configuration of each enabled Reporter plugin. + map_map_string_t::iterator it, itend = plugins.end(); + for (it = plugins.begin(); it != itend; ++it) + { + // Skip disabled plugins. + if (0 != strcmp(it->second["Enabled"].c_str(), "yes")) + continue; + // Skip nonReporter plugins. + if (0 != strcmp(it->second["Type"].c_str(), "Reporter")) + continue; + map_string_t single_plugin_settings = call_GetPluginSettings(it->first.c_str()); + // Copy the received settings as defaults. + // Plugins won't work without it, if some value is missing + // they use their default values for all fields. + settings[it->first] = single_plugin_settings; + } + + /* Second, load user-specific settings, which override + the system-wide settings. */ + struct passwd* pw = getpwuid(geteuid()); + const char* homedir = pw ? pw->pw_dir : NULL; + if (homedir) + { + itend = settings.end(); + for (it = settings.begin(); it != itend; ++it) + { + map_string_t single_plugin_settings; + std::string path = std::string(homedir) + "/.abrt/" + + it->first + "."PLUGINS_CONF_EXTENSION; + /* Load plugin config in the home dir. Do not skip lines with empty value (but containing a "key="), + because user may want to override password from /etc/abrt/plugins/*.conf, but he prefers to + enter it every time he reports. */ + bool success = LoadPluginSettings(path.c_str(), single_plugin_settings, false); + if (!success) + continue; + // Merge user's plugin settings into already loaded settings. + map_string_t::const_iterator valit, valitend = single_plugin_settings.end(); + for (valit = single_plugin_settings.begin(); valit != valitend; ++valit) + it->second[valit->first] = valit->second; + } + } + + if (!ask_user) + return; + + /* Third, check if a login or password is missing, + and ask for it. */ + itend = settings.end(); + for (it = settings.begin(); it != itend; ++it) + { + map_string_t &single_plugin_settings = it->second; + // Login information is missing. + bool loginMissing = single_plugin_settings.find("Login") != single_plugin_settings.end() + && 0 == strcmp(single_plugin_settings["Login"].c_str(), ""); + bool passwordMissing = single_plugin_settings.find("Password") != single_plugin_settings.end() + && 0 == strcmp(single_plugin_settings["Password"].c_str(), ""); + if (!loginMissing && !passwordMissing) + continue; + + // Read the missing information and push it to plugin settings. + printf(_("Wrong settings were detected for plugin %s.\n"), it->first.c_str()); + char result[64]; + if (loginMissing) + { + read_from_stdin(_("Enter your login: "), result, 64); + single_plugin_settings["Login"] = std::string(result); + } + if (passwordMissing) + { +// TODO: echo off, see http://fixunix.com/unix/84474-echo-off.html + read_from_stdin(_("Enter your password: "), result, 64); + single_plugin_settings["Password"] = std::string(result); + } + } +} + /* Reports the crash with corresponding uuid over DBus. */ int report(const char *uuid, bool always) { @@ -429,6 +539,10 @@ int report(const char *uuid, bool always) return result; } + /* Read the plugin settings. */ + map_map_string_t pluginSettings; + get_reporter_plugin_settings(pluginSettings, !always); + /* Ask if user really want to send the report. */ if (!always) { @@ -444,88 +558,6 @@ int report(const char *uuid, bool always) } } - map_map_string_t pluginSettings; -/* - std::string home; - map_plugin_settings_t oldSettings; - map_plugin_settings_t newSettings; - - if (pUID != "") - { - home = get_home_dir(xatoi_u(pUID.c_str())); - if (home != "") - { - oldSettings = reporter->GetSettings(); - - if (LoadPluginSettings(home + "/.abrt/" + plugin_name + "."PLUGINS_CONF_EXTENSION, newSettings)) - { - reporter->SetSettings(newSettings); - } - } - } -*/ - if (!always) - { - // Get informations about all plugins. - map_map_string_t plugins = call_GetPluginsInfo(); - // Check the configuration of each enabled Reporter plugin. - map_map_string_t::iterator it, itend = plugins.end(); - for (it = plugins.begin(); it != itend; ++it) - { - // Skip disabled plugins. - if (0 != strcmp(it->second["Enabled"].c_str(), "yes")) - continue; - // Skip nonReporter plugins. - if (0 != strcmp(it->second["Type"].c_str(), "Reporter")) - continue; - - map_string_t settings = call_GetPluginSettings(it->first.c_str()); - // Login information is missing. - bool loginMissing = settings.find("Login") != settings.end() - && 0 == strcmp(settings["Login"].c_str(), ""); - bool passwordMissing = settings.find("Password") != settings.end() - && 0 == strcmp(settings["Password"].c_str(), ""); - if (!loginMissing && !passwordMissing) - continue; - - // Copy the received settings as defaults. - // Plugins won't work without it, if some value is missing - // they use their default values for all fields. - pluginSettings[it->first] = settings; - - printf(_("Wrong settings were detected for plugin %s.\n"), it->second["Name"].c_str()); - if (loginMissing) - { - printf(_("Enter your login: ")); - fflush(NULL); - char answer[64] = ""; - fgets(answer, sizeof(answer), stdin); - // Remove the newline from the login. - char *newline = strchr(answer, '\n'); - if (newline) - *newline = '\0'; - // Push it to plugin settings. - if (strlen(answer) > 0) - pluginSettings[it->first]["Login"] = answer; - } - if (passwordMissing) - { -// TODO: echo off, see http://fixunix.com/unix/84474-echo-off.html - printf(_("Enter your password: ")); - fflush(NULL); - char answer[64] = ""; - fgets(answer, sizeof(answer), stdin); - // Remove the newline from the login. - char *newline = strchr(answer, '\n'); - if (newline) - *newline = '\0'; - // Push it to plugin settings. - if (strlen(answer) > 0) - pluginSettings[it->first]["Password"] = answer; - } - } - } - int errors = 0; int plugins = 0; puts(_("Reporting...")); diff --git a/src/Daemon/PluginManager.cpp b/src/Daemon/PluginManager.cpp index e63cb3ac..f01d9435 100644 --- a/src/Daemon/PluginManager.cpp +++ b/src/Daemon/PluginManager.cpp @@ -80,60 +80,6 @@ static const char *const plugin_type_str[] = { }; -bool LoadPluginSettings(const char *pPath, map_plugin_settings_t& pSettings) -{ - FILE *fp = fopen(pPath, "r"); - if (!fp) - return false; - - char line[512]; - while (fgets(line, sizeof(line), fp)) - { - strchrnul(line, '\n')[0] = '\0'; - unsigned ii; - bool is_value = false; - bool valid = false; - bool in_quote = false; - string key; - string value; - for (ii = 0; line[ii] != '\0'; ii++) - { - if (line[ii] == '"') - { - in_quote = !in_quote; - } - if (isspace(line[ii]) && !in_quote) - { - continue; - } - if (line[ii] == '#' && !in_quote && key == "") - { - break; - } - if (line[ii] == '=' && !in_quote) - { - is_value = true; - continue; - } - if (!is_value) - { - key += line[ii]; - } - else - { - valid = true; - value += line[ii]; - } - } - if (valid && !in_quote) - { - pSettings[key] = value; - } - } - fclose(fp); - return true; -} - /** * A function. It saves settings. On success it returns true, otherwise returns false. * @param path A path of config file. diff --git a/src/Daemon/PluginManager.h b/src/Daemon/PluginManager.h index b5dcebc5..bf6952f4 100644 --- a/src/Daemon/PluginManager.h +++ b/src/Daemon/PluginManager.h @@ -154,13 +154,4 @@ class CPluginManager map_plugin_settings_t GetPluginSettings(const char *pName); }; -/** - * Loads settings and stores it in second parameter. On success it - * returns true, otherwise returns false. - * @param path A path of config file. - * @param settings A readed plugin's settings. - * @return if it success it returns true, otherwise it returns false. - */ -bool LoadPluginSettings(const char *pPath, - map_plugin_settings_t& pSettings); #endif /*PLUGINMANAGER_H_*/ |