diff options
Diffstat (limited to 'src/cli/report.cpp')
-rw-r--r-- | src/cli/report.cpp | 1022 |
1 files changed, 511 insertions, 511 deletions
diff --git a/src/cli/report.cpp b/src/cli/report.cpp index 43968896..8099a92e 100644 --- a/src/cli/report.cpp +++ b/src/cli/report.cpp @@ -36,24 +36,24 @@ */ static char *trim(char *str) { - if (!str) - return NULL; - - // Remove leading spaces. - char *ibuf; - ibuf = skip_whitespace(str); - int i = strlen(ibuf); - if (str != ibuf) - memmove(str, ibuf, i + 1); - - // Remove trailing spaces. - while (--i >= 0) - { - if (!isspace(str[i])) - break; - } - str[++i] = '\0'; - return str; + if (!str) + return NULL; + + // Remove leading spaces. + char *ibuf; + ibuf = skip_whitespace(str); + int i = strlen(ibuf); + if (str != ibuf) + memmove(str, ibuf, i + 1); + + // Remove trailing spaces. + while (--i >= 0) + { + if (!isspace(str[i])) + break; + } + str[++i] = '\0'; + return str; } /* @@ -62,49 +62,49 @@ static char *trim(char *str) */ static char *escape(const char *str) { - // Determine the size of resultant string. - // Count the required number of escape characters. - // 1. NEWLINE followed by # - // 2. NEWLINE followed by \# (escaped version) - const char *ptr = str; - bool newline = true; - int count = 0; - while (*ptr) - { - if (newline) + // Determine the size of resultant string. + // Count the required number of escape characters. + // 1. NEWLINE followed by # + // 2. NEWLINE followed by \# (escaped version) + const char *ptr = str; + bool newline = true; + int count = 0; + while (*ptr) { - if (*ptr == '#') - ++count; - if (*ptr == '\\' && ptr[1] == '#') - ++count; - } + if (newline) + { + if (*ptr == '#') + ++count; + if (*ptr == '\\' && ptr[1] == '#') + ++count; + } - newline = (*ptr == '\n'); - ++ptr; - } + newline = (*ptr == '\n'); + ++ptr; + } - // Copy the input string to the resultant string, and escape all - // occurences of \# and #. - char *result = (char*)xmalloc(strlen(str) + 1 + count); + // Copy the input string to the resultant string, and escape all + // occurences of \# and #. + char *result = (char*)xmalloc(strlen(str) + 1 + count); - const char *src = str; - char *dest = result; - newline = true; - while (*src) - { - if (newline) + const char *src = str; + char *dest = result; + newline = true; + while (*src) { - if (*src == '#') - *dest++ = '\\'; - else if (*src == '\\' && *(src + 1) == '#') - *dest++ = '\\'; - } + if (newline) + { + if (*src == '#') + *dest++ = '\\'; + else if (*src == '\\' && *(src + 1) == '#') + *dest++ = '\\'; + } - newline = (*src == '\n'); - *dest++ = *src++; - } - *dest = '\0'; - return result; + newline = (*src == '\n'); + *dest++ = *src++; + } + *dest = '\0'; + return result; } /* @@ -113,34 +113,34 @@ static char *escape(const char *str) */ static void remove_comments_and_unescape(char *str) { - char *src = str, *dest = str; - bool newline = true; - while (*src) - { - if (newline) + char *src = str, *dest = str; + bool newline = true; + while (*src) { - if (*src == '#') - { // Skip the comment line! - while (*src && *src != '\n') - ++src; - - if (*src == '\0') - break; - - ++src; - continue; - } - if (*src == '\\' - && (src[1] == '#' || (src[1] == '\\' && src[2] == '#')) - ) { - ++src; // Unescape escaped char. - } - } + if (newline) + { + if (*src == '#') + { // Skip the comment line! + while (*src && *src != '\n') + ++src; + + if (*src == '\0') + break; + + ++src; + continue; + } + if (*src == '\\' + && (src[1] == '#' || (src[1] == '\\' && src[2] == '#')) + ) { + ++src; // Unescape escaped char. + } + } - newline = (*src == '\n'); - *dest++ = *src++; - } - *dest = '\0'; + newline = (*src == '\n'); + *dest++ = *src++; + } + *dest = '\0'; } /* @@ -148,31 +148,31 @@ static void remove_comments_and_unescape(char *str) * Field must be writable. */ static void write_crash_report_field(FILE *fp, const map_crash_data_t &report, - const char *field, const char *description) + const char *field, const char *description) { - const map_crash_data_t::const_iterator it = report.find(field); - if (it == report.end()) - { - // exit silently, all fields are optional for now - //error_msg("Field %s not found", field); - return; - } - - if (it->second[CD_TYPE] == CD_SYS) - { - error_msg("Cannot update field %s because it is a system value", field); - return; - } - - fprintf(fp, "%s%s\n", FIELD_SEP, it->first.c_str()); - - fprintf(fp, "%s\n", description); - if (it->second[CD_EDITABLE] != CD_ISEDITABLE) - fprintf(fp, _("# This field is read only\n")); - - char *escaped_content = escape(it->second[CD_CONTENT].c_str()); - fprintf(fp, "%s\n", escaped_content); - free(escaped_content); + const map_crash_data_t::const_iterator it = report.find(field); + if (it == report.end()) + { + // exit silently, all fields are optional for now + //error_msg("Field %s not found", field); + return; + } + + if (it->second[CD_TYPE] == CD_SYS) + { + error_msg("Cannot update field %s because it is a system value", field); + return; + } + + fprintf(fp, "%s%s\n", FIELD_SEP, it->first.c_str()); + + fprintf(fp, "%s\n", description); + if (it->second[CD_EDITABLE] != CD_ISEDITABLE) + fprintf(fp, _("# This field is read only\n")); + + char *escaped_content = escape(it->second[CD_CONTENT].c_str()); + fprintf(fp, "%s\n", escaped_content); + free(escaped_content); } /* @@ -184,25 +184,25 @@ static void write_crash_report_field(FILE *fp, const map_crash_data_t &report, */ static void write_crash_report(const map_crash_data_t &report, FILE *fp) { - fprintf(fp, "# Please check this report. Lines starting with '#' will be ignored.\n" - "# Lines starting with '%%----' separate fields, please do not delete them.\n\n"); - - write_crash_report_field(fp, report, FILENAME_COMMENT, - _("# Describe the circumstances of this crash below")); - write_crash_report_field(fp, report, FILENAME_REPRODUCE, - _("# How to reproduce the crash?")); - write_crash_report_field(fp, report, FILENAME_BACKTRACE, - _("# Backtrace\n# Check that it does not contain any sensitive data (passwords, etc.)")); - write_crash_report_field(fp, report, CD_DUPHASH, "# DUPHASH"); - write_crash_report_field(fp, report, FILENAME_ARCHITECTURE, _("# Architecture")); - write_crash_report_field(fp, report, FILENAME_CMDLINE, _("# Command line")); - write_crash_report_field(fp, report, FILENAME_COMPONENT, _("# Component")); - write_crash_report_field(fp, report, FILENAME_COREDUMP, _("# Core dump")); - write_crash_report_field(fp, report, FILENAME_EXECUTABLE, _("# Executable")); - write_crash_report_field(fp, report, FILENAME_KERNEL, _("# Kernel version")); - write_crash_report_field(fp, report, FILENAME_PACKAGE, _("# Package")); - write_crash_report_field(fp, report, FILENAME_REASON, _("# Reason of crash")); - write_crash_report_field(fp, report, FILENAME_RELEASE, _("# Release string of the operating system")); + fprintf(fp, "# Please check this report. Lines starting with '#' will be ignored.\n" + "# Lines starting with '%%----' separate fields, please do not delete them.\n\n"); + + write_crash_report_field(fp, report, FILENAME_COMMENT, + _("# Describe the circumstances of this crash below")); + write_crash_report_field(fp, report, FILENAME_REPRODUCE, + _("# How to reproduce the crash?")); + write_crash_report_field(fp, report, FILENAME_BACKTRACE, + _("# Backtrace\n# Check that it does not contain any sensitive data (passwords, etc.)")); + write_crash_report_field(fp, report, CD_DUPHASH, "# DUPHASH"); + write_crash_report_field(fp, report, FILENAME_ARCHITECTURE, _("# Architecture")); + write_crash_report_field(fp, report, FILENAME_CMDLINE, _("# Command line")); + write_crash_report_field(fp, report, FILENAME_COMPONENT, _("# Component")); + write_crash_report_field(fp, report, FILENAME_COREDUMP, _("# Core dump")); + write_crash_report_field(fp, report, FILENAME_EXECUTABLE, _("# Executable")); + write_crash_report_field(fp, report, FILENAME_KERNEL, _("# Kernel version")); + write_crash_report_field(fp, report, FILENAME_PACKAGE, _("# Package")); + write_crash_report_field(fp, report, FILENAME_REASON, _("# Reason of crash")); + write_crash_report_field(fp, report, FILENAME_RELEASE, _("# Release string of the operating system")); } /* @@ -214,56 +214,56 @@ static void write_crash_report(const map_crash_data_t &report, FILE *fp) * Changes to read-only fields are ignored. */ static int read_crash_report_field(const char *text, map_crash_data_t &report, - const char *field) + const char *field) { - char separator[sizeof("\n" FIELD_SEP)-1 + strlen(field) + 2]; // 2 = '\n\0' - sprintf(separator, "\n%s%s\n", FIELD_SEP, field); - const char *textfield = strstr(text, separator); - if (!textfield) - return 0; // exit silently because all fields are optional - - textfield += strlen(separator); - int length = 0; - const char *end = strstr(textfield, "\n" FIELD_SEP); - if (!end) - length = strlen(textfield); - else - length = end - textfield; - - const map_crash_data_t::iterator it = report.find(field); - if (it == report.end()) - { - error_msg("Field %s not found", field); - return 0; - } + char separator[sizeof("\n" FIELD_SEP)-1 + strlen(field) + 2]; // 2 = '\n\0' + sprintf(separator, "\n%s%s\n", FIELD_SEP, field); + const char *textfield = strstr(text, separator); + if (!textfield) + return 0; // exit silently because all fields are optional + + textfield += strlen(separator); + int length = 0; + const char *end = strstr(textfield, "\n" FIELD_SEP); + if (!end) + length = strlen(textfield); + else + length = end - textfield; - if (it->second[CD_TYPE] == CD_SYS) - { - error_msg("Cannot update field %s because it is a system value", field); - return 0; - } + const map_crash_data_t::iterator it = report.find(field); + if (it == report.end()) + { + error_msg("Field %s not found", field); + return 0; + } - // Do not change noneditable fields. - if (it->second[CD_EDITABLE] != CD_ISEDITABLE) - return 0; + if (it->second[CD_TYPE] == CD_SYS) + { + error_msg("Cannot update field %s because it is a system value", field); + return 0; + } - // Compare the old field contents with the new field contents. - char newvalue[length + 1]; - strncpy(newvalue, textfield, length); - newvalue[length] = '\0'; - trim(newvalue); + // Do not change noneditable fields. + if (it->second[CD_EDITABLE] != CD_ISEDITABLE) + return 0; - char oldvalue[it->second[CD_CONTENT].length() + 1]; - strcpy(oldvalue, it->second[CD_CONTENT].c_str()); - trim(oldvalue); + // Compare the old field contents with the new field contents. + char newvalue[length + 1]; + strncpy(newvalue, textfield, length); + newvalue[length] = '\0'; + trim(newvalue); - // Return if no change in the contents detected. - int cmp = strcmp(newvalue, oldvalue); - if (!cmp) - return 0; + char oldvalue[it->second[CD_CONTENT].length() + 1]; + strcpy(oldvalue, it->second[CD_CONTENT].c_str()); + trim(oldvalue); - it->second[CD_CONTENT].assign(newvalue); - return 1; + // Return if no change in the contents detected. + int cmp = strcmp(newvalue, oldvalue); + if (!cmp) + return 0; + + it->second[CD_CONTENT].assign(newvalue); + return 1; } /* @@ -276,21 +276,21 @@ static int read_crash_report_field(const char *text, map_crash_data_t &report, */ static int read_crash_report(map_crash_data_t &report, const char *text) { - int result = 0; - result |= read_crash_report_field(text, report, FILENAME_COMMENT); - result |= read_crash_report_field(text, report, FILENAME_REPRODUCE); - result |= read_crash_report_field(text, report, FILENAME_BACKTRACE); - result |= read_crash_report_field(text, report, CD_DUPHASH); - result |= read_crash_report_field(text, report, FILENAME_ARCHITECTURE); - result |= read_crash_report_field(text, report, FILENAME_CMDLINE); - result |= read_crash_report_field(text, report, FILENAME_COMPONENT); - result |= read_crash_report_field(text, report, FILENAME_COREDUMP); - result |= read_crash_report_field(text, report, FILENAME_EXECUTABLE); - result |= read_crash_report_field(text, report, FILENAME_KERNEL); - result |= read_crash_report_field(text, report, FILENAME_PACKAGE); - result |= read_crash_report_field(text, report, FILENAME_REASON); - result |= read_crash_report_field(text, report, FILENAME_RELEASE); - return result; + int result = 0; + result |= read_crash_report_field(text, report, FILENAME_COMMENT); + result |= read_crash_report_field(text, report, FILENAME_REPRODUCE); + result |= read_crash_report_field(text, report, FILENAME_BACKTRACE); + result |= read_crash_report_field(text, report, CD_DUPHASH); + result |= read_crash_report_field(text, report, FILENAME_ARCHITECTURE); + result |= read_crash_report_field(text, report, FILENAME_CMDLINE); + result |= read_crash_report_field(text, report, FILENAME_COMPONENT); + result |= read_crash_report_field(text, report, FILENAME_COREDUMP); + result |= read_crash_report_field(text, report, FILENAME_EXECUTABLE); + result |= read_crash_report_field(text, report, FILENAME_KERNEL); + result |= read_crash_report_field(text, report, FILENAME_PACKAGE); + result |= read_crash_report_field(text, report, FILENAME_REASON); + result |= read_crash_report_field(text, report, FILENAME_RELEASE); + return result; } /** @@ -314,31 +314,31 @@ static void create_fields_for_editor(map_crash_data_t &crash_data) */ static int launch_editor(const char *path) { - const char *editor, *terminal; - - editor = getenv("ABRT_EDITOR"); - if (!editor) - editor = getenv("VISUAL"); - if (!editor) - editor = getenv("EDITOR"); - - terminal = getenv("TERM"); - if (!editor && (!terminal || strcmp(terminal, "dumb") == 0)) - { - error_msg(_("Cannot run vi: $TERM, $VISUAL and $EDITOR are not set")); - return 1; - } + const char *editor, *terminal; + + editor = getenv("ABRT_EDITOR"); + if (!editor) + editor = getenv("VISUAL"); + if (!editor) + editor = getenv("EDITOR"); + + terminal = getenv("TERM"); + if (!editor && (!terminal || strcmp(terminal, "dumb") == 0)) + { + error_msg(_("Cannot run vi: $TERM, $VISUAL and $EDITOR are not set")); + return 1; + } - if (!editor) - editor = "vi"; + if (!editor) + editor = "vi"; - char *args[3]; - args[0] = (char*)editor; - args[1] = (char*)path; - args[2] = NULL; - run_command(args); + char *args[3]; + args[0] = (char*)editor; + args[1] = (char*)path; + args[2] = NULL; + run_command(args); - return 0; + return 0; } /** @@ -349,75 +349,75 @@ static int launch_editor(const char *path) */ static int run_report_editor(map_crash_data_t &cr) { - /* Open a temporary file and write the crash report to it. */ - char filename[] = "/tmp/abrt-report.XXXXXX"; - int fd = mkstemp(filename); - if (fd == -1) /* errno is set */ - { - perror_msg("can't generate temporary file name"); - return 2; - } - - FILE *fp = fdopen(fd, "w"); - if (!fp) /* errno is set */ - { - perror_msg("can't open '%s' to save the crash report", filename); - return 2; - } - - write_crash_report(cr, fp); - - if (fclose(fp)) /* errno is set */ - { - perror_msg("can't close '%s'", filename); - return 2; - } - - // Start a text editor on the temporary file. - if (launch_editor(filename) != 0) - return 3; /* exit with error */ - - // Read the file back and update the report from the file. - fp = fopen(filename, "r"); - if (!fp) /* errno is set */ - { - perror_msg("can't open '%s' to read the crash report", filename); - return 2; - } - - fseek(fp, 0, SEEK_END); - long size = ftell(fp); - fseek(fp, 0, SEEK_SET); - - char *text = (char*)xmalloc(size + 1); - if (fread(text, 1, size, fp) != size) - { - error_msg("can't read '%s'", filename); - return 2; - } - text[size] = '\0'; - if (fclose(fp) != 0) /* errno is set */ - { - perror_msg("can't close '%s'", filename); - return 2; - } - - // Delete the tempfile. - if (unlink(filename) == -1) /* errno is set */ - { - perror_msg("can't unlink %s", filename); - } - - remove_comments_and_unescape(text); - // Updates the crash report from the file text. - int report_changed = read_crash_report(cr, text); - free(text); - if (report_changed) - puts(_("\nThe report has been updated")); - else - puts(_("\nNo changes were detected in the report")); - - return 0; + /* Open a temporary file and write the crash report to it. */ + char filename[] = "/tmp/abrt-report.XXXXXX"; + int fd = mkstemp(filename); + if (fd == -1) /* errno is set */ + { + perror_msg("can't generate temporary file name"); + return 2; + } + + FILE *fp = fdopen(fd, "w"); + if (!fp) /* errno is set */ + { + perror_msg("can't open '%s' to save the crash report", filename); + return 2; + } + + write_crash_report(cr, fp); + + if (fclose(fp)) /* errno is set */ + { + perror_msg("can't close '%s'", filename); + return 2; + } + + // Start a text editor on the temporary file. + if (launch_editor(filename) != 0) + return 3; /* exit with error */ + + // Read the file back and update the report from the file. + fp = fopen(filename, "r"); + if (!fp) /* errno is set */ + { + perror_msg("can't open '%s' to read the crash report", filename); + return 2; + } + + fseek(fp, 0, SEEK_END); + long size = ftell(fp); + fseek(fp, 0, SEEK_SET); + + char *text = (char*)xmalloc(size + 1); + if (fread(text, 1, size, fp) != size) + { + error_msg("can't read '%s'", filename); + return 2; + } + text[size] = '\0'; + if (fclose(fp) != 0) /* errno is set */ + { + perror_msg("can't close '%s'", filename); + return 2; + } + + // Delete the tempfile. + if (unlink(filename) == -1) /* errno is set */ + { + perror_msg("can't unlink %s", filename); + } + + remove_comments_and_unescape(text); + // Updates the crash report from the file text. + int report_changed = read_crash_report(cr, text); + free(text); + if (report_changed) + puts(_("\nThe report has been updated")); + else + puts(_("\nNo changes were detected in the report")); + + return 0; } /** @@ -431,13 +431,13 @@ static int run_report_editor(map_crash_data_t &cr) */ static void read_from_stdin(const char *question, char *result, int result_size) { - assert(result_size > 1); - printf("%s", question); - fflush(NULL); - if (NULL == fgets(result, result_size, stdin)) - result[0] = '\0'; - // Remove the newline from the login. - strchrnul(result, '\n')[0] = '\0'; + assert(result_size > 1); + printf("%s", question); + fflush(NULL); + if (NULL == fgets(result, result_size, stdin)) + result[0] = '\0'; + // Remove the newline from the login. + strchrnul(result, '\n')[0] = '\0'; } /** Splits a string into substrings using chosen delimiters. @@ -447,16 +447,16 @@ static void read_from_stdin(const char *question, char *result, int result_size) */ static vector_string_t split(const char *s, const char delim) { - std::vector<std::string> elems; - while (1) - { - const char *end = strchrnul(s, delim); - elems.push_back(std::string(s, end - s)); - if (*end == '\0') - break; - s = end + 1; - } - return elems; + std::vector<std::string> elems; + while (1) + { + const char *end = strchrnul(s, delim); + elems.push_back(std::string(s, end - s)); + if (*end == '\0') + break; + s = end + 1; + } + return elems; } /** Returns a list of enabled Reporter plugins, that are used to report @@ -467,64 +467,64 @@ static vector_string_t split(const char *s, const char delim) */ static vector_string_t get_enabled_reporters(map_crash_data_t &crash_data) { - vector_string_t result; - - /* Get global daemon settings. Analyzer->Reporters mapping is stored there. */ - map_map_string_t settings = call_GetSettings(); - /* Reporters are separated by comma in the following map. */ - map_string_t &analyzer_to_reporters = settings["AnalyzerActionsAndReporters"]; - - /* Get the analyzer from the crash. */ - const char *analyzer = get_crash_data_item_content_or_NULL(crash_data, FILENAME_ANALYZER); - if (!analyzer) - return result; /* No analyzer found in the crash data. */ - - /* First try to find package name dependent analyzer. - * nvr = name-version-release - * TODO: Similar code is in MiddleWare.cpp. It should not be duplicated. - */ - const char *package_nvr = get_crash_data_item_content_or_NULL(crash_data, FILENAME_PACKAGE); - if (!package_nvr) - return result; /* No package name found in the crash data. */ - char * package_name = get_package_name_from_NVR_or_NULL(package_nvr); - // analyzer with package name (CCpp:xorg-x11-app) has higher priority - map_string_t::const_iterator reporters_iter; - if (package_name != NULL) - { - char* package_specific_analyzer = xasprintf("%s:%s", analyzer, package_name); - reporters_iter = analyzer_to_reporters.find(package_specific_analyzer); - free(package_specific_analyzer); - free(package_name); - } - - if (analyzer_to_reporters.end() == reporters_iter) - { - reporters_iter = analyzer_to_reporters.find(analyzer); + vector_string_t result; + + /* Get global daemon settings. Analyzer->Reporters mapping is stored there. */ + map_map_string_t settings = call_GetSettings(); + /* Reporters are separated by comma in the following map. */ + map_string_t &analyzer_to_reporters = settings["AnalyzerActionsAndReporters"]; + + /* Get the analyzer from the crash. */ + const char *analyzer = get_crash_data_item_content_or_NULL(crash_data, FILENAME_ANALYZER); + if (!analyzer) + return result; /* No analyzer found in the crash data. */ + + /* First try to find package name dependent analyzer. + * nvr = name-version-release + * TODO: Similar code is in MiddleWare.cpp. It should not be duplicated. + */ + const char *package_nvr = get_crash_data_item_content_or_NULL(crash_data, FILENAME_PACKAGE); + if (!package_nvr) + return result; /* No package name found in the crash data. */ + char * package_name = get_package_name_from_NVR_or_NULL(package_nvr); + // analyzer with package name (CCpp:xorg-x11-app) has higher priority + map_string_t::const_iterator reporters_iter; + if (package_name != NULL) + { + char* package_specific_analyzer = xasprintf("%s:%s", analyzer, package_name); + reporters_iter = analyzer_to_reporters.find(package_specific_analyzer); + free(package_specific_analyzer); + free(package_name); + } + if (analyzer_to_reporters.end() == reporters_iter) - return result; /* No reporters found for the analyzer. */ - } - - /* Reporters found, now parse the list. */ - vector_string_t reporter_vec = split(reporters_iter->second.c_str(), ','); - - // 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 (string_to_bool(it->second["Enabled"].c_str()) != true) - continue; - // Skip nonReporter plugins. - if (0 != strcmp(it->second["Type"].c_str(), "Reporter")) - continue; - // Skip plugins not used in this particular crash. - if (reporter_vec.end() == std::find(reporter_vec.begin(), reporter_vec.end(), std::string(it->first))) - continue; - result.push_back(it->first); - } - return result; + { + reporters_iter = analyzer_to_reporters.find(analyzer); + if (analyzer_to_reporters.end() == reporters_iter) + return result; /* No reporters found for the analyzer. */ + } + + /* Reporters found, now parse the list. */ + vector_string_t reporter_vec = split(reporters_iter->second.c_str(), ','); + + // 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 (string_to_bool(it->second["Enabled"].c_str()) != true) + continue; + // Skip nonReporter plugins. + if (0 != strcmp(it->second["Type"].c_str(), "Reporter")) + continue; + // Skip plugins not used in this particular crash. + if (reporter_vec.end() == std::find(reporter_vec.begin(), reporter_vec.end(), std::string(it->first))) + continue; + result.push_back(it->first); + } + return result; } /** @@ -533,18 +533,18 @@ static vector_string_t get_enabled_reporters(map_crash_data_t &crash_data) */ static bool ask_yesno(const char *question) { - /* The response might take more than 1 char in non-latin scripts. */ - const char *yes = _("y"); - const char *no = _("N"); - char *full_question = xasprintf("%s [%s/%s]: ", question, yes, no); - printf(full_question); - free(full_question); - fflush(NULL); - char answer[16]; - fgets(answer, sizeof(answer), stdin); - /* Use strncmp here because the answer might contain a newline as - the last char. */ - return 0 == strncmp(answer, yes, strlen(yes)); + /* The response might take more than 1 char in non-latin scripts. */ + const char *yes = _("y"); + const char *no = _("N"); + char *full_question = xasprintf("%s [%s/%s]: ", question, yes, no); + printf(full_question); + free(full_question); + fflush(NULL); + char answer[16]; + fgets(answer, sizeof(answer), stdin); + /* Use strncmp here because the answer might contain a newline as + the last char. */ + return 0 == strncmp(answer, yes, strlen(yes)); } /* Returns true if echo has been changed from another state. */ @@ -584,42 +584,42 @@ static bool set_echo(bool enabled) * A structure filled with reporter plugin settings. */ static void get_reporter_plugin_settings(const vector_string_t& reporters, - map_map_string_t &settings) + map_map_string_t &settings) { - /* First of all, load system-wide report plugin settings. */ - for (vector_string_t::const_iterator it = reporters.begin(); it != reporters.end(); ++it) - { - map_string_t single_plugin_settings = call_GetPluginSettings(it->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->c_str()] = 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) - { - map_map_string_t::const_iterator itend = settings.end(); - for (map_map_string_t::iterator it = settings.begin(); it != itend; ++it) + /* First of all, load system-wide report plugin settings. */ + for (vector_string_t::const_iterator it = reporters.begin(); it != reporters.end(); ++it) + { + map_string_t single_plugin_settings = call_GetPluginSettings(it->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->c_str()] = 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) { - 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; + map_map_string_t::const_iterator itend = settings.end(); + for (map_map_string_t::iterator 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; + } } - } } /** @@ -627,136 +627,136 @@ static void get_reporter_plugin_settings(const vector_string_t& reporters, */ static void ask_for_missing_settings(const char *plugin_name, map_string_t &single_plugin_settings) { - // 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) - return; - - // Read the missing information and push it to plugin settings. - printf(_("Wrong settings were detected for plugin %s\n"), plugin_name); - char result[64]; - if (loginMissing) - { - read_from_stdin(_("Enter your login: "), result, 64); - single_plugin_settings["Login"] = std::string(result); - } - if (passwordMissing) - { - bool changed = set_echo(false); - read_from_stdin(_("Enter your password: "), result, 64); - if (changed) - set_echo(true); - - // Newline was not added by pressing Enter because ECHO was disabled, so add it now. - puts(""); - single_plugin_settings["Password"] = std::string(result); - } + // 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) + return; + + // Read the missing information and push it to plugin settings. + printf(_("Wrong settings were detected for plugin %s\n"), plugin_name); + char result[64]; + if (loginMissing) + { + read_from_stdin(_("Enter your login: "), result, 64); + single_plugin_settings["Login"] = std::string(result); + } + if (passwordMissing) + { + bool changed = set_echo(false); + read_from_stdin(_("Enter your password: "), result, 64); + if (changed) + set_echo(true); + + // Newline was not added by pressing Enter because ECHO was disabled, so add it now. + puts(""); + single_plugin_settings["Password"] = std::string(result); + } } /* Reports the crash with corresponding crash_id over DBus. */ int report(const char *crash_id, int flags) { - int old_logmode = logmode; - if (flags & CLI_REPORT_SILENT_IF_NOT_FOUND) - logmode = 0; - // Ask for an initial report. - map_crash_data_t cr = call_CreateReport(crash_id); - logmode = old_logmode; - if (cr.size() == 0) - { - return -1; - } - - const char *rating_str = get_crash_data_item_content_or_NULL(cr, FILENAME_RATING); - unsigned rating = rating_str ? xatou(rating_str) : 4; - - /* Open text editor and give a chance to review the backtrace etc. */ - if (!(flags & CLI_REPORT_BATCH)) - { - create_fields_for_editor(cr); - int result = run_report_editor(cr); - if (result != 0) - return result; - } - - /* Get enabled reporters associated with this particular crash. */ - vector_string_t reporters = get_enabled_reporters(cr); - map_map_string_t reporters_settings; /* to be filled on the next line */ - get_reporter_plugin_settings(reporters, reporters_settings); - - int errors = 0; - int plugins = 0; - if (flags & CLI_REPORT_BATCH) - { - puts(_("Reporting...")); - report_status_t r = call_Report(cr, reporters, reporters_settings); - report_status_t::iterator it = r.begin(); - while (it != r.end()) + int old_logmode = logmode; + if (flags & CLI_REPORT_SILENT_IF_NOT_FOUND) + logmode = 0; + // Ask for an initial report. + map_crash_data_t cr = call_CreateReport(crash_id); + logmode = old_logmode; + if (cr.size() == 0) { - vector_string_t &v = it->second; - printf("%s: %s\n", it->first.c_str(), v[REPORT_STATUS_IDX_MSG].c_str()); - plugins++; - if (v[REPORT_STATUS_IDX_FLAG] == "0") - errors++; - it++; + return -1; } - } - else - { - /* For every reporter, ask if user really wants to report using it. */ - for (vector_string_t::const_iterator it = reporters.begin(); it != reporters.end(); ++it) + + const char *rating_str = get_crash_data_item_content_or_NULL(cr, FILENAME_RATING); + unsigned rating = rating_str ? xatou(rating_str) : 4; + + /* Open text editor and give a chance to review the backtrace etc. */ + if (!(flags & CLI_REPORT_BATCH)) { - char question[255]; - snprintf(question, 255, _("Report using %s?"), it->c_str()); - if (!ask_yesno(question)) - { - puts(_("Skipping...")); - continue; - } - - map_map_string_t::iterator settings = reporters_settings.find(it->c_str()); - if (settings != reporters_settings.end()) - { - map_string_t::iterator rating_setting = settings->second.find("RatingRequired"); - if (rating_setting != settings->second.end() - && string_to_bool(rating_setting->second.c_str()) - && rating < 3) - { - puts(_("Reporting disabled because the backtrace is unusable")); + create_fields_for_editor(cr); + int result = run_report_editor(cr); + if (result != 0) + return result; + } - const char *package = get_crash_data_item_content_or_NULL(cr, FILENAME_PACKAGE); - if (package[0]) - printf(_("Please try to install debuginfo manually using the command: \"debuginfo-install %s\" and try again\n"), package); + /* Get enabled reporters associated with this particular crash. */ + vector_string_t reporters = get_enabled_reporters(cr); + map_map_string_t reporters_settings; /* to be filled on the next line */ + get_reporter_plugin_settings(reporters, reporters_settings); - plugins++; - errors++; - continue; + int errors = 0; + int plugins = 0; + if (flags & CLI_REPORT_BATCH) + { + puts(_("Reporting...")); + report_status_t r = call_Report(cr, reporters, reporters_settings); + report_status_t::iterator it = r.begin(); + while (it != r.end()) + { + vector_string_t &v = it->second; + printf("%s: %s\n", it->first.c_str(), v[REPORT_STATUS_IDX_MSG].c_str()); + plugins++; + if (v[REPORT_STATUS_IDX_FLAG] == "0") + errors++; + it++; + } + } + else + { + /* For every reporter, ask if user really wants to report using it. */ + for (vector_string_t::const_iterator it = reporters.begin(); it != reporters.end(); ++it) + { + char question[255]; + snprintf(question, 255, _("Report using %s?"), it->c_str()); + if (!ask_yesno(question)) + { + puts(_("Skipping...")); + continue; + } + + map_map_string_t::iterator settings = reporters_settings.find(it->c_str()); + if (settings != reporters_settings.end()) + { + map_string_t::iterator rating_setting = settings->second.find("RatingRequired"); + if (rating_setting != settings->second.end() + && string_to_bool(rating_setting->second.c_str()) + && rating < 3) + { + puts(_("Reporting disabled because the backtrace is unusable")); + + const char *package = get_crash_data_item_content_or_NULL(cr, FILENAME_PACKAGE); + if (package[0]) + printf(_("Please try to install debuginfo manually using the command: \"debuginfo-install %s\" and try again\n"), package); + + plugins++; + errors++; + continue; + } + } + else + { + puts(_("Error loading reporter settings")); + plugins++; + errors++; + continue; + } + + ask_for_missing_settings(it->c_str(), settings->second); + + vector_string_t cur_reporter(1, *it); + report_status_t r = call_Report(cr, cur_reporter, reporters_settings); + assert(r.size() == 1); /* one reporter --> one report status */ + vector_string_t &v = r.begin()->second; + printf("%s: %s\n", r.begin()->first.c_str(), v[REPORT_STATUS_IDX_MSG].c_str()); + plugins++; + if (v[REPORT_STATUS_IDX_FLAG] == "0") + errors++; } - } - else - { - puts(_("Error loading reporter settings")); - plugins++; - errors++; - continue; - } - - ask_for_missing_settings(it->c_str(), settings->second); - - vector_string_t cur_reporter(1, *it); - report_status_t r = call_Report(cr, cur_reporter, reporters_settings); - assert(r.size() == 1); /* one reporter --> one report status */ - vector_string_t &v = r.begin()->second; - printf("%s: %s\n", r.begin()->first.c_str(), v[REPORT_STATUS_IDX_MSG].c_str()); - plugins++; - if (v[REPORT_STATUS_IDX_FLAG] == "0") - errors++; } - } - printf(_("Crash reported via %d plugins (%d errors)\n"), plugins, errors); - return errors != 0; + printf(_("Crash reported via %d plugins (%d errors)\n"), plugins, errors); + return errors != 0; } |