From a22c570ddba7a71f717eb2209674f4301f5ba8d7 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Fri, 26 Nov 2010 17:51:54 +0100 Subject: preparatory patch for future factoring out of headers for reportlib Some files and functions are renamed, no logic changes. Signed-off-by: Denys Vlasenko --- src/lib/CrashTypes.cpp | 254 ------------------------------------------------- src/lib/Makefile.am | 2 +- src/lib/crash_dump.cpp | 254 +++++++++++++++++++++++++++++++++++++++++++++++++ src/lib/dump_dir.c | 2 +- src/lib/hooklib.c | 2 +- src/lib/make_descr.cpp | 2 +- 6 files changed, 258 insertions(+), 258 deletions(-) delete mode 100644 src/lib/CrashTypes.cpp create mode 100644 src/lib/crash_dump.cpp (limited to 'src/lib') diff --git a/src/lib/CrashTypes.cpp b/src/lib/CrashTypes.cpp deleted file mode 100644 index acacda5e..00000000 --- a/src/lib/CrashTypes.cpp +++ /dev/null @@ -1,254 +0,0 @@ -/* - Copyright (C) 2010 Denys Vlasenko (dvlasenk@redhat.com) - 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 "abrtlib.h" -#include "crash_types.h" - -const char *const must_have_files[] = { - FILENAME_ARCHITECTURE, - FILENAME_KERNEL , - FILENAME_PACKAGE , - FILENAME_COMPONENT , - FILENAME_RELEASE , - FILENAME_EXECUTABLE , - NULL -}; - -static const char *const editable_files[] = { - FILENAME_DESCRIPTION, - FILENAME_COMMENT , - FILENAME_REPRODUCE , - FILENAME_BACKTRACE , - NULL -}; - -static bool is_editable(const char *name, const char *const *v) -{ - while (*v) { - if (strcmp(*v, name) == 0) - return true; - v++; - } - return false; -} - -bool is_editable_file(const char *file_name) -{ - return is_editable(file_name, editable_files); -} - - -void add_to_crash_data_ext(map_crash_data_t& pCrashData, - const char *pItem, - const char *pType, - const char *pEditable, - const char *pContent) -{ - map_crash_data_t::iterator it = pCrashData.find(pItem); - if (it == pCrashData.end()) { - vector_string_t& v = pCrashData[pItem]; /* create empty vector */ - v.push_back(pType); - v.push_back(pEditable); - v.push_back(pContent); - return; - } - vector_string_t& v = it->second; - while (v.size() < 3) - v.push_back(""); - v[CD_TYPE] = pType; - v[CD_EDITABLE] = pEditable; - v[CD_CONTENT] = pContent; -} - -void add_to_crash_data(map_crash_data_t& pCrashData, - const char *pItem, - const char *pContent) -{ - add_to_crash_data_ext(pCrashData, pItem, CD_TXT, CD_ISNOTEDITABLE, pContent); -} - -static char* is_text_file(const char *name, ssize_t *sz) -{ - /* We were using magic.h API to check for file being text, but it thinks - * that file containing just "0" is not text (!!) - * So, we do it ourself. - */ - - int fd = open(name, O_RDONLY); - if (fd < 0) - return NULL; /* it's not text (because it does not exist! :) */ - - /* Maybe 64k limit is small. But _some_ limit is necessary: - * fields declared "text" may end up in editing fields and such. - * We don't want to accidentally end up with 100meg text in a textbox! - * So, don't remove this. If you really need to, raise the limit. - */ - off_t size = lseek(fd, 0, SEEK_END); - if (size < 0 || size > 64*1024) - { - close(fd); - return NULL; /* it's not a SMALL text */ - } - lseek(fd, 0, SEEK_SET); - - char *buf = (char*)xmalloc(*sz); - ssize_t r = *sz = full_read(fd, buf, *sz); - close(fd); - if (r < 0) - { - free(buf); - return NULL; /* it's not text (because we can't read it) */ - } - - /* Some files in our dump directories are known to always be textual */ - const char *base = strrchr(name, '/'); - if (base) - { - base++; - if (strcmp(base, FILENAME_BACKTRACE) == 0 - || strcmp(base, FILENAME_CMDLINE) == 0 - ) { - return buf; - } - } - - /* Every once in a while, even a text file contains a few garbled - * or unexpected non-ASCII chars. We should not declare it "binary". - */ - const unsigned RATIO = 50; - unsigned total_chars = r + RATIO; - unsigned bad_chars = 1; /* 1 prevents division by 0 later */ - while (--r >= 0) - { - if (buf[r] >= 0x7f - /* among control chars, only '\t','\n' etc are allowed */ - || (buf[r] < ' ' && !isspace(buf[r])) - ) { - if (buf[r] == '\0') - { - /* We don't like NULs very much. Not text for sure! */ - free(buf); - return NULL; - } - bad_chars++; - } - } - - if ((total_chars / bad_chars) >= RATIO) - return buf; /* looks like text to me */ - - free(buf); - return NULL; /* it's binary */ -} - -void load_crash_data_from_debug_dump(struct dump_dir *dd, map_crash_data_t& data) -{ - char *short_name; - char *full_name; - - dd_init_next_file(dd); - while (dd_get_next_file(dd, &short_name, &full_name)) - { - ssize_t sz = 4*1024; - char *text = NULL; - bool editable = is_editable_file(short_name); - - if (!editable) - { - text = is_text_file(full_name, &sz); - if (!text) - { - add_to_crash_data_ext(data, - short_name, - CD_BIN, - CD_ISNOTEDITABLE, - full_name - ); - - free(short_name); - free(full_name); - continue; - } - } - - char *content; - if (sz < 4*1024) /* is_text_file did read entire file */ - content = xstrndup(text, sz); //TODO: can avoid this copying if is_text_file() adds NUL - else /* no, need to read it all */ - content = dd_load_text(dd, short_name); - free(text); - - add_to_crash_data_ext(data, - short_name, - CD_TXT, - editable ? CD_ISEDITABLE : CD_ISNOTEDITABLE, - content - ); - free(short_name); - free(full_name); - free(content); - } -} - -static const std::string* helper_get_crash_data_item_content(const map_crash_data_t& crash_data, const char *key) -{ - map_crash_data_t::const_iterator it = crash_data.find(key); - if (it == crash_data.end()) { - return NULL; - } - if (it->second.size() <= CD_CONTENT) { - return NULL; - } - return &it->second[CD_CONTENT]; -} - -const std::string& get_crash_data_item_content(const map_crash_data_t& crash_data, const char *key) -{ - const std::string* sp = helper_get_crash_data_item_content(crash_data, key); - if (sp == NULL) { - if (crash_data.find(key) == crash_data.end()) - error_msg_and_die("Error accessing crash data: no ['%s']", key); - error_msg_and_die("Error accessing crash data: no ['%s'][%d]", key, CD_CONTENT); - } - return *sp; -} - -const char *get_crash_data_item_content_or_NULL(const map_crash_data_t& crash_data, const char *key) -{ - const std::string* sp = helper_get_crash_data_item_content(crash_data, key); - if (!sp) { - return NULL; - } - return sp->c_str(); -} - -void log_map_crash_data(const map_crash_data_t& data, const char *name) -{ - map_crash_data_t::const_iterator it = data.begin(); - while (it != data.end()) - { - ssize_t sz = it->second.size(); - log("%s[%s]:%s/%s/'%.20s'", - name, it->first.c_str(), - sz > 0 ? it->second[0].c_str() : "", - sz > 1 ? it->second[1].c_str() : "", - sz > 2 ? it->second[2].c_str() : "" - ); - it++; - } -} diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am index baa13a24..ad2d2025 100644 --- a/src/lib/Makefile.am +++ b/src/lib/Makefile.am @@ -39,7 +39,7 @@ libabrt_la_SOURCES = \ load_plugin_settings.cpp \ make_descr.cpp \ run_event.c \ - CrashTypes.cpp \ + crash_dump.cpp \ ABRTException.cpp \ hooklib.c hooklib.h \ parse_release.cpp \ diff --git a/src/lib/crash_dump.cpp b/src/lib/crash_dump.cpp new file mode 100644 index 00000000..338724d5 --- /dev/null +++ b/src/lib/crash_dump.cpp @@ -0,0 +1,254 @@ +/* + Copyright (C) 2010 Denys Vlasenko (dvlasenk@redhat.com) + 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 "abrtlib.h" +#include "abrt_crash_dump.h" + +const char *const must_have_files[] = { + FILENAME_ARCHITECTURE, + FILENAME_KERNEL , + FILENAME_PACKAGE , + FILENAME_COMPONENT , + FILENAME_RELEASE , + FILENAME_EXECUTABLE , + NULL +}; + +static const char *const editable_files[] = { + FILENAME_DESCRIPTION, + FILENAME_COMMENT , + FILENAME_REPRODUCE , + FILENAME_BACKTRACE , + NULL +}; + +static bool is_editable(const char *name, const char *const *v) +{ + while (*v) { + if (strcmp(*v, name) == 0) + return true; + v++; + } + return false; +} + +bool is_editable_file(const char *file_name) +{ + return is_editable(file_name, editable_files); +} + + +void add_to_crash_data_ext(map_crash_data_t& pCrashData, + const char *pItem, + const char *pType, + const char *pEditable, + const char *pContent) +{ + map_crash_data_t::iterator it = pCrashData.find(pItem); + if (it == pCrashData.end()) { + vector_string_t& v = pCrashData[pItem]; /* create empty vector */ + v.push_back(pType); + v.push_back(pEditable); + v.push_back(pContent); + return; + } + vector_string_t& v = it->second; + while (v.size() < 3) + v.push_back(""); + v[CD_TYPE] = pType; + v[CD_EDITABLE] = pEditable; + v[CD_CONTENT] = pContent; +} + +void add_to_crash_data(map_crash_data_t& pCrashData, + const char *pItem, + const char *pContent) +{ + add_to_crash_data_ext(pCrashData, pItem, CD_TXT, CD_ISNOTEDITABLE, pContent); +} + +static char* is_text_file(const char *name, ssize_t *sz) +{ + /* We were using magic.h API to check for file being text, but it thinks + * that file containing just "0" is not text (!!) + * So, we do it ourself. + */ + + int fd = open(name, O_RDONLY); + if (fd < 0) + return NULL; /* it's not text (because it does not exist! :) */ + + /* Maybe 64k limit is small. But _some_ limit is necessary: + * fields declared "text" may end up in editing fields and such. + * We don't want to accidentally end up with 100meg text in a textbox! + * So, don't remove this. If you really need to, raise the limit. + */ + off_t size = lseek(fd, 0, SEEK_END); + if (size < 0 || size > 64*1024) + { + close(fd); + return NULL; /* it's not a SMALL text */ + } + lseek(fd, 0, SEEK_SET); + + char *buf = (char*)xmalloc(*sz); + ssize_t r = *sz = full_read(fd, buf, *sz); + close(fd); + if (r < 0) + { + free(buf); + return NULL; /* it's not text (because we can't read it) */ + } + + /* Some files in our dump directories are known to always be textual */ + const char *base = strrchr(name, '/'); + if (base) + { + base++; + if (strcmp(base, FILENAME_BACKTRACE) == 0 + || strcmp(base, FILENAME_CMDLINE) == 0 + ) { + return buf; + } + } + + /* Every once in a while, even a text file contains a few garbled + * or unexpected non-ASCII chars. We should not declare it "binary". + */ + const unsigned RATIO = 50; + unsigned total_chars = r + RATIO; + unsigned bad_chars = 1; /* 1 prevents division by 0 later */ + while (--r >= 0) + { + if (buf[r] >= 0x7f + /* among control chars, only '\t','\n' etc are allowed */ + || (buf[r] < ' ' && !isspace(buf[r])) + ) { + if (buf[r] == '\0') + { + /* We don't like NULs very much. Not text for sure! */ + free(buf); + return NULL; + } + bad_chars++; + } + } + + if ((total_chars / bad_chars) >= RATIO) + return buf; /* looks like text to me */ + + free(buf); + return NULL; /* it's binary */ +} + +void load_crash_data_from_crash_dump_dir(struct dump_dir *dd, map_crash_data_t& data) +{ + char *short_name; + char *full_name; + + dd_init_next_file(dd); + while (dd_get_next_file(dd, &short_name, &full_name)) + { + ssize_t sz = 4*1024; + char *text = NULL; + bool editable = is_editable_file(short_name); + + if (!editable) + { + text = is_text_file(full_name, &sz); + if (!text) + { + add_to_crash_data_ext(data, + short_name, + CD_BIN, + CD_ISNOTEDITABLE, + full_name + ); + + free(short_name); + free(full_name); + continue; + } + } + + char *content; + if (sz < 4*1024) /* is_text_file did read entire file */ + content = xstrndup(text, sz); //TODO: can avoid this copying if is_text_file() adds NUL + else /* no, need to read it all */ + content = dd_load_text(dd, short_name); + free(text); + + add_to_crash_data_ext(data, + short_name, + CD_TXT, + editable ? CD_ISEDITABLE : CD_ISNOTEDITABLE, + content + ); + free(short_name); + free(full_name); + free(content); + } +} + +static const std::string* helper_get_crash_data_item_content(const map_crash_data_t& crash_data, const char *key) +{ + map_crash_data_t::const_iterator it = crash_data.find(key); + if (it == crash_data.end()) { + return NULL; + } + if (it->second.size() <= CD_CONTENT) { + return NULL; + } + return &it->second[CD_CONTENT]; +} + +const std::string& get_crash_data_item_content(const map_crash_data_t& crash_data, const char *key) +{ + const std::string* sp = helper_get_crash_data_item_content(crash_data, key); + if (sp == NULL) { + if (crash_data.find(key) == crash_data.end()) + error_msg_and_die("Error accessing crash data: no ['%s']", key); + error_msg_and_die("Error accessing crash data: no ['%s'][%d]", key, CD_CONTENT); + } + return *sp; +} + +const char *get_crash_data_item_content_or_NULL(const map_crash_data_t& crash_data, const char *key) +{ + const std::string* sp = helper_get_crash_data_item_content(crash_data, key); + if (!sp) { + return NULL; + } + return sp->c_str(); +} + +void log_map_crash_data(const map_crash_data_t& data, const char *name) +{ + map_crash_data_t::const_iterator it = data.begin(); + while (it != data.end()) + { + ssize_t sz = it->second.size(); + log("%s[%s]:%s/%s/'%.20s'", + name, it->first.c_str(), + sz > 0 ? it->second[0].c_str() : "", + sz > 1 ? it->second[1].c_str() : "", + sz > 2 ? it->second[2].c_str() : "" + ); + it++; + } +} diff --git a/src/lib/dump_dir.c b/src/lib/dump_dir.c index 486c7cfe..19f86072 100644 --- a/src/lib/dump_dir.c +++ b/src/lib/dump_dir.c @@ -504,7 +504,7 @@ int dd_get_next_file(struct dump_dir *dd, char **short_name, char **full_name) } /* Utility function */ -void delete_debug_dump_dir(const char *dd_dir) +void delete_crash_dump_dir(const char *dd_dir) { struct dump_dir *dd = dd_opendir(dd_dir, /*flags:*/ 0); if (dd) diff --git a/src/lib/hooklib.c b/src/lib/hooklib.c index 062e3ddb..63c8a634 100644 --- a/src/lib/hooklib.c +++ b/src/lib/hooklib.c @@ -132,7 +132,7 @@ void trim_debug_dumps(unsigned setting_MaxCrashReportsSize, const char *exclude_ char *d = concat_path_file(DEBUG_DUMPS_DIR, worst_dir); free(worst_dir); worst_dir = NULL; - delete_debug_dump_dir(d); + delete_crash_dump_dir(d); free(d); } } diff --git a/src/lib/make_descr.cpp b/src/lib/make_descr.cpp index a0cb5691..e11325c8 100644 --- a/src/lib/make_descr.cpp +++ b/src/lib/make_descr.cpp @@ -17,7 +17,7 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "abrtlib.h" -#include "crash_types.h" +#include "abrt_crash_dump.h" using namespace std; -- cgit